Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабораторная работа №4

.pdf
Скачиваний:
3
Добавлен:
24.01.2025
Размер:
1.11 Mб
Скачать

3.1 Метод Эйлера

Это самый простой метод группы, он использует разложение Тейлора до первой производной. Таким образом, метод Эйлера осуществляет движение в каждой следующей точке по касательной к кривой, проведенной в предыдущей точке (рисунок 3.2).

Рисунок 3.2 – Формула метода Эйлера

Реализация метода Эйлера на языке программирования C# изображена на рисунке 3.3.

Рисунок 3.3 – Код программы

3.2 Метод Рунге-Кутта 2-го порядка

Данный метод точнее, чем метод Эйлера, но для его применения нужно, чтобы была возможность увеличения числа узлов (рисунок 3.4).

Рисунок 3.4 – Формула метода Рунге-Кутта 2-го порядка Реализация метода Рунге-Кутта 2-го порядка на языке

программирования C# изображена на рисунке 3.5.

11

Рисунок 3.5 – Код программы

3.3 Метод Рунге-Кутта 4-го порядка

Этот метод наиболее часто применяется при программных расчетах и обычно его называют просто методом Рунге-Кутта. В данном методе используется разложение Тейлора до 4-го порядка включительно (рисунок

3.6):

Рисунок 3.6 – Формула метода Рунге-Кутта 4-го порядка Реализация метода Рунге-Кутта 4-го порядка на языке

программирования C# изображена на рисунке 3.7.

12

Рисунок 3.7 – Код программы

Результат работы программы всех 3х методов представлен на рисунке

3.8.

Рисунок 3.8 – Результат работы

13

Таблица 3 – Полученные значения

Точное решение

Решение методом

Решение методом

Решение методом

 

Эйлера

Рунге-Кутта 2

Рунге-Кутта 4

 

 

порядка

порядка

y1(0,1) = 1,11

y1(0,1) = 1,1

y1(0,1) = 1,11

y1(0,1) = 1,11

 

 

 

 

y2(0,2) = 1,23

y2(0,2) = 1,21

y2(0,2) = 1,23

y2(0,2) = 1,23

 

 

 

 

y3(0,3) = 1,37

y3(0,3) = 1,34

y3(0,3) = 1,37

y3(0,3) = 1,37

 

 

 

 

y4(0,4) = 1,54

y4(0,4) = 1,49

y4(0,4) = 1,54

y4(0,4) = 1,54

 

 

 

 

y5(0,5) = 1,74

y5(0,5) = 1,67

y5(0,5) = 1,74

y5(0,5) = 1,74

 

 

 

 

y6(0,6) = 1,99

y6(0,6) = 1,89

y6(0,6) = 1,99

y6(0,6) = 1,99

 

 

 

 

y7(0,7) = 2,29

y7(0,7) = 2,15

y7(0,7) = 2,29

y7(0,7) = 2,29

 

 

 

 

y8(0,8) = 2,65

y8(0,8) = 2,47

y8(0,8) = 2,65

y8(0,8) = 2,65

 

 

 

 

y9(0,9) = 3,08

y9(0,9) = 2,84

y9(0,9) = 3,07

y9(0,9) = 3,08

 

 

 

 

y10(1) = 3,59

y10(1) = 3,29

y10(1) = 3,59

y10(1) = 3,59

 

 

 

 

y11(1,1) = 4,2

y11(1,1) = 3,82

y11(1,1) = 4,19

y11(1,1) = 4,2

 

 

 

 

y12(1,2) = 4,92

y12(1,2) = 4,44

y12(1,2) = 4,91

y12(1,2) = 4,92

 

 

 

 

y13(1,3) = 5,77

y13(1,3) = 5,17

y13(1,3) = 5,75

y13(1,3) = 5,77

 

 

 

 

y14(1,4) = 6,76

y14(1,4) = 6,03

y14(1,4) = 6,74

y14(1,4) = 6,76

 

 

 

 

y15(1,5) = 7,91

y15(1,5) = 7,02

y15(1,5) = 7,89

y15(1,5) = 7,91

 

 

 

 

y16(1,6) = 9,25

y16(1,6) = 8,17

y16(1,6) = 9,22

y16(1,6) = 9,25

 

 

 

 

y17(1,7) = 10,79

y17(1,7) = 9,5

y17(1,7) = 10,76

y17(1,7) = 10,79

 

 

 

 

y18(1,8) = 12,56

y18(1,8) = 11,03

y18(1,8) = 12,53

y18(1,8) = 12,57

 

 

 

 

y19(1,9) = 14,61

y19(1,9) = 12,78

y19(1,9) = 14,57

y19(1,9) = 14,61

 

 

 

 

y20(2) = 16,94

y20(2) = 14,78

y20(2) = 16,89

y20(2) = 16,95

 

 

 

 

Для каждого численного решения был построен совместный график

полученной последовательности ( ) и точного решения ( ) (рисунок 3.9).

14

Как видно на рисунке, методы Рунге-Кутта 2-го и 4-го порядка сильно отличаются по точности от метода Эйлера, по той причине, что метод Эйлера самый простой и при этом самый неточный метод. Также метод Рунге-Кутта

4-го порядка практически совпадает с точным решением, чуть ли не идентичен.

15

Заключение

