变量的微分方程变化与sympy

Differential equation change of variables with sympy

我有这样一个常微分方程:

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

我想执行变量更改:

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

我如何使用 sympy 执行此操作?

使用以下函数:

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 notebooks/anywhere 上做到这一点,您可以在其中混合 Sage 和 Python,这里我定义的变量和函数与 OP 在他的 accepted 上所做的基本相同回答,然后在替换后结果转换回 Sage:

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

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))

# Function is purely sympy
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_() 后,every sympy object gets a _sage_() method to convert back.

给出的结果是:

# Sage object again
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 DFunctionsolve主图书馆。您可能还想将 sympy 的 solve 重命名为其他名称,以避免覆盖 Sage 自己的 sage.symbolic.relation.solve.