Advertisement
slik1977

BrentMethod

Mar 17th, 2022
260
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.79 KB | None | 0 0
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <vector>
  4. #include <cmath>
  5. #include <exception>
  6.  
  7.  
  8. double parab(double x1, double f1, double x2, double f2, double x3, double f3)
  9. {
  10.     return x2 - ((x2 - x1) * (x2 - x1) * (f2 - f3) - (x2 - x3) * (x2 - x3) * (f2 - f1)) / (2 * ((x2 - x1) * (f2 - f3) - (x2 - x3) * (f2 - f1)));
  11. }
  12.  
  13. double  parabola(double a, double b, double (*f)(double x), int64_t n, double eps)
  14. {
  15.     if (a > b)
  16.         std::swap(a, b);
  17.     double e = (a + b) * 0.5;
  18.     double x = (a + b) * 0.5;
  19.     double res = x;
  20.     double incor = b + 1;
  21.     double c, d;
  22.     for (int64_t i = 0; i < n; ++i)
  23.     {
  24.         res = parab(a, f(a), e, f(e), b, f(b));
  25.         if (!(res >= a && res <= b))
  26.             throw std::invalid_argument("Can't find min");
  27.         if (abs(res - x) < eps)
  28.             return res;
  29.         x = res;
  30.         c = std::min(e, x);
  31.         d = std::max(e, x);
  32.         if (f(c) < f(d))
  33.         {
  34.             b = d;
  35.             e = c;
  36.         }
  37.         else
  38.         {
  39.             a = c;
  40.             e = d;
  41.         }
  42.     }
  43.  
  44.     return res;
  45. }
  46.  
  47. double brent(double a, double b, double (*f)(double x), int64_t n, double eps)
  48. {
  49.     if (a > b)
  50.         std::swap(a, b);
  51.     double x, v, w, u, dcur, dprev;
  52.     static const double r = (3 - sqrt(5)) * 0.5;
  53.     x = w = v = a + r * (b - a);
  54.     dcur = dprev = b - a;
  55.     for (int64_t i = 0; i < n; ++i) {
  56.         if (std::max(x - a, b - x) < eps) {
  57.             return x;
  58.         }
  59.  
  60.         double g = dprev * 0.5;
  61.         dprev = dcur;
  62.         if (x == w || w == v || x == v) {
  63.             if (x < (a + b) * 0.5) {
  64.                 u = x + r * (b - x);
  65.                 dprev = b - x;
  66.             } else {
  67.                 u = x - r * (x - a);
  68.                 dprev = x - a;
  69.             }
  70.         } else {
  71.             u = parab(x, f(x), w, f(w), v, f(v));
  72.             if (!(u > a && u < b) || std::abs(u - x) > g) {
  73.                 if (x < (a + b) * 0.5) {
  74.                     u = x + r * (b - x);
  75.                     dprev = b - x;
  76.                 } else {
  77.                     u = x - r * (x - a);
  78.                     dprev = x - a;
  79.                 }
  80.             }
  81.         }
  82.  
  83.         dcur = std::abs(u - x);
  84.         if (f(u) > f(x)) {
  85.             if (u < x) {
  86.                 a = u;
  87.             } else {
  88.                 b = u;
  89.             }
  90.  
  91.             if (f(u) <= f(w) || w == x) {
  92.                 v = w;
  93.                 w = u;
  94.             } else {
  95.                 if (f(u) <= f(v) || v == x || v == w) {
  96.                     v = u;
  97.                 }
  98.             }
  99.         } else {
  100.             if (u < x) {
  101.                 b = x;
  102.             } else {
  103.                 a = x;
  104.             }
  105.             v = w;
  106.             w = x;
  107.             x = u;
  108.         }
  109.  
  110.     }
  111.  
  112.     return x;
  113. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement