Advertisement
Xsufu

Формулы Ньютона-Котеса

Dec 5th, 2020 (edited)
593
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 13.37 KB | None | 0 0
  1. using System;
  2.  
  3. namespace Integration {
  4.     class Program {
  5.        
  6.         //Делегат для упрощённого выбора
  7.         delegate float func(float x);
  8.  
  9.         //Исходная функция задания а
  10.         static float Afunc(float x) {
  11.             return 1 / (float)(Math.Pow(Math.Cosh(x),2));
  12.         }
  13.        
  14.         //Исходная функция задания б
  15.         static float Bfunc(float x) {
  16.             return (float)Math.Sqrt(x + 1);
  17.         }
  18.  
  19.         //Метод правых квадратов
  20.         static float right_rectangles(func func, float mim_lim, float max_lim, float n) {
  21.             //Выделяем память под ответ
  22.             float integral = 0.0f;
  23.             //Вычисление шага
  24.             float step = (max_lim - mim_lim) / n;
  25.             //Вычисляем сумму площадей в установленных границах
  26.             //x меняется на шаг
  27.             for (float x = mim_lim; x < max_lim - step; x += step)
  28.                 integral += step * func(x + step);
  29.             //Выводим численное значение интеграла
  30.             if (func != Bfunc)
  31.                 Console.WriteLine($"Интеграл равен: {integral}");
  32.             return integral;
  33.         }
  34.  
  35.         //Метод левых прямоугольников
  36.         //Работает по аналогии с правыми, но x+step
  37.         static float left_rectangle(func func, float mim_lim, float max_lim, float n) {
  38.             float integral = 0.0f;
  39.             float step = (max_lim - mim_lim) / n;
  40.             for (float x = mim_lim; x < max_lim - step; x += step)
  41.                 integral += step * func(x);
  42.             if (func != Bfunc)
  43.                 Console.WriteLine($"Интеграл равен: {integral}");
  44.             return integral;
  45.         }
  46.  
  47.         //Метод средних прямоугольников
  48.         //Работает как и остальные прямоугольники, но x + step/2
  49.         static float middle_rectangles(func func, float mim_lim, float max_lim, float n) {
  50.             float integral = 0.0f;
  51.             float step = (max_lim - mim_lim) / n;
  52.             for (float x = mim_lim; x < max_lim - step; x+=step)
  53.                 integral += step * func(x + step / 2);
  54.             if (func != Bfunc)
  55.                 Console.WriteLine($"Интеграл равен: {integral}");
  56.             return integral;
  57.         }
  58.  
  59.         //Метод Трапеций
  60.         static float trapezium(func func, float mim_lim, float max_lim, float n) {
  61.             //Память под результат
  62.             float integral = 0.0f;
  63.             //Шаг
  64.             float step = (max_lim - mim_lim) / n;
  65.             //Вычисляем сумму площадей в установленных границах
  66.             //x меняется на шаг
  67.             for (float x = mim_lim; x < max_lim - step; x += step)
  68.                 integral += step * ( (func(x) + func(x+step))/2 );
  69.             if (func != Bfunc)
  70.                 Console.WriteLine($"Интеграл равен: {integral}");
  71.             return integral;
  72.         }
  73.  
  74.         //Метод Симпсона
  75.         static float simpson(func func, float mim_lim, float max_lim, float n) {
  76.             //Выделяем память под ответ
  77.             float integral = 0.0f;
  78.             //Шаг
  79.             float step = (max_lim - mim_lim) / n;
  80.             //Вычисляем сумму площадей в установленных границах
  81.             //x меняется на шаг
  82.             for (float x = mim_lim; x < max_lim - step; x += step)
  83.                 integral += step/6 * (func(x) + 4 * func(x + step/2) + func(x+step));
  84.             if (func != Bfunc)
  85.                 Console.WriteLine($"Интеграл равен: {integral}");
  86.             return integral;
  87.         }
  88.  
  89.         //Правило Симпсона 3/8
  90.         //Сложная формула Ньютона-Котеса с m=3
  91.         static float simpson38(func func, float min_lim, float max_lim, float n) {
  92.             //шаг
  93.             float step = (max_lim - min_lim) / n;
  94.             //Вычисляем слагаемые без множителей
  95.             float integral = func(min_lim) + func(max_lim);
  96.  
  97.             //Вычисляет значение до y без множителя
  98.             for (int i = 1; i < n; i++) {
  99.                 //Если элемент третий в триаде, то домножаем на 2
  100.                 if (i % 3 == 0)
  101.                     integral = integral + 2 * func(min_lim + i * step);
  102.                 //Если 1-ый или 2-ой в триаде то на 3
  103.                 else
  104.                     integral = integral + 3 * func(min_lim + i * step);
  105.             }
  106.             //Вычисляем значение интеграла домножив 3/8 и шаг
  107.             integral =  (3 * step / 8) * integral;
  108.             if (func != Bfunc)
  109.                 Console.WriteLine($"Интеграл равен: {integral}");
  110.             return integral;
  111.         }
  112.  
  113.         //Правило Симпсона 2/45
  114.         //Сложная Формула Ньютона-Котеса с m=4
  115.         static float simpson245(func func, float min_lim, float max_lim, float n) {
  116.             //Шаг
  117.             float step = (max_lim - min_lim) / n;
  118.             //Вычисляем сумму первого и последнего слагаемых
  119.             float integral = 7*func(min_lim) + 7*func(max_lim);
  120.             //Костыль для 12 и 14
  121.             Boolean flag = false;
  122.  
  123.             //ВЫчисляем до последнего слагаемого
  124.             for (int i = 1; i < n; i++) {
  125.                 //Если элемент нечётный, то множитель 32
  126.                 if (i % 2 != 0) {
  127.                     integral = integral + 32 * func(min_lim + i * step);
  128.                 }
  129.  
  130.                 //Иначе 12 или 14 по очереди
  131.                 else if (!flag) {
  132.                     integral = integral + 12 * func(min_lim + i * step);
  133.                     flag = true;
  134.                 }
  135.  
  136.                 else if (flag) {
  137.                     integral = integral + 14 * func(min_lim + i * step);
  138.                     flag = false;
  139.                 }
  140.             }
  141.             //Вычисляем значение интеграла домножив сумму на 2/45 и шаг
  142.             integral = (2 * step / 45) * integral;
  143.             if (func != Bfunc)
  144.                 Console.WriteLine($"Интеграл равен: {integral}");
  145.             return integral;
  146.         }
  147.  
  148.         static void Main(string[] args) {
  149.             //Память под пределы интегрирования
  150.             float min = 0, max = 0;
  151.             //Выделяем память под делегат
  152.             func function = Afunc;
  153.  
  154.             int menu = 0;
  155.             Console.WriteLine("Выберите функцию:");
  156.             Console.WriteLine("\t1) 1/cosh^2(x) \n\t2) Sqrt(x+1)");
  157.             menu = Int32.Parse(Console.ReadLine());
  158.  
  159.             switch(menu) {
  160.                 case 1:
  161.                     function = Afunc;
  162.                     min = (float)Math.Log(2);
  163.                     max = (float)Math.Log(3);
  164.                     break;
  165.                 case 2:
  166.                     function = Bfunc;
  167.                     min = 1;
  168.                     max = 3;
  169.                     break;
  170.                 default:
  171.                     Console.WriteLine("Ошибка ввода");
  172.                     break;
  173.             }
  174.  
  175.             if (function == Afunc) {
  176.                 Console.WriteLine("Метод средних прямоугольников:");
  177.                 middle_rectangles(function, min, max, 5);
  178.                 middle_rectangles(function, min, max, 10);
  179.                 middle_rectangles(function, min, max, 100);
  180.  
  181.                 Console.WriteLine();
  182.                 Console.WriteLine("Метод левых прямоугольников:");
  183.                 left_rectangle(function, min, max, 5);
  184.                 left_rectangle(function, min, max, 10);
  185.                 left_rectangle(function, min, max, 100);
  186.  
  187.                 Console.WriteLine();
  188.                 Console.WriteLine("Метод правых прямоугольников:");
  189.                 right_rectangles(function, min, max, 5);
  190.                 right_rectangles(function, min, max, 10);
  191.                 right_rectangles(function, min, max, 100);
  192.  
  193.                 Console.WriteLine();
  194.                 Console.WriteLine("Метод трапеций:");
  195.                 trapezium(function, min, max, 5);
  196.                 trapezium(function, min, max, 10);
  197.                 trapezium(function, min, max, 100);
  198.  
  199.                 Console.WriteLine();
  200.                 Console.WriteLine("Метод Симпсона:");
  201.                 simpson(function, min, max, 5);
  202.                 simpson(function, min, max, 10);
  203.                 simpson(function, min, max, 100);
  204.  
  205.                 Console.WriteLine();
  206.                 Console.WriteLine("Правило Симпсона 3/8:");
  207.                 simpson38(function, min, max, 5);
  208.                 simpson38(function, min, max, 10);
  209.                 simpson38(function, min, max, 100);
  210.  
  211.                 Console.WriteLine();
  212.                 Console.WriteLine("Правило Симпсона 2/45:");
  213.                 simpson245(function, min, max, 5);
  214.                 simpson245(function, min, max, 10);
  215.                 simpson245(function, min, max, 100);
  216.             }
  217.  
  218.             else {
  219.                 //Погрешность
  220.                 const float eps = 0.001f;
  221.                 //Решение, полученное аналитическим путём
  222.                 const float answer = 3.44772f;
  223.                 //Память под результат вычислений
  224.                 float integral = 0;
  225.                 //Количество делений для задания 2
  226.                 int i = 0;
  227.  
  228.                 Console.WriteLine("Метод средних прямоугольников:");
  229.                 i = 0;
  230.                 integral = 0;
  231.                 while(Math.Abs((answer - integral)) > eps) {
  232.                     i++;
  233.                     integral = middle_rectangles(function, min, max, i);
  234.                 }
  235.                 Console.WriteLine ($"Интеграл равен: {integral}. Кол-во итераций: {i}");
  236.  
  237.                 Console.WriteLine();
  238.                 Console.WriteLine("Метод правых прямоугольников:");
  239.                 i = 0;
  240.                 integral = 0;
  241.                 while (Math.Abs((answer - integral)) > eps) {
  242.                     i++;
  243.                     integral = right_rectangles(function, min, max, i);
  244.                 }
  245.                 Console.WriteLine($"Интеграл равен: {integral}. Кол-во итераций: {i}");
  246.  
  247.                 Console.WriteLine();
  248.                 Console.WriteLine("Метод левых прямоугольников:");
  249.                 i = 0;
  250.                 integral = 0;
  251.                 while (Math.Abs((answer - integral)) > eps) {
  252.                     i++;
  253.                     integral = left_rectangle(function, min, max, i);
  254.                 }
  255.                 Console.WriteLine($"Интеграл равен: {integral}. Кол-во итераций: {i}");
  256.  
  257.                 Console.WriteLine();
  258.                 Console.WriteLine("Метод трапеций:");
  259.                 i = 0;
  260.                 integral = 0;
  261.                 while (Math.Abs((answer - integral)) > eps) {
  262.                     i++;
  263.                     integral = trapezium(function, min, max, i);
  264.                 }
  265.                 Console.WriteLine($"Интеграл равен: {integral}. Кол-во итераций: {i}");
  266.  
  267.                 Console.WriteLine();
  268.                 Console.WriteLine("Метод Симпсона:");
  269.                 i = 0;
  270.                 integral = 0;
  271.                 while (Math.Abs((answer - integral)) > eps) {
  272.                     i++;
  273.                     integral = simpson(function, min, max, i);
  274.                 }
  275.                 Console.WriteLine($"Интеграл равен: {integral}. Кол-во итераций: {i}");
  276.  
  277.                 Console.WriteLine();
  278.                 Console.WriteLine("Правило Симпсона 3/8:");
  279.                 i = 0;
  280.                 integral = 0;
  281.                 while (Math.Abs((answer - integral)) > eps) {
  282.                     i++;
  283.                     integral = simpson38(function, min, max, i);
  284.                 }
  285.                 Console.WriteLine($"Интеграл равен: {integral}. Кол-во итераций: {i}");
  286.  
  287.                 Console.WriteLine();
  288.                 Console.WriteLine("Правило Симпсона 2/45:");
  289.                 i = 0;
  290.                 integral = 0;
  291.                 while (Math.Abs((answer - integral)) > eps) {
  292.                     i++;
  293.                     integral = simpson245(function, min, max, i);
  294.                 }
  295.                 Console.WriteLine($"Интеграл равен: {integral}. Кол-во итераций: {i}");
  296.             }                
  297.         }
  298.     }
  299. }
  300.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement