Advertisement
_takumi

integral

Jun 1st, 2022 (edited)
822
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.18 KB | None | 0 0
  1. #include <math.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <getopt.h>
  5. #include <string.h>
  6. #include <stdbool.h>
  7.  
  8. typedef double afunc(double);
  9.  
  10. extern double f1(double);
  11. extern double f2(double);
  12. extern double f3(double);
  13. extern double t_f1(double);
  14. extern double t_f2(double);
  15. extern double t_f3(double);
  16. extern double t_f4(double);
  17.  
  18. struct {
  19.     const char *name; // -- длинный параметр
  20.     int has_arg;
  21.     int *flag;
  22.     int val;
  23. } option;
  24.  
  25. static int its = 0;
  26.  
  27. static double root(afunc *f, afunc *g, double a, double b, double eps1) {
  28.     double Fa, Fb, c;
  29.     bool one_sign;
  30.     while (true) {
  31.         its++;
  32.         Fa = (*f)(a) - (*g)(a);
  33.         Fb = (*f)(b) - (*g)(b);
  34.         c = (a * Fb - b * Fa) / (Fb - Fa);
  35.         one_sign = ((Fa > 0) && ((*f)((a + b) / 2) - (*g)((a + b) / 2) > (Fa + Fb) / 2))
  36.                    || ((Fa < 0) && ((*f)((a + b) / 2) - (*g)((a + b) / 2) < (Fa + Fb) / 2));
  37.         if (one_sign) {
  38.             a = c;
  39.             if (((*f)(c) - (*g)(c)) * (f(c + eps1) - (*g)(c + eps1)) < 0)
  40.                 break;
  41.         }
  42.         else {
  43.             b = c;
  44.             if (((*f)(c) - (*g)(c)) * ((*f)(c - eps1) - (*g)(c - eps1)) < 0)
  45.                 break;
  46.         }
  47.     }
  48.     return c;
  49. }
  50.  
  51. static double integral(afunc *f, double a, double b, double eps2) {
  52.     const double p = 1.0/3;
  53.     bool first = true;
  54.     double n0 = 10;
  55.     double h, I, In = 0, I2n = 0; //i2n - curr, in - prev
  56.     while (true) {
  57.         In = I2n;
  58.         h = (b - a) / n0;
  59.         I2n = 0;
  60.         for (int i = 0; i < n0; ++i) {
  61.             I2n += (*f)(a + (i + 0.5) * h);
  62.         }
  63.         I2n *= h;
  64.         if ((!first) && (eps2 > p * fabs(In - I2n))) {
  65.             break;
  66.         }
  67.         n0 *= 2;
  68.         first = false;
  69.     }
  70.     I = I2n;
  71.     return I;
  72. }
  73.  
  74. static afunc *map(int fn) {
  75.     if (fn == 1) {
  76.         return &t_f1;
  77.     }
  78.     else if (fn == 2) {
  79.         return &t_f2;
  80.     }
  81.     else if (fn == 3) {
  82.         return &t_f3;
  83.     }
  84.     else if (fn == 4) {
  85.         return &t_f1;
  86.     }
  87.     else if (fn == 5) {
  88.         return &t_f2;
  89.     }
  90.     else if (fn == 6) {
  91.         return &t_f3;
  92.     }
  93.     else {
  94.         return &t_f4;
  95.     }
  96. }
  97.  
  98. int main(int argc, char *argv[]) {
  99.     double tmp = 0;
  100.     int f1n, f2n;
  101.     double a, b, e, r, ans;
  102.     int *longindex = NULL;
  103.     const char *short_options = "hriR:I:";
  104.     const struct option long_options[] = {
  105.             { "help", no_argument, NULL, 'h' },
  106.             { "root", no_argument, NULL, 'r' },
  107.             { "iterations", no_argument, NULL, 'i' },
  108.             { "test-root", required_argument, NULL, 'R' },
  109.             { "test-integral", required_argument, NULL, 'I' },
  110.             { NULL, 0, NULL, 0}
  111.     };
  112.     int c = getopt_long(argc, argv, short_options,
  113.                        long_options, longindex);
  114.     switch (c) {
  115.         case 'h':
  116.             printf("--help, -h               вывести этот мануал\n"
  117.                    "--root, -r               вывести абсциссы точек пересечения кривых\n"
  118.                    "--iterations, -r         вывести число итераций, потребовавшихся на приближенное решение уравнений при поиске точек пересечения\n"
  119.                    "--test-root, -R          позволяют протестировать функцию root\n"
  120.                    "--test-integral, -I      позволяют протестировать функцию integral\n");
  121.             break;
  122.         case 'r':
  123.             printf("f1 x f2 : %lf\n", root(&f1, &f2, 1.2, 2.5, 0.0000001));
  124.             printf("f2 x f3 : %lf\n", root(&f2, &f3, 0, 1.2, 0.0000001));
  125.             printf("f1 x f3 : %lf\n", root(&f1, &f3, -0.5, 0, 0.0000001));
  126.             break;
  127.         case 'i':
  128.             tmp = root(&f1, &f2, 1.2, 2.5, 0.0000001);
  129.             printf("f1 x f2 : %d\n", its);
  130.             its = 0;
  131.             tmp = root(&f2, &f3, 0, 1.2, 0.0000001);
  132.             printf("f2 x f3 : %d\n", its);
  133.             its = 0;
  134.             tmp = root(&f1, &f3, -0.5, 0, 0.0000001);
  135.             printf("f1 x f3 : %d\n", its);
  136.             its = 0;
  137.             break;
  138.         case 'R':
  139.             sscanf(optarg, "%d:%d:%lf:%lf:%lf:%lf", &f1n, &f2n, &a, &b, &e, &r);
  140.             tmp = root(map(f1n), map(f2n), a, b, e);
  141.             printf("%lf %lf %lf\n", tmp, fabs(tmp - r), fabs(tmp - r) / r);
  142.             break;
  143.         case 'I':
  144.             sscanf(optarg, "%d:%lf:%lf:%lf:%lf", &f1n, &a, &b, &e, &r);
  145.             tmp = integral(map(f1n), a, b, e);
  146.             printf("%lf %lf %lf\n", tmp, fabs(tmp - r), fabs(tmp - r) / r);
  147.             break;
  148.         case -1:
  149.             a = root(&f1, &f3, -0.4, 0, 0.0000001);
  150.             b = root(&f1, &f2, 1.2, 2.5, 0.0000001);
  151.             tmp = root(&f2, &f3, 0, 1.2, 0.0000001);
  152.             ans = integral(&f1, a, b, 0.0001);
  153.             ans -= integral(&f3, a, tmp, 0.0001);
  154.             ans -= integral(&f2, tmp, b, 0.0001);
  155.             printf("%lf\n", ans);
  156.             break;
  157.         default:
  158.             printf("Wrong option, use --help for help\n");
  159.     }
  160.     return 0;
  161. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement