#include #include #include #include //#define DEBUGOUT const double EPS0 = 1e-4; const double EPS = 1e-6; /* Const array of string variant of used function. */ const char text_func[8][50] = { "f1 = 3(0.5/(x+1)+1)", "f2 = 2.5x − 9.5", "f3 = 5/x (x>0)", // for testing root functon "4testing_f4 = x*x", "4testing_f5 = sqrt(x + 4)", "4testing_f6 = ln(x)", // for testing integrate function "4testing_f7 = sin(cos(x))", "4testing_f8 = exp(sin(1/x))" }; /* Const array with low coordinates of segments, where finding root. */ const double LOW[3][3] = { {0, 4, 1}, {0, 0, 3}, {0, 0, 0}, }; /* Const array with hi coordinates of segments, where finding root. */ const double HI[3][3] = { {0, 6, 2}, {0, 0, 5}, {0, 0, 0}, }; /* Function to compare not integer values. */ int cmp(double a, double b){ double tmp = a - b; if (fabs(tmp) < EPS) return 0; return tmp > 0 ? 1 : -1; } /* Functions declaration */ double f0(double x){ assert(cmp(x, -1) != 0); return 3 * (0.5 / (x + 1) + 1); } double f1(double x){ return 2.5 * x - 9.5; } double f2(double x){ assert(cmp(x, 0) > 0); return 5.0 / x; } // only 4 testing double f3(double x){ return x * x; } double f4(double x){ assert(cmp(x, -4) >= 0); return pow(x + 4, .5); } double f5(double x){ return log(x); } double f6(double x){ return sin(cos(x)); } double f7(double x){ assert(cmp(x, 0) != 0); return exp(sin(1/x)); } /* Init */ const char * func(double (*p)(double)){ if (p == f0) return text_func[0]; else if (p == f1) return text_func[1]; else if (p == f2) return text_func[2]; else if (p == f3) return text_func[3]; else if (p == f4) return text_func[4]; else if (p == f5) return text_func[5]; else if (p == f6) return text_func[6]; else if (p == f7) return text_func[7]; else assert(false); } /* Function, that return subtract i-th and j-th func with same argument x. */ double getSubF(double (*g1)(double), double (*g2)(double), double x){ return g1(x) - g2(x); } /* Function, that calculate intersect point of 2 func i and j on argument segment [a, b], and using epsilon eps1, answer puts in x */ double root(double (*g1)(double), double (*g2)(double), double a, double b, double eps1, double *x){ double Fa = g1(a) - g2(a); double Fb = g1(b) - g2(b); int First = cmp(Fa, 0) < 0 ? 1 : -1; int Second = cmp(g1((a + b) / 2) - g2((a + b) / 2), (Fa + Fb) / 2) > 0 ? -1 : 1; bool IsA = First * Second == 1; double c; fprintf(stderr, "IsA == %d\nFirst == %d\nSecond == %d\n", IsA, First, Second); while ((IsA && (fabs(Fa) > eps1)) || (!IsA && (fabs(Fb) > eps1))){ c = (a * Fb - b * Fa) / (Fb - Fa); fprintf(stderr, "\ta = %lf\tF(a) = %lf\n\tb = %lf\tF(b) = %lf\n\tc = %lf\tF(c) = %lf\n\n", a, Fa, b, Fb, c, g1(c) - g2(c)); if (IsA){ a = c; Fa = g1(a) - g2(a); } else { b = c; Fb = g1(b) - g2(b); } } *x = (IsA ? a : b); printf("%s\n%s\nIntersect (%lf, %lf)\n\n", func(g1), func(g2), *x, g1(*x)); return *x; } /* Function, that calculate integral value of i-th func on segment [a, b], and using epsilon value eps2, with Simpson metod at n subsegments. */ double calcI(double (*g)(double), double a, double b, double *odd, double *nodd, double eps2, int n){ double I = 0; double h = (b - a) / n; *nodd = *odd + *nodd; *odd = 0; for (int k = 1; k < n / 2; ++ k) *odd += g(a + (k + 1) * 2 * h); I = g(a) + g(b) + 4 * (*odd) + 2 * (*nodd); I *= h / 3; return I; } /* Function, that calculate integral value of i-th func on segment [a, b], and using epsilon value eps2, with Simpson metod and find optimal subsegment value. */ double integrate(double (*g)(double), double a, double b, double eps2){ double p = 1.0 / 15; int n = 2; double odd = 0; double nodd = 0; double I1 = calcI(g, a, b, &odd, &nodd, eps2, n); n *= 2; double I2 = calcI(g, a, b, &odd, &nodd, eps2, n); while (cmp(p * fabs(I2 - I1), eps2) > 0){ I1 = I2; n *= 2; I2 = calcI(g, a, b, &odd, &nodd, eps2, n); } n *= 2; I2 = calcI(g, a, b, &odd, &nodd, eps2, n); fprintf(stderr, "\t%s \t n = %d\n", func(g), n); printf("%s\nSegment (%lf, %lf)\nIntegral %lf\n\n", func(g), a, b, I2); return I2; } /* Function to run hand-inputed testcases*/ void testing(){ double X; root(f3, f4, 1, 50, EPS, &X); root(f2, f4, 1, 3, EPS, &X); double I; I = integrate(f6, -1, 10, EPS); I = integrate(f7, 0.1, 5, EPS); } int main(){ #ifndef DEBUGOUT freopen("/dev/null", "wt", stderr); #endif //testing(); //return 0; double A, B, C; double EPS1 = EPS / 10; /* Calculaing intersects points */ root(f0, f2, LOW[0][2], HI[0][2], EPS1, &A); root(f0, f1, LOW[0][1], HI[0][1], EPS1, &B); root(f1, f2, LOW[1][2], HI[1][2], EPS1, &C); double EPS2 = EPS / 10; /* Find integral value on segment with intersect points */ double S0 = integrate(f0, A, B, EPS2); double S1 = integrate(f1, B, C, EPS2); double S2 = integrate(f2, C, A, EPS2); /* Calculate intersect area */ double S = fabs(S0 + S1 + S2); printf("Area = %lf\n", S); return 0; }