Tvor0zhok

Numerical Integration

Sep 15th, 2021 (edited)
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.40 KB | None | 0 0
  1. // main.cpp
  2. #include "integrate.h"
  3. #include <iostream>
  4. #include <cassert>
  5. #include <iomanip>
  6. #include <string>
  7. #include <cmath>
  8. using namespace std;
  9.  
  10. const double EPS = 1e-6;
  11. const double R = 4.0;
  12.  
  13. const double a = -4.0, b = 4.0;
  14.  
  15. // Вычисление значения функций f(x) и ее первообразной F(x)
  16.  
  17. double F (double x) { return 0.5 * (R * R * asin(x / R) + x * sqrt(R * R - x * x)); }
  18. double f (double x) { return sqrt(R * R - x*x); }
  19.  
  20. // Правило Рунге оценки погрешности
  21.  
  22. void Runge(int& n, double& I1, double& I2, Method method)
  23. {
  24. if (fabs(I1 - I2) >= EPS)
  25. {
  26. I2 = I1;
  27.  
  28. n *= 2;
  29.  
  30. I1 = method(f, a, b, n);
  31.  
  32. Runge(n, I1, I2, method);
  33. }
  34. }
  35.  
  36. // вспомогательные функции для вывода таблицы на экран
  37.  
  38. Method choice(int i)
  39. {
  40. switch (i)
  41. {
  42. case 1: return LeftRectangle;
  43. case 2: return RightRectangle;
  44. case 3: return Rectangle;
  45. case 4: return Trapezoid;
  46. case 5: return Simpson;
  47. }
  48. }
  49.  
  50. string method(int i)
  51. {
  52. switch (i)
  53. {
  54. case 1: return "LeftRectangle";
  55. case 2: return "RightRectangle";
  56. case 3: return "Rectangle";
  57. case 4: return "Trapezoid";
  58. case 5: return "Simpson";
  59. }
  60. }
  61.  
  62. int main()
  63. {
  64. cout << setprecision(12) << fixed;
  65.  
  66. assert(-R <= a && b <= R);
  67.  
  68. // шапка таблицы
  69.  
  70. cout << left << setw(25) << "Method" << setw(12) << "n" << setw(20) << "I1" << setw(20) << "|I1 - RealAns|" << setw(15) << "|I1 - I2|" << "\n";
  71.  
  72. // выбор методов вычисления интеграла:
  73. // 1 - метод левых прямоугольников
  74. // 2 - метод правых прямоугольников
  75. // 3 - метод средних прямоугольников
  76. // 4 - метод трапеций
  77. // 5 - метод Симпсона (парабол)
  78.  
  79. int variants[] = { 2, 5 };
  80. int size = sizeof variants / sizeof(*variants);
  81.  
  82. // реальный ответ
  83.  
  84. double RealAns = F(b) - F(a);
  85.  
  86. // вывод таблицы на экран
  87.  
  88. for (int i = 0; i < size; ++i)
  89. {
  90. int n = 4, cur = variants[i];
  91.  
  92. double I1 = choice(cur)(f, a, b, n);
  93. double I2 = choice(cur)(f, a, b, n / 2);
  94.  
  95. Runge(n, I1, I2, choice(cur));
  96.  
  97. cout << left << setw(25) << method(cur) << setw(12) << n << setw(20) << I1 << setw(20) << fabs(I1 - RealAns) << setw(15) << fabs(I1 - I2) << "\n";
  98. }
  99.  
  100. return 0;
  101. }
  102.  
  103. //integrate.cpp
  104. #include <cassert>
  105.  
  106. typedef double (*Function)(double);
  107.  
  108. // Метод левых прямоугольников
  109. double LeftRectangle(Function f, double a, double b, int n)
  110. {
  111. assert(n >= 2);
  112.  
  113. double res = 0.0;
  114.  
  115. double h = (b - a) / (n - 1), x = a;
  116.  
  117. for (int i = 1; i <= n - 1; ++i, x += h)
  118. res += f(x);
  119.  
  120. return res * h;
  121. }
  122.  
  123. // Метод правых прямоугольников
  124. double RightRectangle(Function f, double a, double b, int n)
  125. {
  126. assert(n >= 2);
  127.  
  128. double res = 0.0;
  129.  
  130. double h = (b - a) / (n - 1), x = a + h;
  131.  
  132. for (int i = 2; i <= n; ++i, x += h)
  133. res += f(x);
  134.  
  135. return res * h;
  136. }
  137.  
  138. // Метод средних прямоугольников
  139. double Rectangle(Function f, double a, double b, int n)
  140. {
  141. assert(n >= 2);
  142.  
  143. double res = 0.0;
  144.  
  145. double h = (b - a) / (n - 1), x = a + h / 2;
  146.  
  147. for (int i = 1; i <= n - 1; ++i, x += h)
  148. res += f(x);
  149.  
  150. return res * h;
  151. }
  152.  
  153. // Метод трапеций
  154. double Trapezoid(Function f, double a, double b, int n)
  155. {
  156. assert(n >= 2);
  157.  
  158. double res = (f(a) + f (b)) / 2.0;
  159.  
  160. double h = (b - a) / (n - 1), x = a + h;
  161.  
  162. for (int i = 2; i <= n - 1; ++i, x += h)
  163. res += f(x);
  164.  
  165. return res * h;
  166. }
  167.  
  168. // Метод Симпсона (парабол)
  169. double Simpson(Function f, double a, double b, int n)
  170. {
  171. assert(n >= 2);
  172.  
  173. double res1 = 0.0, res2 = 0.0;
  174.  
  175. double h = (b - a) / 2.0 / (n - 1), x = a + h;
  176.  
  177. for (int i = 2; i <= 2 * n - 2; ++i, x += h)
  178. if (i & 1) res1 += f(x);
  179. else res2 += f(x);
  180.  
  181. double res = f(a) + f(b) + 2 * res1 + 4 * res2;
  182.  
  183. return res * h / 3.0;
  184. }
  185.  
  186. //integrate.h
  187. #ifndef INTEGRATE
  188. #define INTEGRATE
  189.  
  190. typedef double (*Function)(double);
  191. typedef double (*Method)(Function, double, double, int);
  192.  
  193. double LeftRectangle(Function, double, double, int);
  194. double RightRectangle(Function, double, double, int);
  195. double Rectangle(Function, double, double, int);
  196. double Trapezoid(Function, double, double, int);
  197. double Simpson(Function, double, double, int);
  198.  
  199. #endif
Add Comment
Please, Sign In to add comment