ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 01.12.2023
Просмотров: 25
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Министерство образования Республики Беларусь
Учреждение образования
БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ
ИНФОРМАТИКИ И РАДИОЭЛЕКТРОНИКИ
Факультет компьютерных систем и сетей
Кафедра информатики
Дисциплина: Методы численного анализа
ОТЧЁТ
к лабораторной работе
на тему
Метод Адамса
Выполнил: студент группы 153503
Кончик Денис Сергеевич
Проверил: Анисимов Владимир Яковлевич
Минск 2022
Содержание
1.ЦЕЛЬ РАБОТЫ 3
2.ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ 3
3.АЛГОРИТМ РЕШЕНИЯ 4
4.ПРОГРАММНАЯ РЕАЛИЗАЦИЯ 5
5. ТЕСТОВЫЕ ПРИМЕРЫ 8
6. ЗАДАНИЕ 14
7. ВЫВОД 15
-
ЦЕЛЬ РАБОТЫ
Изучить решение задачи Коши для обыкновенных дифференциальных уравнений методом Адамса.
-
ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ
-
АЛГОРИТМ РЕШЕНИЯ
-
ПРОГРАММНАЯ РЕАЛИЗАЦИЯ
# -*- coding: cp1251 -*-
import numpy as np
import matplotlib.pyplot as plt
import sympy
import math
from calculate import CalculateListY
from calculate import CalculateY
plot_dots = 10**3
eps = 10**-3
# Тестовый пример 1
# y'= y + e^x
# y = x * e^x
x0, y0 = 1, math.e
L, R = 1, 2
def f(x, y):
return y + math.e ** x
def p(x):
return -1
def q(x):
return math.e ** x
def ans(x):
return round(x * math.e ** x, 6)
# Метод Рунге-Кутта 4 порядка
def RungeKuttaMethod4(x, n):
y_list = [y0]
h = (x - x0) / n
for k in range(n):
x_k = x0 + k * h
y_k = y_list[-1]
K1 = h * f(x_k, y_k)
K2 = h * f(x_k + h / 2, y_k + K1 / 2)
K3 = h * f(x_k + h / 2, y_k + K2 / 2)
K4 = h * f(x_k + h, y_k + K3)
y_list.append(y_k + 1/6 * (K1 + 2 * K2 + 2 * K3 + K4))
return y_list
# Неявный метод Адамса 2 порядка
def AdamsImplicit2(x, n):
y_list = [y0]
h = (x - x0) / n
for k in range(n):
y_k = y_list[-1]
p_k = p(x0 + k * h)
p_k_plus1 = p(x0 + (k + 1) * h)
q_k = q(x0 + k * h)
q_k_plus1 = q(x0 + (k + 1) * h)
y_list.append(((2 - h * p_k) * y_k + h * (q_k + q_k_plus1)) / (2 + h * p_k_plus1))
return y_list
# Явный метод Адамса 2 порядка
def AdamsExplicit2(x, n):
h = (x - x0) / n
y_list = [y0, CalculateY(RungeKuttaMethod4, x0 + h, eps)[0]]
for k in range (1, n):
x_k_minus1 = x0 + (k - 1) * h
x_k = x0 + k * h
y_k_minus1 = y_list[-2]
y_k = y_list[-1]
y_list.append(y_k + h * ((3/2) * f(x_k,y_k) - (1/2) * f(x_k_minus1, y_k_minus1)))
return y_list
# Явный метод Адамса 3 порядка
def AdamsExplicit3(x, n):
h = (x - x0) / n
y_list = [y0, CalculateY(RungeKuttaMethod4, x0 + h, eps)[0], CalculateY(RungeKuttaMethod4, x0 + 2 * h, eps)[0]]
for k in range (2, n):
x_k_minus2 = x0 + (k - 2) * h
x_k_minus1 = x0 + (k - 1) * h
x_k = x0 + k * h
y_k_minus2 = y_list[-3]
y_k_minus1 = y_list[-2]
y_k = y_list[-1]
y_list.append(y_k + h*((23/12)*f(x_k,y_k)-(4/3)*f(x_k_minus1,y_k_minus1)+(5/12)*f(x_k_minus2,y_k_minus2)))
return y_list
x_list = []
for i in range(plot_dots + 1):
x_list.append(L + (R - L) / plot_dots * i)
xToCalculate = 1.5
print(f"Количество точек для построения графика: {plot_dots}")
print(f"Точность: {eps:.0e}")
print("\nN_max – максимальное количество узлов для одной из точек, \nнеобходимое для достижения заданной точности")
print("N_middle – среднее количество узлов по всем точкам при \nдостижении заданной точности")
print(f"\nТочка: {xToCalculate}")
print(f"Калькулятор: {ans(xToCalculate)}")
y_list, N_max, N_middle = CalculateListY(AdamsImplicit2, x_list, eps)
print("\nНеявный метод Адамса 2 порядка O(h^2):")
print(f"N_max: {N_max}")
print(f"N_middle: {int(N_middle)}")
print("На графике: красный")
print(f"В точке: {CalculateY(AdamsImplicit2, xToCalculate, eps)[0]} [{CalculateY(AdamsImplicit2, xToCalculate, eps)[1]}]")
print(f"Delta = {abs(CalculateY(AdamsImplicit2, xToCalculate, eps)[0] - ans(xToCalculate)):.2e}")
plt.plot(x_list, y_list, 'red', linewidth = 2)
y_list, N_max, N_middle = CalculateListY(AdamsExplicit2, x_list, eps)
print("\nЯвный метод Адамса 2 порядка O(h^2):")
print(f"N_max: {N_max}")
print(f"N_middle: {int(N_middle)}")
print("На графике: синий")
print(f"В точке: {CalculateY(AdamsExplicit2, xToCalculate, eps)[0]} [{CalculateY(AdamsExplicit2, xToCalculate, eps)[1]}]")
print(f"Delta = {abs(CalculateY(AdamsExplicit2, xToCalculate, eps)[0] - ans(xToCalculate)):.2e}")
plt.plot(x_list, y_list, '--b', linewidth = 2)
y_list, N_max, N_middle = CalculateListY(AdamsExplicit3, x_list, eps)
print("\nЯвный метод Адамса 3 порядка O(h^3):")
print(f"N_max: {N_max}")
print(f"N_middle: {int(N_middle)}")
print("На графике: желтый")
print(f"В точке: {CalculateY(AdamsExplicit3, xToCalculate, eps)[0]} [{CalculateY(AdamsExplicit3, xToCalculate, eps)[1]}]")
print(f"Delta = {abs(CalculateY(AdamsExplicit3, xToCalculate, eps)[0] - ans(xToCalculate)):.2e}")
plt.plot(x_list, y_list, ':y', linewidth = 2)
plt.show()
# Вычислить Y по методу и X
def CalculateY(method, x, eps):
n = 1 # Количество узлов от x0 до x для точности eps
while True:
y_list = method(x, n)
y_list_correctly = method(x, n * 2)
max_delta = max(abs(y_list_correctly[2 * i] - y_list[i]) for i in range(n + 1))
if (max_delta < eps):
return round(y_list_correctly[-1], 6), n * 2
else:
n *= 2
# Создать список Y по методу и списку X
def CalculateListY(method, x_list, eps):
y_list = [] # Список игреков
n_list = [] # Список n (числа узлов) для каждой точки
for x in x_list:
y, n = CalculateY(method, x, eps)
y_list.append(y)
n_list.append(n)
return y_list, max(n_list), sum(n_list) / len(x_list)
5. ТЕСТОВЫЕ ПРИМЕРЫ
Явные методы Адамса k-го порядка требуют предварительного вычисления решения в k начальных точках. Для вычисления начальных значений программа использует метод Рунге-Кутта 4-го порядка.
Для неявного метода Адамса 2-го порядка программа считает, что исходное дифференциальное уравнение является линейным.
Тестовый пример 1.1.
С помощью неявного метода Адамса 2 порядка1, явных методов Адамса 2, 3, 4 порядков2,3,4 найти с заданной точностью решение заданного уравнения на заданном отрезке.
ДУ | Начальное условие | Отрезок | Решение | Точность | |||
| | | | | |||
Точек для построения графиков: | |||||||
| |||||||
1 – красный, 2 – синий, 3 – желтый, 4 – черный | |||||||
Количество необходимых для достижения заданной точности точек разбиения отрезка для одной из точек в методе | |||||||
| Адамс [2] (неявный) | Адамс [2] (явный) | Адамс [3] (явный) | Адамс [4] (явный) | |||
Макс. | 2048 | 4096 | 512 | 256 | |||
Ср. | 556 | 1228 | 190 | 71 |
Тестовый пример 1.2.
Для условия предыдущего задания найти значения решения задачи Коши в заданных точках.
n – число точек разбиения отрезка [1; x] для достижения заданной точности в точке x.
– шаг разбиения, соответствующий количеству точек разбиения n.
Неявный метод Адамса 2-го порядка | |||
x | 2.0 | 2.7 | 3.4 |
| | | |
Метод(х) | | | |
| | | |
n | 128 | 512 | 1024 |
| | | |
Явный метод Адамса 2-го порядка | |||
x | 2.0 | 2.7 | 3.4 |
| | | |
Метод(х) | | | |
| | | |
n | 256 | 1024 | 2048 |
| | | |
Явный метод Адамса 3-го порядка | |||
x | 2.0 | 2.7 | 3.4 |
| | | |
Метод(х) | | | |
| | | |
n | 64 | 128 | 256 |
| | | |