scipy的'ode`求解器与' vode'方法给出一个空数组结果

时间:2015-07-17 20:38:21

标签: python matlab numpy scipy ode

我正在尝试整合等式

bg' = dmat*bg + releasevec.

Dmat是一个6x6数组值,bg是一个6x1向量。要将dmatbg相乘,我使用点积。然后releasevec被添加到此产品中。

我想在零到三的时间跨度上整合这个等式。现在,下面的代码产生的f_results是一个空数组,即没有结果。

有一点背景是这个代码是从MATLAB ode求解器(ode15s专门)改编而来的。 ode15s的明显Python等价物是scipy&#39>

ode.set_integrator('vode', method = 'bdf')

从时间段0到1,bg中产生的f_results结果应为

[5.76068434946487e-16, 1.92039036486442e-14, 2.97732034735096e-21,
 1.15568146353068e-18, 3.50848451366317e-19, 6.99348172634721e-27] 

如您所见,这些bg结果与代码中提供的初始bgbg0)值几乎没有区别。我知道MATLAB的ode15s求解器使用内部时间步长来执行积分,因此我认为可能需要在积分器中弄乱步骤参数。

问题:为什么我的结果是空数组?我是否错误地设置了初始条件?如何生成我发布的下一组bg值?

如果我遗漏了任何相关信息或任何内容,请告诉我,我会尽快解决。

def ode_solv(t, bg, dmat, releasevec):
    ydot[0] = dmat2[0].dot(bg) + releasevec[0]
    ydot[1] = dmat2[1].dot(bg) + releasevec[1]
    ydot[2] = dmat2[2].dot(bg) + releasevec[2]
    ydot[3] = dmat2[3].dot(bg) + releasevec[3]
    ydot[4] = dmat2[4].dot(bg) + releasevec[4]
    ydot[5] = dmat2[5].dot(bg) + releasevec[5]
    return ydot

ydot = np.zeros(6)

dmat2 = np.array([[-1960368.83845003, 58694.00323479, 39129.33548986, 1862545.49972536, 0.0, 0.0],
              [58694.00323479, -1.89355617e+09, 0.0, 1231.23020241, 21038.6060172, 14025.7373448],
              [39129.33548986, 0.68216154, -7.57402415e+09, 0.0, 0.0, 0.0],
              [1862545.49972536, 0.0, 0.0, -9.28416441e+08, 0.0, 0.0],
              [0.0, 21038.64595532, 0.0, 0.0, -1.15156310e+09, 0.0],
              [0.0, 0.0, 14025.76397021, 0.0, 0.0, -5.97115916e+09]], np.float)
bg0 = [5.74717437413422e-16, 1.91588665922461e-14, 2.97070077781448e-21,
   1.15297115567223e-18, 3.50025640453469e-19, 6.97793289948656e-27]

releasevec = [0.0, 0.0000363636, 0.0, 0.0, 0.0, 0.0]

t0 = 0.0
t1 = 3

f_results = []

soln = ode(ode_solv).set_integrator('vode', method='bdf', order=5)
soln.set_initial_value(t0, bg0)
soln.set_f_params(dmat2, releasevec)
while soln.t < t1:
    soln.integrate(soln.bg)
    f_results.append([soln.t, soln.bg])
print f_results

2 个答案:

答案 0 :(得分:2)

这一行不正确:

soln.set_initial_value(t0, bg0)

你有相反的论点。第一个参数必须是初始;第二个(可选)参数是给出该值的时间。

还有其他一些问题:

  • soln.bg更改为soln.y
  • soln.integrate(soln.bg)行不正确。参数应该是下一个期望的t值。

({另请)查看the ode docstring中的示例。

答案 1 :(得分:2)

除了Warren刚刚指出的内容之外,您还可以通过向量化来大规模简化和加速ode_solv函数:

def ode_solv(t, bg, dmat, releasevec):
    return dmat2.dot(bg) + releasevec

您也无需直接访问soln.y属性 - 调用integrate的结果是该时间步的bg的新值,即:

bg = soln.integrate(t)
results.append(bg)