如何提取SymPy求解ODE得到的通解分量并绘图?
访问SymPy常微分方程通解的各个分量
问题场景
使用SymPy求解常微分方程后,得到形如C1*exp(-z*sqrt(-e)) + C2*exp(z*sqrt(-e))或C1*airyai(-e + z) + C2*airybi(-e + z)的通解,希望直接访问通解中的各个基函数分量(如exp(-z*sqrt(-e))、airyai(-e + z)),而非手动复制结果,以便后续绘图等操作。
用户的求解代码:
import sympy as sym import numpy as np z = sym.Symbol('z') e = sym.Symbol('e') f = sym.Function('f') edo = sym.diff(f(z), z , 2) + e * f(z) soln = sym.dsolve(edo, f(z)) print(soln.rhs)
运行输出:
C1*exp(-z*sqrt(-e)) + C2*exp(z*sqrt(-e))
解决方案
SymPy返回的通解右侧(soln.rhs)是Add类型的表达式,可通过以下方法拆分提取各个分量:
拆分线性组合项
通解的每一项(如C1*exp(...))可通过soln.rhs.args直接获取,该属性返回所有相加项的元组:# 获取所有项 terms = soln.rhs.args # 输出:(C1*exp(-z*sqrt(-e)), C2*exp(z*sqrt(-e)))提取基函数(去除系数C1/C2)
对每个项使用as_coeff_mul()方法,分离系数和对应的基函数:# 处理第一项 coeff1, func1 = terms[0].as_coeff_mul() base_func1 = func1[0] # 得到exp(-z*sqrt(-e)) # 处理第二项 coeff2, func2 = terms[1].as_coeff_mul() base_func2 = func2[0] # 得到exp(z*sqrt(-e))Airy函数通解的处理示例
若通解为C1*airyai(-e + z) + C2*airybi(-e + z),方法完全通用:terms = soln.rhs.args _, airyai_term = terms[0].as_coeff_mul() _, airybi_term = terms[1].as_coeff_mul() # airyai_term[0] 对应 airyai(-e + z) # airybi_term[0] 对应 airybi(-e + z)绘图实现示例
将基函数转换为数值可计算函数,结合Matplotlib绘图:import matplotlib.pyplot as plt # 代入e的具体值,比如e=1 func1_eval = base_func1.subs(e, 1) # 转换为numpy可调用函数 num_func1 = sym.lambdify(z, func1_eval, 'numpy') # 生成z的数值点 z_vals = np.linspace(-5, 5, 100) y_vals = num_func1(z_vals) # 绘图 plt.plot(z_vals, y_vals, label=str(base_func1)) plt.legend() plt.show()
说明
该方法适用于SymPy返回的线性齐次ODE通解(多个带系数的基函数相加的形式);若通解包含非齐次特解+齐次通解的复杂结构,可先判断soln.rhs的类型再针对性拆分。
内容的提问来源于stack exchange,提问作者HMPtwo
相关产品推荐
相关产品推荐

