#include #include #include const double EPS1 = 1e-5; const double EPS2 = 1e-5; typedef struct Slice { int n; double *keys, *values; } Slice; double f(int k, double x) { switch(k) { case 0: return exp(x) + 2; case 1: return -1/x; case 2: return -2*(x + 1)/3; default: return 0; } } double fp(int k, double x) { switch(k) { case 0: return exp(x); case 1: return 1/(x * x); case 2: return -2*x/3; default: return 0; } } double rootChord(int f1, int f2, double l, double r, double lv, double rv) { double m = (l * rv - r * lv) / (rv - lv); if (fabs(m - l) < EPS1 || fabs(r - m) < EPS1) { return m; } double mv = f(f1, m) - f(f2, m); if ((lv < 0) != (mv < 0)) { return rootChord(f1, f2, l, m, lv, mv); } else { return rootChord(f1, f2, m, r, mv, rv); } } double rootTangent(int f1, int f2, double l, double r, double lv, double rv, double lp, double rp) { //fprintf(stderr, "%.4lf, %.4lf\n", l, r); //system("pause"); double m1 = l - lv / lp; double m2 = r - rv / rp; double m = (l < m1 && m1 < r) ? m1 : m2; if (fabs(m - l) < EPS1 || fabs(r - m) < EPS1) { return m; } double mv = f(f1, m) - f(f2, m); double mp = fp(f1, m) - fp(f2, m); if ((lv < 0) != (mv < 0)) { return rootTangent(f1, f2, l, m, lv, mv, lp, mp); } else { return rootTangent(f1, f2, m, r, mv, rv, mp, rp); } } double root(int f1, int f2, double l, double r) { //fprintf(stderr, "Root: %.4lf, %.4lf\n", l, r); double lv = f(f1, l) - f(f2, l); double rv = f(f1, r) - f(f2, r); double lp = fp(f1, l) - fp(f2, l); double rp = fp(f1, r) - fp(f2, r); //fprintf(stderr, "C\n"); double root1 = rootChord(f1, f2, l, r, lv, rv); //fprintf(stderr, "T\n"); double root2 = rootTangent(f1, f2, l, r, lv, rv, lp, rp); //fprintf(stderr, "OK\n"); return root1; } void expandArray(int fn, Slice *s) { s->n *= 2; s->keys = realloc(s->keys, (s->n + 1) * sizeof(double)); s->values = realloc(s->values, (s->n + 1) * sizeof(double)); for (int i = s->n; i >= 2; i -= 2) { s->keys[i] = s->keys[i / 2]; s->values[i] = s->values[i / 2]; } for (int i = 1; i < s->n; i += 2) { s->keys[i] = (s->keys[i - 1] + s->keys[i + 1]) / 2.0; s->values[i] = f(fn, s->keys[i]); } } Slice newSlice(int fn, double l, double r) { Slice res; res.n = 1; res.keys = malloc(2 * sizeof(double)); res.values = malloc(2 * sizeof(double)); res.keys[0] = l; res.values[0] = f(fn, l); res.keys[1] = r; res.values[1] = f(fn, r); expandArray(fn, &res); return res; } double integrateArray(Slice s) { double res = s.values[0] + s.values[s.n]; for (int i = 1; i < s.n; ++i) { if (i % 2) { res += 2 * s.values[i]; } else { res += 4 * s.values[i]; } } res *= fabs(s.keys[0] - s.keys[s.n]) / (s.n * 3); return res; } double integrate(int fn, double l, double r) { Slice sl = newSlice(fn, l, r); double prev, cur = integrateArray(sl); do { prev = cur; expandArray(fn, &sl); cur = integrateArray(sl); } while (fabs(cur - prev) > EPS2); return prev; } int main(void) { double RANGES[3][2]; RANGES[0][0] = -3.0; RANGES[0][1] = -1.0; RANGES[1][0] = -5.0; RANGES[1][1] = -3.0; // fprintf(stderr, "To send: %.4lf, %.4lf\n", RANGES[1][0], RANGES[1][1]); RANGES[2][0] = -1.0; RANGES[2][1] = -0.1; double cuts[3]; //fprintf(stderr, "---\n"); cuts[0] = root(1, 2, RANGES[0][0], RANGES[0][1]); cuts[1] = root(0, 2, RANGES[1][0], RANGES[1][1]); cuts[2] = root(0, 1, RANGES[2][0], RANGES[2][1]); //fprintf(stderr, "---\n"); double ints[3]; ints[0] = integrate(0, cuts[1], cuts[2]); ints[1] = integrate(1, cuts[0], cuts[2]); ints[2] = integrate(2, cuts[0], cuts[1]); //fprintf(stderr, "---\n"); double result; if ((cuts[0] < cuts[1]) == (cuts[1] < cuts[2])) { result = ints[1] - ints[0] - ints[2]; } else if ((cuts[0] < cuts[2]) == (cuts[2] < cuts[1])) { result = ints[2] - ints[0] - ints[1]; } else { result = ints[0] - ints[1] - ints[2]; } //fprintf(stderr, "---\n"); printf("Result: %.4lf\n", fabs(result)); printf("Points: %.4lf %.4lf %.4lf\n", cuts[0], cuts[1], cuts[2]); return 0; }