1)
Код:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
enum {
A12 = 18,
B12 = 30,
A13 = -10,
B13 = 0,
A23 = 0,
B23 = 10,
EPS = 1000
};
typedef double (*func)(double);
double f1(double x);
double f2(double x);
double f3(double x);
double deriv(func f, double x, double dx);
double root(func, func, double, double, double);
double integral(func, double, double, double);
int
main(void)
{
//printf("----------\nDEBUG:\n----------\n");
double eps1 = 0.1 / EPS, eps2 = 0.01 / EPS;
double a = root(f1, f2, A12 / 10.0, B12 / 10.0, eps1);
double b = root(f1, f3, A13 / 10.0, B13 / 10.0, eps1);
double c = root(f2, f3, A23 / 10.0, B23 / 10.0, eps1);
double i1, i2, i3;
if(a < b)
i1 = integral(f1, a, b, eps2);
else
i1 = integral(f1, b, a, eps2);
//printf("i1 - %lf\n", i1);
if(a < c)
i2 = integral(f2, a, c, eps2);
else
i2 = integral(f2, c, a, eps2);
//printf("i2 - %lf\n", i2);
if(b < c)
i3 = integral(f3, b, c, eps2);
else
i3 = integral(f3, c, b, eps2);
//printf("i3 - %lf\n", i3);
double I = i1 - i2 - i3;
//printf("%lf\n", I);
//printf("----------\nSTOP DEBUG\n----------\n");
printf("f1(x) = 3/((x - 1) * (x - 1) + 1)\nf2(x) = sqrt(x + 0.5)\nf3(x) = exp(-x)\n");
printf("Points of intersection:\n");
printf(" f1 and f2: %.5lf\n", a);
printf(" f1 and f3: %.5lf\n", b);
printf(" f2 and f3: %.5lf\n", c);
printf("Area: %.5lf\n", I);
return 0;
}
double f1(double x)
{
return 3/((x - 1) * (x - 1) + 1);
}
double f2(double x)
{
return sqrt(x + 0.5);
}
double f3(double x)
{
return exp(-x);
}
double deriv(func f, double x, double dx)
{
double dy = (*f)(x + dx) - (*f)(x);
return dy / dx;
}
// комбинированный способ
double root(func f, func g, double a, double b, double eps)
{
char sgnd1 = ((*f)(a) - (*g)(a)) < 0; // знак первой производной F(x) = f(x) - g(x)
char sgnd2f = (*f)((a + b) / 2) <= (((*f)(a) + (*f)(b)) / 2);
char sgnd2g = (*g)((a + b) / 2) <= (((*g)(a) + (*g)(b)) / 2);
char sgnd2 = sgnd2f * sgnd2g; // знак второй производной F(x)
char sgn = !(sgnd1 ^ sgnd2); // F'(x) * F''(x) > 0
double c1, c2, Fa, Fb;
while(b - a >= eps){
Fa = (*f)(a) - (*g)(a);
Fb = (*f)(b) - (*g)(b);
c1 = (a * Fb - b * Fa) / (Fb - Fa); // точка пересечения хорды с осью абсцисс
if(sgn)
c2 = b - Fb / (deriv(f, b, eps) - deriv(g, b, eps));
else
c2 = a - Fa / (deriv(f, a, eps) - deriv(g, a, eps));
if(c2 > c1){
b = c2;
a = c1;
} else {
b = c1;
a = c2;
}
}
return (a + b) / 2;
}
// метод прямоугольников
double integral(func f, double a, double b, double eps)
{
int n = 1 / eps;
double p = 1 / 3.0;
double h;
double Fi;
double In = 0, I2n = 0;
int i;
do{
In = I2n;
n *= 2;
h = (b - a) / n;
for(i = 0; i < n; i++){
Fi = (*f)(a + (i + 0.5) * h);
I2n += Fi;
}
I2n *= h;
}while(p * abs(In - I2n) >= eps);
return I2n;
}