2016-08-07 71 views
1

我試圖自動化幾個進程,比如使用Sympy從拉格朗日生成ODE並使用Numpy和Scipy對它們進行數值整合。 最後的完整代碼。solve()產生的常微分方程的結果我得到一個字典,Sympy表達式如下所示:odeint()中的Sympy表達式給出了派生錯誤

{Derivative(lambda1(t), t): (y(t) + 1)/(x(t)*y(t)), 
Derivative(z(t), t): x(t), 
Derivative(x(t), t): y(t)*z(t), 
Derivative(y(t), t): -x(t)*z(t) 
} 
從這個我想微分方程系統 odeint()從SciPy的整合

然後。爲此,我需要從def Field(Q,t):內的字典中提取表達式(例如lambdify),以引入odeint(Field,Q_0,t_array)。這裏就是我困難運行:

我第一次嘗試

def Equ2(nQ,t,Q,Field): 
x1,y1,z1,lamb1 = nQ 
dQ =[] 
for f in Q: 
    dQ.append(lambdify(Q, Field[f.diff(t)],'numpy')(x1,y1,z1,lamb1)) 
return dQ[0:len(nQ)] 

但因爲它需要的字段2點的參數也不能去odeint(),我試圖將它傳遞的可選arga=()odeint(),給我(長)錯誤:

ValueError     Traceback (most recent call last) 
<ipython-input-20-63f086b8a252> in Equ2(nQ, t, Q, Field) 
     20  dQ =[] 
     21  for f in Q: 
---> 22   dQ.append(lambdify(Q, Field[f.diff(t)],'numpy')(x1,y1,z1,lamb1)) 
     23  return dQ[0:len(Q)-1] 

[...] 
ValueError: 
Can't calculate 1st derivative wrt 14.0430379424125. 

所以,我想基本上是相同的,但沒有循環,

def Equ1(nQ,t): 
x1,y1,z1,lamb1 = nQ 
dx = lambdify((x,y,z,lam[0]), field[x.diff(t)],'numpy')(x1,y1,z1,lamb1) 
dy = lambdify((x,y,z,lam[0]), field[y.diff(t)],'numpy')(x1,y1,z1,lamb1) 
dz = lambdify((x,y,z,lam[0]), field[z.diff(t)],'numpy')(x1,y1,z1,lamb1) 
dlam = lambdify((x,y,z,lam[0]), field[lam[0].diff(t)],'numpy')(x1,y1,z1,lamb1) 
return [dx,dy,dz] 

,並有(我認爲)同樣的問題:

ValueError        Traceback (most recent call last) 
<ipython-input-20-63f086b8a252> in Equ1(nQ, t) 
     9 def Equ1(nQ,t): 
    10  x1,y1,z1,lamb1 = nQ 
---> 11  dx = lambdify((x,y,z,lam[0]), field[x.diff(t)],'numpy')(x1,y1,z1,lamb1) 
    12  dy = lambdify((x,y,z,lam[0]), field[y.diff(t)],'numpy')(x1,y1,z1,lamb1) 
    13  dz = lambdify((x,y,z,lam[0]), field[z.diff(t)],'numpy')(x1,y1,z1,lamb1) 

[...] 
ValueError: 
Can't calculate 1st derivative wrt 17.6326726993661. 

如果我試圖簡單地說:

def Equ0(nQ,t): 
x,y,z,lamb = nQ 
dx = y*z 
dy = -x*z 
dz = x 
dlam = (y+1.)/(x*y) 
return [dx,dy,dz] 

整合工作得很好。另外,如果我用類似的參數調用EquX()函數,它將在odeint()之內使用,它們工作得很好。

全碼

from sympy import * 
from sympy.physics.mechanics import dynamicsymbols 
from numpy import linspace, sin, cos 
from scipy.integrate import odeint 

t = Symbol('t') 
x = Function('x')(t) 
y = Function('y')(t) 
z = Function('z')(t) 

lam = dynamicsymbols('lambda1:{0}'.format(5)) 
f = x.diff(t)- y*z 
eq = Matrix([x.diff(t) - lam[0].diff(t)*y*x*z+z, 
     y.diff(t) +x*z, 
     z.diff(t)-x 
     ]) 

field = solve(list(eq)+[f],[x.diff(t),y.diff(t),z.diff(t),lam[0].diff(t)]) 


def Equ0(nQ,t): 
    x,y,z,lamb = nQ 
    dx = y*z 
    dy = -x*z 
    dz = x 
    dlam = (y+1.)/(x*y) 
    return [dx,dy,dz] 

