Python求解三阶时变系数ODE出现can't convert expression to float错误求助
问题根源
你出现这个报错的核心原因是混用了SymPy的符号运算逻辑和Scipy的数值求解逻辑:
- 你用SymPy定义的
A1/A2/A3都是符号表达式,不是可以直接参与数值计算的函数/数值 - 微分方程函数
du_dt需要返回纯数值结果给odeint,你直接返回了带符号变量的表达式,自然无法转成float
解决思路
你需要先把所有带导数的符号表达式提前推导完成,再转成可接收数值时间t的数值函数,再传入odeint中使用,具体步骤如下:
- 先导入缺失的numpy依赖
- 定义独立的符号时间变量,完成所有系数的符号推导
- 用SymPy的
lambdify方法把所有需要的系数转成数值函数 - 在微分方程函数中,每次传入当前时间点,计算得到该时刻的系数数值,再返回导数结果
修正后的完整代码
import numpy as np import matplotlib.pyplot as plt from scipy.integrate import odeint from sympy import symbols, atan, diff, lambdify # 第一步:定义符号变量,完成所有系数的符号推导 t_sym = symbols('t_sym') V = 2.5e3 Ra = 7.5e3 C1 = 3.3e-6 RL = 1.10 L = 3.32e-6 C2 = 3.16e-12 Rd = 0.5 w1 = 1/(C1*L) T1 = Ra*C1 C23 = C1*C2/(C1+C2) w2 = 1/(L*C23) # 用符号变量定义R5 R5 = 0.015 - 0.006*atan(t_sym - 5) Tm = L/(RL + R5) A1_sym = 1/Tm + 1/T1 A2_sym = diff(1/Tm, t_sym) + w2 + (1/L)*diff(R5, t_sym) + 1/(T1*Tm) A3_sym = (1/L)*diff(R5, t_sym, 2) + (1/(L*T1))*diff(R5, t_sym) + (w2 - w1)/T1 # 第二步:把符号表达式转成可接收数值t的函数 A1_func = lambdify(t_sym, A1_sym, 'numpy') A2_func = lambdify(t_sym, A2_sym, 'numpy') A3_func = lambdify(t_sym, A3_sym, 'numpy') # 第三步:定义微分方程函数,全部用数值计算 def du_dt(y, t): A1_val = A1_func(t) A2_val = A2_func(t) A3_val = A3_func(t) return [ y[1], y[2], (- A1_val*y[2] - A2_val*y[1] - A3_val*y[0]) ] # 求解 t = np.linspace(0, 0.2, 1000) # 时间范围 y0 = [3.0425e10, 0, 0] # 初始值 y = odeint(du_dt, y0, t) # 可选:绘图查看结果 plt.plot(t, y[:, 0]) plt.xlabel('t') plt.ylabel('y') plt.show()
额外注意点
你原来的微分方程表达式里符号写错了:原方程是y''' + A1 y'' + A2 y' + A3 y =0,移项后y''' = -A1 y'' -A2 y' -A3 y,你原来代码里写的是+A3*y[0],会导致方程逻辑错误,上面的修正代码已经改了这个问题。
内容的提问来源于stack exchange,提问作者shoxeal
相关产品推荐
相关产品推荐

