生成和求解同步ODE';Python中的s

生成和求解同步ODE';Python中的s,python,scipy,sympy,Python,Scipy,Sympy,我对Python比较陌生,在编写生成并求解微分方程组的代码时遇到了一些问题 我的方法是创建一组变量和系数,(x0,x1,…,xn)和(c0,c1,…,cn),在一个带有函数var()的列表中分别创建。然后在EOM1()中构造方程。初始条件以及方程组都放在EOM2()中,并使用odeint进行求解 目前,下面的代码正在运行,尽管效率不高,我认为这是因为odeint在每次交互中都会运行所有代码(这是我需要解决的其他问题,但不是主要问题!) 我的问题是,我很难让Python恰当地处理Symphy生成的

我对Python比较陌生,在编写生成并求解微分方程组的代码时遇到了一些问题

我的方法是创建一组变量和系数,(x0,x1,…,xn)和(c0,c1,…,cn),在一个带有函数var()的列表中分别创建。然后在EOM1()中构造方程。初始条件以及方程组都放在EOM2()中,并使用
odeint
进行求解

目前,下面的代码正在运行,尽管效率不高,我认为这是因为
odeint
在每次交互中都会运行所有代码(这是我需要解决的其他问题,但不是主要问题!)

我的问题是,我很难让Python恰当地处理Symphy生成的变量。我用绳子绕过去了

output.append(part.evalf(subs={'x0':x0, 'x1':x1, 'c0':c0, 'c1':c1}))
EOM2()中。不幸的是,我不知道如何将这一行推广到从x0到xn,从c0到cn的变量列表。这同样适用于EOM2()中的前一行

    x0, x1 = xn
    c0, c1 = cn
换句话说,我将n设置为一个任意数字,Python有没有办法像我在上面手动输入的元素那样解释每个元素?我试过以下方法

output.append(part.evalf(subs={'x{0}'.format(j):var(n)[0][j], 'c{0}'.format(j):var(n)[1][j]}))
然而,这产生了一个错误,导致我首先使用evalf

TypeError: can't convert expression to float

有没有什么方法可以做我想做的,生成一组n个方程,然后用
odeint
求解?

如果我理解正确,你想在一个symphy表达式中进行任意数量的替换。这是如何做到的:

n = 10
syms = sy.symbols('x0:{}'.format(n))   # an array of n symbols
expr = sum(syms)                       # some expression with those symbols
floats = [1/(j+1) for j in range(n)]   # numbers to put in 
expr.subs({symbol: value for symbol, value in zip(syms, floats)})
在这种情况下,SUB的结果是浮动(不需要evalf)


请注意,
symbols
函数可以通过冒号符号直接为您创建任意数量的符号。不需要循环

而不是使用
evalf
您希望研究使用
sympy.lambdify
来生成一个用于SciPy的回调。您需要创建一个预期签名为
odeint
的函数,例如:

y, params = sym.symbols('y:3'), sym.symbols('kf kb')
ydot = rhs(y, p=params)
f = sym.lambdify((y, t) + params, ydot)
yout = odeint(f, y0, tout, param_values)
在2017年SciPy大会上,我们提供了一个关于如何使用
lambdify
odeint
的教程,材料可在以下位置获得:


如果您愿意使用外部库来处理外部解算器的函数签名,您可能会对我编写的库感兴趣:

为什么首先要使用符号?谢谢,太好了!但是,我仍然发现odeint存在一些问题。在你提供的情况下,我们有一系列的数字可以替代。然而,在我的例子中,我不能这样做,因为我想把这些方程放到odeint函数中,然后将值替换到我的方程中。这意味着我在生成一组与odeint兼容的方程时仍然存在问题。尽管如此,我还是非常感谢你提供的有用信息:)我想我不可能要求一个更彻底、更充实的答案。非常感谢。
y, params = sym.symbols('y:3'), sym.symbols('kf kb')
ydot = rhs(y, p=params)
f = sym.lambdify((y, t) + params, ydot)
yout = odeint(f, y0, tout, param_values)