def Equ1(nQ,t): 
    x1,y1,z1,lamb1 = nQ 
    dx = lambdify((x,y,z,lam[0]), field[x.diff(t)],'numpy')(x1,y1,z1,lamb1) 
    dy = lambdify((x,y,z,lam[0]), field[y.diff(t)],'numpy')(x1,y1,z1,lamb1) 
    dz = lambdify((x,y,z,lam[0]), field[z.diff(t)],'numpy')(x1,y1,z1,lamb1) 
    dlam = lambdify((x,y,z,lam[0]), field[lam[0].diff(t)],'numpy')(x1,y1,z1,lamb1) 
    return [dx,dy,dz] 


def Equ2(nQ,t,Q,Field): 
    x1,y1,z1,lamb1 = nQ 
    dQ =[] 
    for f in Q: 
     dQ.append(lambdify(Q, Field[f.diff(t)],'numpy')(x1,y1,z1,lamb1)) 
    return dQ[0:len(Q)-1] 

q = [x,y,z,lam[0]] 
nq = [1,2,3,4] 
time=linspace(0,10,10) 

### This line works just fine: 
print Equ0(nq,t), Equ1(nq,t), Equ2(nq,t,q,field) #They give the same output 

sol0 = odeint(Equ0,nq,time) 
sol1 = odeint(Equ1,nq,time) #Errors here 
sol2 = odeint(Equ2,nq,time,args=(q,field)) #And here 

最後完整的錯誤:

--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-20-63f086b8a252> in Equ1(nQ, t) 
    9 def Equ1(nQ,t): 
10  x1,y1,z1,lamb1 = nQ 
---> 11  dx = lambdify((x,y,z,lam[0]), field[x.diff(t)],'numpy')(x1,y1,z1,lamb1) 
12  dy = lambdify((x,y,z,lam[0]), field[y.diff(t)],'numpy')(x1,y1,z1,lamb1) 
13  dz = lambdify((x,y,z,lam[0]), field[z.diff(t)],'numpy')(x1,y1,z1,lamb1) 

/usr/local/lib/python2.7/dist-packages/sympy/core/expr.pyc in diff(self, *symbols, **assumptions) 
2864   new_symbols = list(map(sympify, symbols)) # e.g. x, 2, y, z--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-20-63f086b8a252> in Equ1(nQ, t) 
    9 def Equ1(nQ,t): 
10  x1,y1,z1,lamb1 = nQ 
---> 11  dx = lambdify((x,y,z,lam[0]), field[x.diff(t)],'numpy')(x1,y1,z1,lamb1) 
12  dy = lambdify((x,y,z,lam[0]), field[y.diff(t)],'numpy')(x1,y1,z1,lamb1) 
13  dz = lambdify((x,y,z,lam[0]), field[z.diff(t)],'numpy')(x1,y1,z1,lamb1) 

    /usr/local/lib/python2.7/dist-packages/sympy/core/expr.pyc in diff(self, *symbols, **assumptions) 
    2864   new_symbols = list(map(sympify, symbols)) # e.g. x, 2, y, z 
2865   assumptions.setdefault("evaluate", True) 
---> 2866   return Derivative(self, *new_symbols, **assumptions) 
2867 
2868  ########################################################################### 

/usr/local/lib/python2.7/dist-packages/sympy/core/function.pyc in __new__(cls, expr, *variables, **assumptions) 
1068     ordinal = 'st' if last_digit == 1 else 'nd' if last_digit == 2 else 'rd' if last_digit == 3 else 'th' 
1069     raise ValueError(filldedent(''' 
---> 1070     Can\'t calculate %s%s derivative wrt %s.''' % (count, ordinal, v))) 
1071 
1072    if all_zero and not count == 0: 

ValueError: 
Can't calculate 1st derivative wrt 0.0. 

2865   assumptions.setdefault("evaluate", True) 
---> 2866   return Derivative(self, *new_symbols, **assumptions) 
2867 
2868  ########################################################################### 

/usr/local/lib/python2.7/dist-packages/sympy/core/function.pyc in __new__(cls, expr, *variables, **assumptions) 
1068     ordinal = 'st' if last_digit == 1 else 'nd' if last_digit == 2 else 'rd' if last_digit == 3 else 'th' 
1069     raise ValueError(filldedent(''' 
---> 1070     Can\'t calculate %s%s derivative wrt %s.''' % (count, ordinal, v))) 
1071 
1072    if all_zero and not count == 0: 

ValueError: 
Can't calculate 1st derivative wrt 0.0. 

TL; DR出現內部odeint(),我不能重現外odeint一些推導錯誤()自定義製作功能。

回答

3

如果你想使用t作爲符號,你應該避免在函數聲明中聲明t作爲浮點數。嘗試用另一個名稱替換浮點數tstt或...