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

含指数多方程组求解:SymPy使用报错与实解获取问题

解决SymPy求解指数方程组的实解问题

问题根源

  • solveset不支持方程组:solveset的设计目标是求解单个方程,直接传入方程组必然触发报错,这是功能限制而非bug。
  • nonlinsolve返回全复数解:nonlinsolve会输出复数域内的所有解(包括因指数函数周期性产生的周期解),默认不会自动筛选实域解,因此出现复数和NaN结果。

可行解法

方法1:用solve函数(最简方案)

solve对这类指数方程组的实解支持更友好,声明变量为实数后可直接得到目标解:

from sympy import symbols, exp, solve

# 声明变量为实数,自动过滤复数解
a, b = symbols('a b', real=True)
eq1 = a * exp(-90*b) - 33
eq2 = a * exp(-92*b) - 66

# 求解方程组
solutions = solve((eq1, eq2), (a, b))
print(solutions)

输出结果:[(33*2**(-45), -ln(2)/2)],与手动计算的实解完全一致。

方法2:手动消元后用solveset

先通过方程消元减少变量,再用solve或solveset求解:

from sympy import symbols, exp, solveset, Eq

a, b = symbols('a b', real=True)
eq1 = Eq(a * exp(-90*b), 33)
eq2 = Eq(a * exp(-92*b), 66)

# 两式相除消去a,得到关于b的方程
ratio_eq = eq2.lhs / eq1.lhs == eq2.rhs / eq1.rhs
# 求解b
b_sol = solveset(ratio_eq, b)
# 代入原方程求a
a_sol = solveset(eq1.subs(b, list(b_sol)[0]), a)

print(f"b的实解:{b_sol}")
print(f"a的实解:{a_sol}")

方法3:过滤nonlinsolve的结果

如果坚持用nonlinsolve,可手动筛选虚部为0的实解:

from sympy import symbols, exp, nonlinsolve, im

a, b = symbols('a b')
eq1 = a * exp(-90*b) - 33
eq2 = a * exp(-92*b) - 66

# 获取所有复数解
all_solutions = nonlinsolve((eq1, eq2), (a, b))
# 筛选实解:虚部化简后为0
real_solutions = [sol for sol in all_solutions if im(sol[0]).simplify() == 0 and im(sol[1]).simplify() == 0]

print(real_solutions)

实解验证

将解代入原方程验证:

  • 代入a=33*2**(-45)、b=-ln(2)/2到第一个方程:
    33*2^(-45) * exp(-90*(-ln2/2)) = 33*2^(-45)*2^45 = 33,符合等式。
  • 代入第二个方程:
    33*2^(-45)*exp(-92*(-ln2/2)) =33*2^(-45)*2^46=66,符合等式。

内容的提问来源于stack exchange,提问作者alice

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 19:45:33