含指数多方程组求解: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
相关产品推荐
相关产品推荐

