简体   繁体   English

具有龙格-库塔 python 的洛伦兹吸引子

[英]Lorenz attractor with Runge-Kutta python

  1. Hello I have to program a python function to solve Lorenz differential equations using Runge-Kutta 2cond grade您好,我必须编写 python function 来使用 Runge-Kutta 2cond 等级求解 Lorenz 微分方程

微分方程

sigma=10, r=28 and b=8/3 sigma=10, r=28 和 b=8/3

with initial conditions (x,y,z)=(0,1,0)初始条件 (x,y,z)=(0,1,0)

this is the code i wrote, but it throws me an error saying overflow encountered in double_scalars , and I don't see what is wrong with the program这是我写的代码,但它给我一个错误,说在double_scalars中遇到溢出,我看不出程序有什么问题

from pylab import *
def runge_4(r0,a,b,n,f1,f2,f3):
    def f(r,t):
        x=r[0]
        y=r[1]
        z=r[2]
        fx=f1(x,y,z,t)
        fy=f2(x,y,z,t)
        fz=f3(x,y,z,t)
        return array([fx,fy,fz],float)
    h=(b-a)/n
    lista_t=arange(a,b,h)
    print(lista_t)
    X,Y,Z=[],[],[]
    for t in lista_t:
        k1=h*f(r0,t)
        print("k1=",k1)
        k2=h*f(r0+0.5*k1,t+0.5*h)
        print("k2=",k2)
        k3=h*f(r0+0.5*k2,t+0.5*h)
        print("k3=",k3)
        k4=h*f(r0+k3,t+h)
        print("k4=",k4)
        r0+=(k1+2*k2+2*k3+k4)/float(6)
        print(r0)
        X.append(r0[0])
        Y.append(r0[1])
        Z.append(r0[2])
    return array([X,Y,Z])

def f1(x,y,z,t):
    return 10*(y-x)
def f2(x,y,z,t):
    return 28*x-y-x*z
def f3(x,y,z,t):
    return x*y-(8.0/3.0)*z
#and I run it
r0=[1,1,1]

runge_4(r0,1,50,20,f1,f2,f3)

Solving differential equations numerically can be challenging.数值求解微分方程可能具有挑战性。 If you choose too high step sizes, the solution will accumulate high errors and can even become unstable, as in your case.如果您选择太高的步长,解决方案将累积高错误,甚至可能变得不稳定,就像您的情况一样。

Either you should drastically reduce the step size ( h ) or just use the adaptive Runge Kutta method provided by scipy :您应该大幅减小步长 ( h ),或者只使用scipy提供的自适应龙格库塔方法:

from numpy import array, linspace
from scipy.integrate import solve_ivp
import pylab
from mpl_toolkits import mplot3d

def func(t, r):
    x, y, z = r 
    fx = 10 * (y - x)
    fy = 28 * x - y - x * z
    fz = x * y - (8.0 / 3.0) * z
    return array([fx, fy, fz], float)

# and I run it
r0 = [0, 1, 0]
sol = solve_ivp(func, [0, 50], r0, t_eval=linspace(0, 50, 5000))

# and plot it
fig = pylab.figure()
ax = pylab.axes(projection="3d")
ax.plot3D(sol.y[0,:], sol.y[1,:], sol.y[2,:], 'blue')
pylab.show()

This solver uses 4th and 5th order Runge Kutta combination and controls the deviation between them by adapting the step size.该求解器使用 4 阶和 5 阶 Runge Kutta 组合,并通过调整步长来控制它们之间的偏差。 See more usage documentation here: https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html在此处查看更多使用文档: https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.ZFC35FDC70D5FC69D269EZ883A822C7A53

在此处输入图像描述

You use a step size of h=2.5 .您使用的步长为h=2.5

For RK4 the useful step sizes given a Lipschitz constant L are in the range L*h=1e-3 to 0.1 , one might get somewhat right looking results up to L*h=2.5 .对于 RK4,给定 Lipschitz 常数L的有用步长在L*h=1e-30.1的范围内,直到L*h=2.5可能会得到一些正确的结果。 Above that the method turns chaotic, any resemblance to the underlying ODE is lost.除此之外,该方法变得混乱,与底层 ODE 的任何相似性都将丢失。

The Lorenz system has a Lipschitz constant of about L=50 , see Chaos and continuous dependency of ODE solution , so h<0.05 is absolutely required, h=0.002 is better and h=2e-5 gives the numerically best results for this numerical method. Lorenz 系统的 Lipschitz 常数约为L=50 ,参见Chaos and Continuous dependency of ODE 解,因此绝对需要h<0.05h=0.002更好, h=2e-5给出了该数值方法的最佳数值结果.

It can be related to a division by zero or when a limit of a type is exceeded (float type).它可能与除以零或超出类型的限制(浮点类型)有关。

To figure out where and when it happens you can set numpy.seterr('raise') and it will raise an exception so you can debug and see what it's happening.要弄清楚它发生的地点和时间,您可以设置numpy.seterr('raise')它将引发异常,以便您可以调试并查看它发生了什么。 It seems your algorithm is diverging.看来您的算法正在发散。

Here you can se how to use numpy.seterr在这里您可以了解如何使用numpy.seterr

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM