簡體   English   中英

求解非線性(和非多項式)方程組

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

在這種形式中,您可以直接替換DE的值:

>>> sol.subs({D:1, E:S.Half})
{A: 1030/1367, B: 1030/1367, C: 2265971/1367}

您還可以通過求解任何分母為 0 的情況來查看DE之間的哪些關系是禁止的:

>>> 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM