使用Sympy求解常微分方程所得解不满足给定初始条件问题
问题原因
- SymPy求解包含平方项的非线性常微分方程时,通解存在多分支(由开平方、反双曲函数的多值性导致),默认返回的分支未适配你设定的所有参数为正、v(t)为实值的约束,导致解的形式冗余复杂。
- dsolve的初始条件(ics参数)处理逻辑对非线性带参数方程的适配不完善,积分常数消去后未自动做针对性化简,导致残留未合并的表达式,代入t=0时无法得到预期的v(0)=0结果。
解决方法
方法1:手动化简得到符合物理场景的简洁解
该方程为阻尼落体速度方程,标准解析解为双曲正切形式,你可以在求解后手动转换并验证:
import sympy as sp v = sp.Function('v', real=True) t, g, m, c = sp.symbols('t g m c', positive=True, real=True) eq = sp.Eq(v(t).diff(t), g - c/m*v(t)**2) sol = sp.dsolve(eq, v(t), ics={v(0):0}) # 手动改写为符合参数约束的简洁实值解 standard_sol = sp.Eq(v(t), sp.sqrt(g*m/c)*sp.tanh(sp.sqrt(g*c/m)*t)) # 验证初始条件 print(standard_sol.subs(t, 0)) # 验证解是否满足原方程 print(sp.checkodesol(eq, standard_sol))
运行后会输出Eq(v(0), 0)和(True, 0),说明解符合要求。
方法2:给dsolve指定参数强制化简、指定求解器
在调用dsolve时开启simplify开关,指定使用分离变量法求解,减少冗余分支:
sol = sp.dsolve(eq, v(t), ics={v(0):0}, hint='separable', simplify=True) sol = sol.simplify()
得到的解经过化简后就会和标准解析解一致。
内容的提问来源于stack exchange,提问作者Vahid
相关产品推荐
相关产品推荐

