簡體   English   中英

"帶有 sympy 的變量的微分方程變化"

[英]Differential equation change of variables with sympy

我有一個像這樣的常微分方程:

DiffEq = Eq(-ℏ*ℏ*diff(Ψ,x,2)/(2*m) + m*w*w*(x*x)*Ψ/2 - E*Ψ   ,  0)

使用以下功能:

def variable_change(ODE,dependent_var, 
                    independent_var,
                    new_dependent_var = None, 
                    new_independent_var= None, 


                    dependent_var_relation = None,
                    independent_var_relation = None,
                    order = 2):





    if new_dependent_var == None:
        new_dependent_var = dependent_var
    if new_independent_var == None:
        new_independent_var = independent_var




    # dependent variable change

    if new_independent_var != independent_var:

        for i in range(order, -1, -1):

            # remplace derivate
            a = D(dependent_var , independent_var, i )
            ξ = Function("ξ")(independent_var)

            b = D( dependent_var.subs(independent_var, ξ),  independent_var  ,i)

            rel = solve(independent_var_relation, new_independent_var)[0]


            for j in range(order, 0, -1):
                b = b.subs( D(ξ,independent_var,j), D(rel,independent_var,j))

            b = b.subs(ξ, new_independent_var)

            rel = solve(independent_var_relation, independent_var)[0]
            b = b.subs(independent_var, rel)


            ODE =   ODE.subs(a,b)

        ODE = ODE.subs(independent_var, rel)


    # change of variables of indpendent variable


    if new_dependent_var != dependent_var:

        ODE = (ODE.subs(dependent_var.subs(independent_var,new_independent_var) , (solve(dependent_var_relation, dependent_var)[0])))
        ODE = ODE.doit().expand()

    return ODE.simplify()

對於發布的示例:

from sympy import *
from sympy import diff as D

E, ℏ ,w,m,x,u = symbols("E, ℏ , w,m,x,u")
Ψ ,H = map(Function, ["Ψ ","H"])
Ψ ,H = Ψ(x), H(u)



DiffEq = Eq(-ℏ*ℏ*D(Ψ,x,2)/(2*m) + m*w*w*(x*x)*Ψ/2 - E*Ψ,0)
display(DiffEq)



display(Eq(u , x*sqrt(m*w/ℏ)))
display(Eq(Ψ, H*exp(-u*u/2)))


newODE = variable_change(ODE = DiffEq,


                independent_var = x, 
                new_independent_var= u,
                independent_var_relation = Eq(u , x*sqrt(m*w/ℏ)),
                dependent_var = Ψ,  


                new_dependent_var = H,   
                dependent_var_relation = Eq(Ψ, H*exp(-u*u/2)),

                order = 2)







display(newODE)

在這種替換下,輸出的微分方程為:

Eq((-E*H + u*w*ℏ*D(H, u) + w*ℏ*H/2 - w*ℏ*D(H, (u, 2))/2)*exp(-u**2/2), 0)

如果有人想知道如何在 CoCalc 筆記本/任何可以混合 Sage 和 Python 的地方也能做到這一點,我在這里定義了與 OP 所做的基本相同的變量和函數,然后在替換后將結果轉換回 Sage:

var("E w m x u")
var("h_bar", latex_name = r'\hbar')
Ψ = function("Ψ")(x)
H = function('H')(u)

display(h_bar*diff(Ψ, x, 2))
DiffEq = (-h_bar*h_bar*Ψ.diff(x, 2)/(2*m) + m*w*w*(x*x)*Ψ/2 - E*Ψ == 0)
display(DiffEq)

display(u == x*sqrt(m*w/h_bar))
display(Ψ == H*exp(-u*u/2))


newODE = variable_change(
    ODE = DiffEq._sympy_(),
    independent_var = x._sympy_(),
    new_independent_var = u._sympy_(),
    independent_var_relation = (u == x*sqrt(m*w/h_bar))._sympy_(),
    dependent_var = Ψ._sympy_(),
    new_dependent_var = H._sympy_(),
    dependent_var_relation = (Ψ == H*exp(-u*u/2))._sympy_(),
    order = 2
)

display(newODE._sage_())

請注意,唯一的區別是,當在 OP 的函數中用作參數時,這里的東西會轉換為 SymPy(如果你不這樣做,它可能會中斷!)。 在表達式變量上只調用一次_sympy_()后, 每個 sympy 對象都會獲得一個_sage_()方法來轉換回.

給出的結果是:

1/2*(2*h_bar*u*w*diff(H(u), u) + h_bar*w*H(u) - h_bar*w*diff(H(u), u, u) - 2*E*H(u))*e^(-1/2*u^2) == 0

這只是 OP 的結果,但 Sage 處理操作數的方式略有不同。

注意:為了避免在從 SymPy 導入所有內容后覆蓋 Sage 上的內容,您可能只想import diff as DFunction並從主庫中solve 您可能還想將 sympy 的solve重命名為其他名稱,以避免覆蓋 Sage 自己的sage.symbolic.relation.solve

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM