在Python中使用Runge-kutta四阶的ODE系统

时间:2015-08-02 11:46:13

标签: python ode runge-kutta

我正在编写一个python程序来解决初始条件下的一阶微分方程的2x2系统。我的代码:

    If tsShowElapsed.Hours > 0 Then
        strFormat = "{0:#0}:{1:#0}:{2:00}"
    Else
        strFormat = "{1:#0}:{2:00}"
    End If


    lblShowTimer.Text = String.Format(strFormat,
                             Math.Floor(tsShowElapsed.TotalHours),
                              tsShowElapsed.Minutes,
                              tsShowElapsed.Seconds)

我知道我可以from math import * import numpy as np np.set_printoptions(precision=6) ## control numpy's decimal output :) form1 = raw_input('Enter the 1st function of u & v only >> ') form2 = raw_input('Enter the 2nd function of u & v only >> ') start = input("Enter the lower limit of the interval >> ") stop = input("Enter the upper limit of the interval >> ") h = input("Using step size? ") N = int(np.round((stop - start)/h, decimals = 4)) ##calculate the number of times to iterate ## np.round fixes a python bug returning 2.99999997 instead of ## 3 which reduced the number of times iterated by -1 k = np.zeros((2, 4)) u = np.zeros((N +1,)) ## fill our u's first with N+1 0's v = np.zeros((N +1,)) ## fill our v's first with N+1 0's u[0] = input("Give me an initial value for u'>> ") v[0] = input("Give me the second initial value for v' >> ") t = np.arange(start, stop + h, h) def f1(t, u, v): return eval(form1) def f2(t, u, v): return eval(form2) ##for u now def trialu(): for j in range(0, N): k[0, 0] = h * f1(t[j], u[j], v[j]) k[1, 0] = h * f2(t[j], u[j], v[j]) k[0, 1] = h * f1(t[j] + h/2, u[j] + 0.5*k[0, 0], v[j] + 0.5*k[1, 0]) k[1, 1] = h * f2(t[j] + h/2, u[j] + 0.5*k[0, 0], v[j] + 0.5*k[1, 0]) k[0, 2] = h * f1(t[j] + h/2, u[j] + 0.5*k[0, 1], v[j] + 0.5*k[1, 1]) k[1, 2] = h * f2(t[j] + h/2, u[j] + 0.5*k[0, 1], v[j] + 0.5*k[1, 1]) k[0, 3] = h * f1(t[j], u[j] + k[0, 2], v[j] + k[1, 2]) k[1, 3] = h * f2(t[j], u[j] + k[0, 2], v[j] + k[1, 2]) u[j+1] = u[j] + (k[0, 0] + 2*k[0, 1] + 2*k[0, 2] + k[0, 3])/6 v[j+1] = v[j] + (k[1, 0] + 2*k[1, 1] + 2*k[1, 2] + k[1, 3])/6 return u 但我希望return (u, v)能有所不同而且print "u ~ ", u会在另一条线上显示,但似乎我只需重复试验以返回v,是否有更好的办法?不重复v?我也想打印k为j = 1,2,...单独?
一个示例是使用def trialu()u' = -3*u + 2*v以及v' = 3*u - 4*v的步长来解决[0,0.4]中的h = 0.1u[0] = 0

1 个答案:

答案 0 :(得分:0)

我不确定你在问什么,也许这很有用:

# example u and v
u = [1.003, 1.002, 1.001]
v = [0, 0, 0]

for i, (uapprox, vapprox) in enumerate(zip(u, v)):
    print "on iteration", i, "u ~", uapprox, "and v ~", vapprox

输出:

on iteration 0 u ~ 1.003 and v ~ 0
on iteration 1 u ~ 1.002 and v ~ 0
on iteration 2 u ~ 1.001 and v ~ 0