在python中集成3体系

时间:2015-10-07 16:48:17

标签: python numpy scipy

这是一个更为数学的问题。

我们有3个身体系统,具有已知的初始参数,如位置,质量,速度。这使得系统像 enter image description here

我和j = 1,2,3
那么问题是如何处理这个问题,将这个系统提供给 scipy odeint

更新
 我写了代码

from scipy import linspace
from scipy.integrate import odeint

def rf(i, j, r):
    x1, y1, z1 = r[0]
    x2, y2, z2 = r[1]
    x3, y3, z3 = r[2]
    r12 = ((x1-x2)**2+(y1-y2)**2+(z1-z2)**2)**2
    r13 = ((x1-x3)**2+(y1-y3)**2+(z1-z3)**2)**2
    r23 = ((x2-x3)**2+(y2-y3)**2+(z2-z3)**2)**2
    if i == 1:
        if j == 2:
            r = r12
        elif j == 3:
            r = r13
    if i == 2:
        if j == 1:
            r = r12
        elif j == 3:
            r = r23
    if i == 3:
        if j == 1:
            r = r13
        elif j == 2:
            r = r23
    return r


def dotf(r, t0):
    x1, y1, z1 = r[0]
    x2, y2, z2 = r[1]
    x3, y3, z3 = r[2]
    x = [x1, x2, x3]
    y = [y1, y2, y3]
    z = [z1, z2, z3]

    k2 = 6.67e-11
    m = [2e6, 2.2e7, 0.1e3]

    for i in range(1, 3, 1):
        xs, ys, zs = 0, 0, 0
        for j in range(1, 3, 1):
            if i != j:
                r = rf(i, j, r)
                xs = xs + m[j]*(x[i]-x[j])/r
                ys = ys + m[j]*(y[i]-y[j])/r
                zs = zs + m[j]*(z[i]-z[j])/r
        x[i] = -1 * k2 * xs
        y[i] = -1 * k2 * ys
        z[i] = -1 * k2 * zs
    return [[x1,y1,z1], [x2,y2,z2], [x3,y3,z3]]


t = linspace(0, 50, 1e4)
r1 = [1, 2, 1]
r2 = [0.5, 0.1, 3]
r3 = [0.6, 1, 1.5]
r = [r1, r2, r3] 

u = odeint(dotf, r, t)


并得到输出错误:

Traceback (most recent call last):
  File "3b.py", line 73, in <module>
    u = odeint(dotf, r, t)
  File "/usr/local/lib/python2.7/dist-packages/scipy/integrate/odepack.py", line 148, in odeint
    ixpr, mxstep, mxhnil, mxordn, mxords)
ValueError: object too deep for desired array

1 个答案:

答案 0 :(得分:3)

我已经纠正了代码中的两个明显错误;它运行,但我不是 确定它是正确的。最后的代码。

第一个错误是odeint想要处理状态和向量的向量 国家衍生物。通过向量我的意思是rank-1数组;你提交了 矩阵(rank-2数组)作为初始条件。我改变了 r r = r1 + r2 + r3 + x1 dotf rf 列表上的运算符是串联,但它是在numpy数组上 元素添加。

此更改意味着我必须将作业更改为dotfrrf。我还将rr的返回值更改为矢量。

第二个错误是你使用odeint来表示两个不同的东西: 首先是系统状态向量,第二是从from scipy import linspace from scipy.integrate import odeint def rf(i, j, r): x1, y1, z1 = r[:3] x2, y2, z2 = r[3:6] x3, y3, z3 = r[6:] r12 = ((x1-x2)**2+(y1-y2)**2+(z1-z2)**2)**2 r13 = ((x1-x3)**2+(y1-y3)**2+(z1-z3)**2)**2 r23 = ((x2-x3)**2+(y2-y3)**2+(z2-z3)**2)**2 if i == 1: if j == 2: r = r12 elif j == 3: r = r13 if i == 2: if j == 1: r = r12 elif j == 3: r = r23 if i == 3: if j == 1: r = r13 elif j == 2: r = r23 return r def dotf(r, t0): x1, y1, z1 = r[:3] x2, y2, z2 = r[3:6] x3, y3, z3 = r[6:] x = [x1, x2, x3] y = [y1, y2, y3] z = [z1, z2, z3] k2 = 6.67e-11 m = [2e6, 2.2e7, 0.1e3] for i in range(1, 3, 1): xs, ys, zs = 0, 0, 0 for j in range(1, 3, 1): if i != j: rr = rf(i, j, r) xs = xs + m[j]*(x[i]-x[j])/rr ys = ys + m[j]*(y[i]-y[j])/rr zs = zs + m[j]*(z[i]-z[j])/rr x[i] = -1 * k2 * xs y[i] = -1 * k2 * ys z[i] = -1 * k2 * zs return [x1,y1,z1, x2,y2,z2, x3,y3,z3] t = linspace(0, 50, 1e4) r1 = [1, 2, 1] r2 = [0.5, 0.1, 3] r3 = [0.6, 1, 1.5] r = r1 + r2 + r3 u = odeint(dotf, r, t) # uncomment to plot # from matplotlib import pyplot # # pyplot.plot(t,u) # pyplot.show() 返回。一世 将第二个更改为c

解决方案似乎不稳定;我不知道这是不是 合理的。我想还有其他的错误,但你至少有 现在运行的东西。

我的建议是从你知道的更简单的东西开始 解决方案,例如,稳定的一阶线性系统,或稳定的 欠阻尼的二阶系统,或洛伦兹,如果你想要的东西 乱。

有关Scipy文档的信息,请参阅http://docs.scipy.org/doc/,例如,我使用过 http://scipy-0.13.0/reference/generated/scipy.integrate.odeint.html#scipy.integrate.odeint for awk '{k=$1 OFS $2; s[k]+=$4; c[k]++} END{for(i in s) print i, s[i]/c[i], c[i] " bases" }' input for Scipy 0.13.0(这是我的Ubuntu附带的 14.04系统)。

END