Files
Runge-Kutta/main.py
T
2024-11-17 21:13:16 +03:00

137 lines
3.6 KiB
Python

'''import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
y = np.sin(x)
fig, ax = plt.subplots()
line, = ax.plot(x,y)
ax.set_xlabel('x-axis')
ax.set_ylabel('y-axis')
ax.set_title('Graph')
#plt.plot(x,y, label='sin(x)')
#plt.plot(x,y*2, label='cos(x)')
def update_graph(new_y):
line.set_ydata(new_y)
plt.draw()
plt.pause(0.1)
ax.grid(True)
ax.legend()
for i in range(10):
new_y = np.sin(x + 0.5 * i)
update_graph(new_y)
plt.show()
'''
import numpy as np
import matplotlib.pyplot as plt
# Определяем функции для уравнений
def func_a(x, y):
return x + np.cos(y)
def func_b(x, y):
return x**2 + y**2
# Реализация метода Рунге-Кутты 2-го порядка
def runge_kutta_2(f, x0, y0, h, N):
x = x0 + np.arange(N+1) * h
y = np.zeros(N+1)
y[0] = y0
for k in range(N):
k1 = f(x[k], y[k])
k2 = f(x[k] + h, y[k] + h * k1)
y[k+1] = y[k] + h * (k1 + k2) / 2
return x, y
# Реализация метода Рунге-Кутты 4-го порядка
def runge_kutta_4(f, x0, y0, h, N):
x = x0 + np.arange(N+1) * h
y = np.zeros(N+1)
y[0] = y0
for k in range(N):
k1 = f(x[k], y[k])
k2 = f(x[k] + h/2, y[k] + h * k1 / 2)
k3 = f(x[k] + h/2, y[k] + h * k2 / 2)
k4 = f(x[k] + h, y[k] + h * k3)
y[k+1] = y[k] + h * (k1 + 2*k2 + 2*k3 + k4) / 6
return x, y
# Начальные условия и параметры
equations = {
'a': {'func': func_a, 'x0': 1.0, 'y0': 30.0, 'x_end': 2.0},
'b': {'func': func_b, 'x0': 2.0, 'y0': 1.0, 'x_end': 1.0} # Обратное интегрирование
}
methods = {
'RK2': runge_kutta_2,
'RK4': runge_kutta_4
}
h_values = [0.1, 0.05, 0.01, 0.005, 0.001]
N_values = [10, 20, 100, 200, 1000]
for eq_label, eq_params in equations.items():
print(f"\nРешение для уравнения {eq_label}:")
x0 = eq_params['x0']
y0 = eq_params['y0']
x_end = eq_params['x_end']
if x_end < x0:
direction = -1
else:
direction = 1
for method_label, method_func in methods.items():
print(f"\nМетод {method_label}:")
ys = {}
xs = {}
abs_errors = []
max_abs_errors = []
for h, N in zip(h_values, N_values):
h = direction * h # Учёт направления интегрирования
x, y = method_func(eq_params['func'], x0, y0, h, N)
xs[N] = x
ys[N] = y
for i in range(1, len(N_values)):
N_prev = N_values[i-1]
N_curr = N_values[i]
# Поиск общих индексов для сравнения
factor = N_curr // N_prev
indices = [int(k * factor) for k in [1, N_prev]]
# Вычисление относительных ошибок
rel_errors = np.abs(ys[N_curr][indices] - ys[N_prev][[1, N_prev]])
print(f"N_{N_curr}: {' '.join(map(str, rel_errors))}")
# Вычисление максимальных абсолютных ошибок
max_error = np.max(rel_errors)
max_abs_errors.append(max_error)
# Построение графика логарифма абсолютных ошибок
plt.plot(np.log2(N_values[1:]), np.log2(max_abs_errors), label=f"{method_label} для уравнения {eq_label}")
plt.xlabel("log2(N)")
plt.ylabel("log2(max абсолютная ошибка)")
plt.legend()
plt.title("График логарифма абсолютных ошибок")
plt.show()