[英]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.