简体   繁体   English

"带有 sympy 的变量的微分方程变化"

[英]Differential equation change of variables with sympy

I have an ordinary differential equation like this:我有一个像这样的常微分方程:

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

Use the following function: 使用以下功能:

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

For the example posted: 对于发布的示例:

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)

Under this substitution the differential equation outputted is then: 在这种替换下,输出的微分方程为:

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

If anyone is wondering how they could do it as well on CoCalc notebooks/anywhere where you can mix Sage and Python, here I defined basically the same variables and functions as OP did, and then after substitution the result is converted back to Sage:如果有人想知道如何在 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_())

Note that the only difference is that here things are converted to SymPy when using as arguments inside OP's function (it'll probably break if you don't!).请注意,唯一的区别是,当在 OP 的函数中用作参数时,这里的东西会转换为 SymPy(如果你不这样做,它可能会中断!)。 After you call _sympy_() only once on a variable of expression, every sympy object gets a _sage_() method to convert back .在表达式变量上只调用一次_sympy_()后, 每个 sympy 对象都会获得一个_sage_()方法来转换回.

The result given was:给出的结果是:

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

Which is just OP's result, but Sage handles operands a little bit differently.这只是 OP 的结果,但 Sage 处理操作数的方式略有不同。

Note: in order to avoid overriding stuff on Sage after importing everything from SymPy, you may want to import only diff as D , Function and solve from the main library.注意:为了避免在从 SymPy 导入所有内容后覆盖 Sage 上的内容,您可能只想import diff as DFunction并从主库中solve You might also want to rename sympy's solve to something else to avoid overriding Sage's own sage.symbolic.relation.solve .您可能还想将 sympy 的solve重命名为其他名称,以避免覆盖 Sage 自己的sage.symbolic.relation.solve

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM