Константы Рунге-Кутты, расходящиеся для системы Лоренца?
Я пытаюсь решить систему Лоренца, используя метод Рунге Кутты 4-го порядка, где
dx/dt=a*(y-x)
dy/dt=x(b-z)-y
dx/dt=x*y-c*z
Поскольку эта система не зависит от времени, возможно, эту часть итерации игнорировать, поэтому я просто имею dX=F(x,y,z)
def func(x0):
a=10
b=38.63
c=8/3
fx=a*(x0[1]-x0[0])
fy=x0[0]*(b-x0[2])-x0[1]
fz=x0[0]*x0[1]-c*x0[2]
return np.array([fx,fy,fz])
def kcontants(f,h,x0):
k0=h*f(x0)
k1=h*f(f(x0)+k0/2)
k2=h*f(f(x0)+k1/2)
k3=h*f(f(x0)+k2)
#note returned K is a matrix
return np.array([k0,k1,k2,k3])
x0=np.array([-8,8,27])
h=0.001
t=np.arange(0,50,h)
result=np.zeros([len(t),3])
for time in range(len(t)):
if time==0:
k=kcontants(func,h,x0)
result[time]=func(x0)+(1/6)*(k[0]+2*k[1]+2*k[2]+k[3])
else:
k=kcontants(func,h,result[time-1])
result[time]=result[time-1]+(1/6)*(k[0]+2*k[1]+2*k[2]+k[3])
Результатом должны быть атракторы Лоренца, однако мой код расходится вокруг пятой итерации, и это потому, что константы, которые я создаю в kconstants
сделайте, однако я проверил, и я почти уверен, что внедрение Rge Kutta не виновато... (по крайней мере, я думаю)
редактировать:
Нашел похожий пост, пока не могу понять, что я делаю не так
3 ответа
У вас есть дополнительный звонок f(x0)
в расчете k1
, k2
а также k3
, Изменить функцию kcontants
в
def kcontants(f,h,x0):
k0=h*f(x0)
k1=h*f(x0 + k0/2)
k2=h*f(x0 + k1/2)
k3=h*f(x0 + k2)
#note returned K is a matrix
return np.array([k0,k1,k2,k3])
Вы смотрели на разные начальные значения для вашего расчета? Имеют ли смысл те, которые вы выбрали? Т.е. они физические? Из прошлого опыта с rk вы можете иногда получить очень запутанные результаты, если выберете глупые стартовые параметры.
Спокойной ночи. Это и версия, которую я сделал с помощью интегратора scipy edo, scipy.integrate.odeint .
# Author : Carlos Eduardo da Silva Lima
# Theme : Movement of a Plant around a fixed star
# Language : Python
# date : 11/19/2022
# Environment : Google Colab
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
from scipy.optimize import root
from scipy.linalg import eig
from mpl_toolkits.mplot3d import Axes3D
##################################
# Condições inicial e parãmetros #
##################################
t_inicial = 0
t_final = 100
N = 10000
h = 1e-3
x_0 = 1.0
y_0 = 1.0
z_0 = 1.0
#####################
# Equação de Lorenz #
#####################
def Lorenz(r,t,sigma,rho,beta):
x = r[0]; y = r[1]; z = r[2]
edo1 = sigma*(y-x)
edo2 = x*(rho-z)-y
edo3 = x*y-beta*z
return np.array([edo1,edo2,edo3])
t = np.linspace(t_inicial,t_final,N)
r_0 = np.array([x_0,y_0,z_0])
#sol = odeint(Lorenz,r_0,t,rtol=1e-6,args = (10,28,8/3))
sol = odeint(Lorenz, r_0, t, args=(10,28,8/3), Dfun=None, col_deriv=0, full_output=0, ml=None, mu=None, rtol=1e-9, atol=1e-9, tcrit=None, h0=0.0, hmax=0.0, hmin=0.0, ixpr=0, mxstep=0, mxhnil=0, mxordn=12, mxords=5, printmessg=0, tfirst=False)
'''x = sol[:,0]
y = sol[:,1]
z = sol[:,2]'''
x, y, z = sol.T
# Plot
plt.style.use('dark_background')
ax = plt.figure(figsize = (10,10)).add_subplot(projection='3d')
ax.plot(x,y,z,'m-',lw=0.5, linewidth = 1.5)
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
ax.set_title("Atrator de Lorenz")
plt.show()
Во второй части я моделирую две системы Лоренца, чтобы проверить чувствительные зависимости систем от начальных условий. Во второй системе я добавляю определенное количество eps =1e-3 к начальным условиям x(t0), y(t0) и z(t0).
# Depedência com as condições iniciais
eps = 1e-3
r_0_eps = np.array([x_0+eps,y_0+eps,z_0+eps])
sol_eps = odeint(Lorenz, r_0_eps, t, args=(10,28,8/3), Dfun=None, col_deriv=0, full_output=0, ml=None, mu=None,
rtol=1e-9, atol=1e-9, tcrit=None, h0=0.0, hmax=0.0, hmin=0.0, ixpr=0, mxstep=0, mxhnil=0, mxordn=12, mxords=5, printmessg=0, tfirst=False)
'''x_eps = sol_eps[:,0]
y_eps = sol_eps[:,1]
z_eps = sol_eps[:,2]'''
x_eps, y_eps, z_eps = sol_eps.T
# Plot
plt.style.use('dark_background')
ax = plt.figure(figsize = (10,10)).add_subplot(projection='3d')
ax.plot(x,y,z,'r-',lw=1.5)
ax.plot(x_eps,y_eps,z_eps,'b-.',lw=1.1)
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
ax.set_title("Lorenz Attractor")
plt.show()
Надеюсь, я помог, увидимся :).