odeint 中的“'float' 不可下标”

Posted

技术标签:

【中文标题】odeint 中的“\'float\' 不可下标”【英文标题】:"'float' is not subscriptable" in odeintodeint 中的“'float' 不可下标” 【发布时间】:2018-11-22 04:35:25 【问题描述】:

我正在尝试在 Python 中实现耦合微分方程,作为一个新用户,我似乎陷入了困境。我使用此 tutorial 作为解决我的 ODE 的指南,并查看了 documentation 以发现不可用

这是我定义函数的地方

def Burnout(t, y, m, nu, S0, V, delta, mu):
    S = y[0];

    E = [0 for i in range(0,m)]
    dEdt = [0 for i in range(0,m)]

    for i in range(0,m):
        E.append(y[i+1])

    P = y[m+1]

    dSdt = -nu*S*P*(S/S0)**V
    dEdt.append(nu*S*P*(S/S0)**V-m*delta*E[0])

    for i in range(1,m):
        dEdt.append(m*delta*E[i-1]-m*delta*E[i])

    dPdt = m*delta*E[m-1]-mu*P

    return [dSdt, *dEdt[0:m], dPdt]

然后,和教程一样,我定义初始条件

 S0 = N
 y0.append(S0)

 for i in range (0, m):
    E.append(0)
    y0.append(E[i])

 P0 = Z
 y0.append(P0)

其中 N 和 Z 是先前定义的东西,而 E 是一个空数组。当我最终调用 odeint(Burnout, y0, t, args = p) 时,我得到一个“float”对象不可下标,指向我在 Burnout 函数中对 S 的定义。当我将一个列表传递给 odeint 时,我对为什么 Python 说我传递了一个浮点数感到有点困惑。有谁看到我做错了什么?提前致谢!

编辑:好的,现在这是一个最小、完整且可验证的示例,它给了我同样的错误

将 numpy 导入为 np 从 scipy.integrate 导入 o​​deint

 def Burnout(t, y, m, nu, S0, V, delta, mu):

    S = y[0]

    E = [0 for i in range(0,m)]
    dEdt = [0 for i in range(0,m)]

    for i in range(0,m):
        E.append(y[i+1])

    P = y[m+1]

    dSdt = -nu*S*P*(S/S0)**V
    dEdt.append(nu*S*P*(S/S0)**V-m*delta*E[0])

    for i in range(1,m):
        dEdt.append(m*delta*E[i-1]-m*delta*E[i])

    dPdt = m*delta*E[m-1]-mu*P

    return [dSdt, *dEdt[0:m], dPdt]


V = 2.97
m = 26
delta = 1/6
mu = 1
nu = 10
S0 = 5

t = np.linspace(0,56,100)

y = [10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100]
p = (m, nu, V, S0, delta, mu)
print(odeint(Burnout,y,t,args=p))

【问题讨论】:

听起来像传递给Burnout 的内容,因为yfloat。我无法从发布的代码中看出为什么会这样。 但是我通过了 y0,正如你在我的第二个 Blockcode 中看到的那样,它被定义为一个数组。 我没有看到任何对Burnout 的呼叫。请提供minimal reproducible example。 你确定t 也是一个数组吗?它不是 dt 作为浮点数,它需要是 t 的所有值的数组。 out = odeint(Burnout, y0, t, args = p) 我在这里称呼它。我相信t 一定是一个数组,但我会检查我对它的定义以确定,谢谢! 【参考方案1】:

您在 ode 定义中的参数排序错误。在y 之前可以有t,但是你必须定义tfirst = True (see docs)。

Burnout 的定义中交换参数可以解决我的问题。

def Burnout(y, t, m, nu, S0, V, delta, mu):
   # ...
   # rest of function
   # ...

您也可以在odeint 调用中定义附加关键字tfirst

odeint(Burnout, y, t, args=p, tfirst=True)

【讨论】:

谢谢!我对此很愚蠢,但我很高兴你们都发现了我的错误。以后会更小心的

以上是关于odeint 中的“'float' 不可下标”的主要内容,如果未能解决你的问题,请参考以下文章

无法编译使用 boost 中的 odeint 的 C++

如何修复 scipy 的 odeint 函数中的 np.float64 不可调用错误? [关闭]

Rs deSolve 和 Pythons odeint 的区别

在python(odeint)中求解具有时间相关系数的常微分方程

路径关闭时如何让 SciPy.integrate.odeint 停止?

如何使用 scipy.integrate.odeint 求解具有时间相关变量的 ODE 系统