В ходе выполнения лабораторной работы были освоены вычислительные методы нахождения определенного интеграла и исследования точности вычислений при разном числе разбиений, а также методы группы Рунге-Кутта для численного решения дифференциального уравнения первого порядка (задачи Коши).

Отчет был написан согласно ОС ТУСУР 01-2021.

16

Приложение А

using System;

class NumericalIntegration

{

//Функция под интегралом static double f(double x)

{

return Math.Exp(0.3 * x) * Math.Sqrt(0.8 * x);

}

//Метод левых прямоугольников

static double LeftRectangleMethod(double a, double b, int n)

{

double h = (b - a) / n; double sum = 0.0;

for (int i = 0; i < n; i++)

{

sum += f(a + i * h);

}

return Math.Round(sum * h, 2);

}

// Метод правых прямоугольников

static double RightRectangleMethod(double a, double b, int n)

{

double h = (b - a) / n; double sum = 0.0;

for (int i = 1; i <= n; i++)

{

sum += f(a + i * h);

}

return Math.Round(sum * h, 2);

}

// Метод трапеций

static double TrapezoidMethod(double a, double b, int n)

{

double h = (b - a) / n;

double sum = 0.5 * (f(a) + f(b)); for (int i = 1; i < n; i++)

{

sum += f(a + i * h);

}

return Math.Round(sum * h, 2);

}

// Метод Симпсона

static double SimpsonMethod(double a, double b, int n)

{

if (n % 2 == 1) n++; double h = (b - a) / n; double sum = f(a) + f(b);

for (int i = 1; i < n; i++)

{

sum += f(a + i * h) * (i % 2 == 0 ? 2 : 4);

}

return Math.Round(sum * h / 3, 2);

}

static void Main()

{

double a = 3.0, b = 4.0;

int[] ns = { 6, 40, 120, 400 }; foreach (int n in ns)

{

Console.WriteLine($"n = {n}");

Console.WriteLine($"Метод левых прямоугольников: {LeftRectangleMethod(a,

b, n)}");

17

Console.WriteLine($"Метод правых прямоугольников: {RightRectangleMethod(a, b, n)}");

Console.WriteLine($"Метод трапеции: {TrapezoidMethod(a, b, n)}"); Console.WriteLine($"Метод Симпсона: {SimpsonMethod(a, b, n)}"); Console.WriteLine();

}

}

}

18

Приложение Б

using System;

class DerivativeCalculator

{

//Функция, производную которой надо найти static double f(double x)

{

return 2 * x * x * x + x + 1;

}

//Левая разностная производная

static double LeftDerivative(double x, double h)

{

return Math.Round((f(x) - f(x - h)) / h, 2);

}

// Правая разностная производная

static double RightDerivative(double x, double h)

{

return Math.Round((f(x + h) - f(x)) / h, 2);

}

// Центральная разностная производная

static double CentralDerivative(double x, double h)

{

return Math.Round((f(x + h) - f(x - h)) / (2 * h), 2);

}

// Точное значение производной

static double ExactDerivative(double x)

{

return Math.Round(6*x*x + 1, 2);

}

static void Main()

{

double h = 0.1;

double x; // Значение точки, в которой нужно вычислить производную // Значение точки, для вычисления

x = 1.0;

Console.WriteLine($"f'(x) точное: {ExactDerivative(x)}"); Console.WriteLine($"Левая разностная производная: {LeftDerivative(x, h)}"); Console.WriteLine($"Правая разностная производная: {RightDerivative(x,

h)}");

Console.WriteLine($"Центральная разностная производная: {CentralDerivative(x, h)}");

}

}

19

Приложение В

using System;

class DifferentialEquationSolver

{

static double Function(double x, double y)

{

return 2*x*x + y; // y′=2x2+y

}

// Метод Эйлера (Метод Рунге-Кутта 1-го порядка)

static double EulerMethod(double x0, double y0, double h, int steps)

{

double y = y0; double x = x0;

for (int i = 1; i <= steps; i++)

{

y += h * Function(x, y); x += h;

}

return y;

}

// Метод Рунге-Кутта 2-го порядка

static double RungeKutta2ndOrder(double x0, double y0, double h, int steps)

{

double y = y0; double x = x0;

for (int i = 1; i <= steps; i++)

{

double k1 = h * Function(x, y);

double k2 = h * Function(x + h, y + k1); y += (k1 + k2) / 2.0;

x += h;

}

return y;

}

// Метод Рунге-Кутта 4-го порядка

static double RungeKutta4thOrder(double x0, double y0, double h, int steps)

{

double y = y0; double x = x0;

for (int i = 1; i <= steps; i++)

{

double k1 = h * Function(x, y);

double k2 = h * Function(x + h / 2.0, y + k1 / 2.0); double k3 = h * Function(x + h / 2.0, y + k2 / 2.0); double k4 = h * Function(x + h, y + k3);

y += (k1 + 2 * k2 + 2 * k3 + k4) / 6.0; x += h;

}

return y;

}

static void Main()

{

double x0 = 0, y0 = 1, h = 0.1; int steps = 20;

Console.WriteLine("Метод Эйлера:"); for (int i = 1; i <= steps; i++)

{

double yi = EulerMethod(x0, y0, h, i); Console.WriteLine($"{Math.Round(yi, 2)}");

}

Console.WriteLine("\nМетод Рунге-Кутта 2-го порядка:"); for (int i = 1; i <= steps; i++)

20