[英]Solving system of nonlinear (and nonpolynomial) equations
我想使用 python/sympy 来解决来自电子阻抗计算的简单方程组。
在此类计算中,由于“并联阻抗”公式,人们通常不得不处理以下形式的表达式:
par(x,y) := (x*y)/(x+y)
现在我尝试使用以下代码:
from sympy import *
def par(var1,var2):
return (var1 * var2)/(var1+var2)
A = Symbol('A')
B = Symbol('B')
C = Symbol('C')
D = Symbol('D')
E = Symbol('E')
eq1 = A + par(B+50 , (C+ par(D, (E+50)) )) - 50
eq2 = B + par(A+50 , (C+ par(D , (E+50)) )) - 50
eq3 = E + par(D+50, (C+ par(A+50, B+50)) ) - 50
因此在五个变量{A,B,C,D,E}
中定义了三个方程组,然后运行
solve([eq1,eq2,eq3], A, B,C,D,E)
计算只是不会终止。
你对我如何处理这些类型的方程式有什么建议吗? 基本上是除以多项式的多项式,具有复数的解。
您也可以尝试Z3 库:
from z3 import Reals, Solver, sat, set_option
def par(var1, var2):
return (var1 * var2) / (var1 + var2)
vars = Reals('A B C D E')
A, B, C, D, E = vars
set_option(rational_to_decimal=True, precision=30)
s = Solver()
s.add(A + par(B + 50, (C + par(D, (E + 50)))) == 50)
s.add(B + par(A + 50, (C + par(D, (E + 50)))) == 50)
s.add(E + par(D + 50, (C + par(A + 50, B + 50))) == 50)
if s.check() == sat:
m = s.model()
print(m)
我得到以下输出:
[D = 0.502507819412956050111927878839?,
C = 0.125,
E = 50.188198722936229689352204927638?,
B = -50.625,
A = -50.625]
D 和 E 值末尾的问号表示它们已被近似。
如果您随后尝试将 A、B 和 C 的值放入原始代码中,sympy 会给出两个精确的表达式:
[{A: -405/8,
B: -405/8,
C: 1/8,
D: -31857/1292 + 5*sqrt(676050154)/5168,
E: 443/1304 + 5*sqrt(676050154)/2608},
{A: -405/8,
B: -405/8,
C: 1/8,
D: -5*sqrt(676050154)/5168 - 31857/1292,
E: 443/1304 - 5*sqrt(676050154)/2608}]
采纳 Oscar 的建议并专注于 A、B 和 C,您可以根据 D 和 E 为它们找到解决方案:
>>> solve((eq1, eq2, eq3), A, B, C)[0] # one solution
(
50*(D + E)*(D + E + 50)/(3*D**2 - 2*D*E + 150*D - 3*E**2 - 50*E + 5000),
50*(D + E)*(D + E + 50)/(3*D**2 - 2*D*E + 150*D - 3*E**2 - 50*E + 5000),
(-3*D**3*E + 50*D**3 + 2*D**2*E**2 - 500*D**2*E + 10000*D**2 + 3*D*E**3 + 50*D*E**2 - 25000*D*E + 500000*D + 200*E**3 - 5000*E**2 - 500000*E + 12500000)/(3*D**3 + D**2*E + 150*D**2 - 5*D*E**2 + 100*D*E + 5000*D - 3*E**3 - 50*E**2 + 5000*E))
请注意,A 和 B 的解是相同的(与 A 和 B 的前两个方程的对称性一致)。
>>> sol = Dict(*zip((A,B,C),_))
>>> sol[A] = sol[B]
True
在这种形式中,您可以直接替换D
和E
的值:
>>> sol.subs({D:1, E:S.Half})
{A: 1030/1367, B: 1030/1367, C: 2265971/1367}
您还可以通过求解任何分母为 0 的情况来查看D
和E
之间的哪些关系是禁止的:
>>> from sympy.solvers.solvers import denoms
>>> set([j.simplify() for i in denoms(sol) for j in solve(i,D)])
{-E, E/3 - sqrt(10*E**2 - 9375)/3 - 25, E/3 + sqrt(10*E**2 - 9375)/3 - 25}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.