Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- 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;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement