You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 22:12:39