Лабораторная работа №4
.pdf
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
