简体   繁体   English

在python中的龙格库塔方法

[英]Runge Kutta method in python

These are the functions I have written: 这些是我写的功能:

def rk4(f, t0, y0, h, N):
    t = t0 + arange(N+1)*h
    y = zeros((N+1, size(y0)))
    y[0] = y0
    for n in range(N):
        xi1 = y[n]
        f1 = f(t[n], xi1)
        xi2 = y[n] + (h/2.)*f1
        f2 = f(t[n+1], xi2)
        xi3 = y[n] + (h/2.)*f2
        f3 = f(t[n+1], xi3)
        xi4 = y[n] + h*f3
        f4 = f(t[n+1], xi4)
        y[n+1] = y[n] + (h/6.)*(f1 + 2*f2 + 2*f3 + f4)
    return y

def lorenzPlot():
    y = rk4(fLorenz, 0, array([0,2,20]), .01, 10000)
    fig = figure()
    ax = Axes3D(fig)
    ax.plot(*y.T)

def fLorenz(t,Y):   
    def Y(x,y,z):
        return array([10*(y-x), x*(28-z)-y, x*y-(8./3.)*z])

By implementing lorenzPlot, it's supposed to graph the numerical solution to fLorenz (the Lorenz system of equations) obtained using rk4 (4th order Runge Kutta method). 通过实现lorenzPlot,它应该将数值解映射到使用rk4(四阶Runge Kutta方法)获得的fLorenz(Lorenz方程组)。 I'm having a problem with the function fLorenz. 我的函数fLorenz有问题。 When I define it as above and call lorenzPlot, I get an error that says 当我如上所述定义它并调用lorenzPlot时,我得到一个错误

File "C:/...", line 38, in rk4
    xi2 = y[n] + (h/2.)*f1
TypeError: unsupported operand type(s) for *: 'float' and 'NoneType'

I guessed that this had something to do with not being able to multiply the array correctly. 我猜这与无法正确乘法数组有关。
However, when I changed fLorenz to 但是,当我改变fLorenz

def fLorenz(t,x,y,z):   
    return array([10*(y-x), x*(28-z)-y, x*y-(8./3.)*z])

calling lorenzPlot gives me the error stating that fLorenz takes 4 arguments, but only 2 are given. 调用lorenzPlot给出了错误,指出fLorenz需要4个参数,但只给出了2个参数。

Additionally, rk4 and lorenzPlot both work correctly for functions composed of a singular equation. 另外,rk4和lorenzPlot都适用于由奇异方程组成的函数。

How should I change fLorenz so that it can be used as f in rk4 and lorenzPlot? 我应该如何更改fLorenz以便它可以在rk4和lorenzPlot中用作f?

Your first fLorenz function defines a sub-function, but doesn't actually return anything. 你的第一个fLorenz函数定义了一个子函数,但实际上并没有返回任何东西。 Your second one does, except it's expecting four arguments ( t, x, y, z ), and you only give it t, Y . 你的第二个确实如此,除了期望四个参数( t, x, y, z ),你只给它t, Y

From what I can understand, Y is a three-tuple; 根据我的理解, Y是一个三元组; you can simply unpack it before you use the values: 您可以在使用值之前简单地解压缩它:

def fLorenz(t, Y):
    x, y, z = Y
    return array([10*(y-x), x*(28-z)-y, x*y-(8./3.)*z])

Your fLorenz doesn't return anything, ie, due to the well documented Python conventions, it returns None . 你的fLorenz没有返回任何东西,也就是说,由于文档记录很好,它返回None

Your error message tells you 您的错误消息告诉您

unsupported operand type(s) for *: 'float' and 'NoneType' *不支持的操作数类型:'float'和'NoneType'

and that the error happens in the statement 并且该错误发生在语句中

    xi2 = y[n] + (h/2.)*f1

In the previous line you assigned to f1 what is returned by an invocation of fLorenz , ie, None . 在上一行中,您为f1分配了fLorenz调用返回的fLorenz ,即None

If you change the function fLorenz so that it returns a numerical value, either scalar or array, maybe you can proceed with your calculation. 如果更改函数fLorenz以使其返回数值(标量或数组),则可以继续进行计算。

Apart from the implementation errors, your understanding of the RK4 method is incomplete. 除了实现错误之外,您对RK4方法的理解还不完整。 The evaluation of the midpoint slopes has to happen at the midpoint of all components, which includes the time component. 中点斜率的评估必须发生在所有组件的中点,包括时间组件。 Thus it should be t[n]+h/2 instead of t[n+1] in the evaluation of f2 and f3 . 因此,在f2f3的评估中应该是t[n]+h/2而不是t[n+1]

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

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