这是一个更为数学的问题。
我们有3个身体系统,具有已知的初始参数,如位置,质量,速度。这使得系统像
我和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
答案 0 :(得分:3)
我已经纠正了代码中的两个明显错误;它运行,但我不是 确定它是正确的。最后的代码。
第一个错误是odeint
想要处理状态和向量的向量
国家衍生物。通过向量我的意思是rank-1数组;你提交了
矩阵(rank-2数组)作为初始条件。我改变了
r
r = r1 + r2 + r3
+
x1
dotf
rf
列表上的运算符是串联,但它是在numpy数组上
元素添加。
此更改意味着我必须将作业更改为dotf
等
r
和rf
。我还将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