带单位非线性方程组求解报错:Sympy与Pint兼容问题排查
问题分析
我正在开发一个求解泵工作点的工具,通过联立泵曲线和系统曲线方程,求解扬程(H)和流量(Q)两个未知量。代码分为导入与符号定义、泵曲线拟合、类定义与调用三部分。但当使用带单位(foot、foot²)的变量构建非线性方程组时,Sympy抛出NotImplementedError,提示无法识别<Quantity, Quantity>的_eval_is_eq签名;改用无单位变量时代码可正常运行。
解决方案
1. 分离单位与变量
避免直接给Sympy符号附加单位,将单位作为独立的转换因子或系数处理:
- 先定义无单位的符号变量
Q、H - 构建方程组时,先将带单位的系数转换为统一单位下的数值,求解后再给结果附加单位
示例代码片段:
from sympy import symbols, Eq, solve from pint import UnitRegistry ureg = UnitRegistry() # 定义无单位符号 Q_sym, H_sym = symbols('Q H') # 泵曲线方程:H = a*Q² + b*Q + c,先转换系数单位 a = (0.01 / ureg.foot**2).to_base_units().magnitude b = (0.5 / ureg.foot).to_base_units().magnitude c = (100 * ureg.foot).to_base_units().magnitude pump_eq = Eq(H_sym, a * Q_sym**2 + b * Q_sym + c) # 系统曲线方程:H = d*Q² + e,同样转换系数单位 d = (0.005 / ureg.foot**2).to_base_units().magnitude e = (20 * ureg.foot).to_base_units().magnitude system_eq = Eq(H_sym, d * Q_sym**2 + e) # 求解无单位结果后附加单位 solution = solve((pump_eq, system_eq), (Q_sym, H_sym)) Q_result = solution[Q_sym] * ureg.foot H_result = solution[H_sym] * ureg.foot
2. 自定义单位兼容的等式逻辑
如果需要保留符号带单位,可手动实现单位统一后的等式判断:
from sympy import Eq from pint import Quantity def eq_with_units(lhs, rhs): # 先统一到基准单位,再比较数值 lhs_std = lhs.to_base_units() rhs_std = rhs.to_base_units() return Eq(lhs_std.magnitude, rhs_std.magnitude) # 用自定义等式构建方程组 pump_eq = eq_with_units(H, a*Q**2 + b*Q + c) system_eq = eq_with_units(H, d*Q**2 + e) solution = solve((pump_eq, system_eq), (Q, H))
3. 升级Sympy版本
部分旧版本Sympy对Quantity类型的等式支持不完善,尝试升级到最新稳定版:
pip install --upgrade sympy
关键原因
Sympy原生符号系统未内置对带单位Quantity类型的等式判断逻辑,当等式两边为<Quantity, Quantity>类型时,Sympy无法识别对应的_eval_is_eq方法,因此抛出NotImplementedError。无单位符号属于Sympy原生支持的类型,所以能正常求解。
内容的提问来源于stack exchange,提问作者nate
相关产品推荐
相关产品推荐

