137 lines
3.6 KiB
Python
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()
|