2017-01-04 11 views
2

私はいくつかのJavaコードの結果である多変量方程式のシステムを解こうとしています。ランタイムの前には、フォームの数も変数の数も分かっていません。例はプログラムで多変量方程式系を解く方法は?

ZeroDivisionError: polynomial division 

変数は区間[0,1]のすべてのあるエラーをスロー

(I) (e-a*d*e-b*d*e+2*b*d*f+2*b*d*e*g)/(-1+a*d+b*d)+f == 0 

(II) e*g+((f+e*g)*a*d)/(-1+a*d+b*d)==0 

(III) -e*h+((-f-e*g)*d)/(-1+a*d+b*d)==0 

(IV) -e*j+((-f-e*g)*c)/(-1+a*d+b*d)==0 

Iは、単に入力を返すSymjaを用いて試みたが、SymPy、であり、そしてなります私はすべての解決策が必要です。 Mathematicaはこれを解決することができますが、商用ソフトウェアであるため残念ながらこのプロジェクトでは使用できません。

使用するソフトウェアに関する推奨事項に感謝します。 SymPyが本当に好きだったのですが、なぜこのエラーが発生するのか分かりません。アイディアは高く評価されています。

from sympy.solvers import solve 
from sympy.abc import a,b,c,d,e,f,g,h,j 

lst = a,b,c,d,e,f,g,h,j 
sys = [(e-a*d*e-b*d*e+2*b*d*f+2*b*d*e*g)/(-1+a*d+b*d)+f,e*g+((f+e*g)*a*d)/(-1+a*d+b*d),-e*h+((-f-e*g)*d)/(-1+a*d+b*d),-e*j+((-f-e*g)*c)/(-1+a*d+b*d)] 

solution = solve(sys, lst) 
print solution 

Mathematicaのバージョンは次のとおりです:

eqn = {(e - a*d*e - b*d*e + 2*b*d*f + 2*b*d*e*g)/(-1 + a*d + b*d) + f == 0, e*g + ((f + e*g)*a*d)/(-1 + a*d + b*d) == 0, -e*h + ((-f - e*g)*d)/(-1 + a*d + b*d) == 0, -e*j + ((-f - e*g)*c)/(-1 + a*d + b*d) == 0}; 
Simplify[Solve[eqn, {a, b, c, d, e, f, g, h, j}]] 

出力:場合

{{e -> 0, f -> 0}, 
{c -> (1 - 2 a d - 3 b d) j, f -> ((-1 + 2 a d + b d) e)/(-1 + 2 a d + 3 b d), g -> (a d)/(1 - 2 a d - 3 b d), h -> d/(1 - 2 a d - 3 b d)}, 
{a -> 0, c -> j - 3 b d j, f -> ((-1 + b d) e)/(-1 + 3 b d), g -> 0, h -> d/(1 - 3 b d)}, 
{a -> (1 - b d)/(2 d), c -> -2 b d j, f -> 0, g -> 1/4 - 1/(4 b d), h -> -(1/(2 b))}} 
+0

Mathematicaの表現とソリューションを投稿できますか? –

+0

共通分母を乗算しようとしましたか?私はそれらのツールがそれを自動化する方法を与えると思いますが、結果を解決できるかどうかを手で確認することもできます。 – agentp

+0

@agentpはいこれを試してみましたが、それでも問題はありませんでした。 – berndibus

答えて

0

この質問を閉じますが、ここではMathematicaの試みであるSymPyエラーにMWEの下にバージョン。しかし、現在のところ、変数を区間[0,1]に制限する条件が不足している。

Solve[{ 
    (e - a d e - b d e + 2 b d f + 2 b d e g)/(-1 + a d + b d) + f == 0, 
    e g + ((f + e g) a d)/(-1 + a d + b d) == 0, 
    -e h + ((-f - e g) d)/(-1 + a d + b d) == 0, 
    -e j + ((-f - e g) c)/(-1 + a d + b d) == 0 
    }, 
{a, b, c, d, e, f, g, h, j}] 

enter image description here

+0

私の質問にMathematicaのバージョンを追加しましたが、商用ソフトウェアとしてMathematicaを使用することはできません。 – berndibus

+0

変数を区間[0,1]に制限する条件を追加していないので、SymPy(または他のソフトウェア)から必要なものに主に関係しないと推測されます。 –

+0

それはいいですが、私はそれが2番目のステップでは、主な課題は解決であることを制限することが可能だろうと思った。それを直接行うことができれば、はるかに良いでしょう。 – berndibus

0

[OK]を、私はMathematicaのと同じ出力を与えると、自分自身がSAGEを使用して問題を解決することができました。

sage: a,b,c,d,e,f,g,h,j = var('a,b,c,d,e,f,g,h,j') 
sage: qe = [(e-a*d*e-b*d*e+2*b*d*f+2*b*d*e*g)+f*(-1+a*d+b*d),e*g*(-1+a*d+b*d)+((f+e*g)*a*d),-e*h*(-1+a*d+b*d)+((-f-e*g)*d),-e*j*(-1+a*d+b*d)+((-f-e*g)*c)] 
sage: print(solve(qe,a,b,c,d,e,f,g,h,j, solution_dict=True)) 

は、出力あなたが9つの変数と4次方程式を持って

[{g: r5, j: r7, b: r2, d: r4, e: 0, h: r6, c: r3, f: 0, a: r1}, 
{g: r12, j: r14, b: r8, d: r10, e: r11, h: r13, c: r9, f: -r11*r12, a: -(r10*r8 - 1)/r10}, 
{g: r15*r18, j: r19, b: -1/6*(4*r15*r16*r18 - r16 + 3*r17)*(4*r15*r16*r18^2/(4*r15*r16*r18 - r16 + 3*r17) + 2*r16*r18/(4*r15*r16*r18 - r16 + 3*r17) - r18)/(r16*r18^2), d: 2*r16*r18/(4*r15*r16*r18 - r16 + 3*r17), e: r16, h: r18, c: 2*r16*r19/(4*r15*r16*r18 - r16 + 3*r17), f: r17, a: r15}, 
{g: r20*r23, j: 0, b: -1/6*(4*r20*r21*r23 - r21 + 3*r22)*(4*r20*r21*r23^2/(4*r20*r21*r23 - r21 + 3*r22) + 2*r21*r23/(4*r20*r21*r23 - r21 + 3*r22) - r23)/(r21*r23^2), d: 2*r21*r23/(4*r20*r21*r23 - r21 + 3*r22), e: r21, h: r23, c: 0, f: r22, a: r20}, 
{g: -2*r24*r27 - 1, j: 0, b: r24, d: r25, e: r26, h: r27, c: 0, f: 2*r24*r26*r27 + r26, a: -(r24*r25 - 1)/r25}, 
{g: 0, j: r30, b: r29, d: 0, e: r31, h: 0, c: r30, f: r31, a: r28}, 
{g: 0, j: 0, b: r33, d: 0, e: r34, h: 0, c: 0, f: r34, a: r32}, 
{g: -1, j: 0, b: 0, d: r35, e: r36, h: r37, c: 0, f: r36, a: 1/r35}, 
{g: r40, j: 0, b: 0, d: r38, e: r39, h: 2*r38*r40 + r38, c: 0, f: r39, a: r40/(2*r38*r40 + r38)}, 
{g: -1/2, j: 0, b: -1/2*(r41 - r42)/(r41*r43), d: -2/3*r41*r43/(r41 - r42), e: r41, h: r43, c: 0, f: r42, a: -1/2/r43}] 
1

注意を与えます。したがって、あなたは4つの変数を取り除くことができます。あなたはSympyにそれを伝える必要があります。

次のコードは、最初の分母アウト及び排除a,b,c,dを乗算:

以下の出力を生成
import sympy as sy 
from IPython.display import display # for pretty printing 

# sy.init_printing() # LaTeX-like pretty printing for IPython 

a, b, c, d, e, f, g, h, j = sy.symbols("a, b, c, d, e, f, g, h, j", real=True) 
lst = a, b, c, d, e, f, g, h, j 
sys0 = sy.Matrix([(e-a*d*e-b*d*e+2*b*d*f+2*b*d*e*g)/(-1+a*d+b*d)+f, 
        e*g+((f+e*g)*a*d)/(-1+a*d+b*d), 
        -e*h+((-f-e*g)*d)/(-1+a*d+b*d), 
        -e*j+((-f-e*g)*c)/(-1+a*d+b*d)]) 

# Denominator can be factored out: 
den = a*d + b*d - 1 
sys1 = sy.simplify(sys0*den).expand() 
print("Factored out denominator:") 
display(sys1) 

# Elimnate four variables: 
sol1 = sy.solve(sys1, a, b, c, d, dict=True) 
print("Solutions:") 
display(sol1) 
print("Substituting back into the equation gives obviously 0, i.e.:") 
display(sy.simplify(sys1.subs(sol1[0])).T) 

print("The denominator != 0 results in:") 
den1 = sy.simplify(den.subs(sol1[0])) 
display(sy.solve(den1)) 

Factored out denominator: 
Matrix([ 
[-a*d*e + a*d*f + 2*b*d*e*g - b*d*e + 3*b*d*f + e - f], 
[     2*a*d*e*g + a*d*f + b*d*e*g - e*g], 
[    -a*d*e*h - b*d*e*h - d*e*g - d*f + e*h], 
[    -a*d*e*j - b*d*e*j - c*e*g - c*f + e*j]]) 
Solutions: 
[{d: 2*e*h/(4*e*g - e + 3*f), 
    c: 2*e*j/(4*e*g - e + 3*f), 
    a: g/h, 
    b: (-e + f)/(2*e*h)}] 
Substituting back into the equation gives obviously 0, i.e.: 
Matrix([[0, 0, 0, 0]]) 
The denominator != 0 results in: 
[{e: -f/g}] 

そこで得られたアイデンティティがある:

-f/g != e # denominator - only false, if f,e=0 since f,g,e>=0 
a = g/h 
b = (-e + f)/(2*e*h) 
c = 2*e*j/(4*e*g - e + 3*f) 
d = 2*e*h/(4*e*g - e + 3*f) 

私が知っている限り、Sympyはmultiv (私は間違っていると証明したいが)。しかし、結果は手で行うのに十分に簡単です:

0 <= g <= h 
0 <= f-e <= 2*e*h 
0 <= 2*e*j <= 4*e*g - e + 3*f 
0 <= 2*e*h <= 4*e*g - e + 3*f 
0 <= e,f,g,h,j <= 1 

場合f,e=0が同様に有効です。 sys0.subs(e,0).diff(f)fに依存していないことを確認することで確認できます。

+1

非常に良いアプローチ。 – Stelios

+0

これは確かに、この特定のシステムにとって素晴らしいアプローチです。残念ながら、方程式の構造は実行時には分かっていません。これは、共通分母を有するすべての方程式のこの場合がアーティファクトであり、他の場合において異なることがあることを意味する。したがって、私はこのソリューションをどのようにプログラムで動作するように拡張することができないのか分かりません。 – berndibus

+0

@berndibus方程式の構造について何も知りませんが、私の経験上、このようなアプローチは問題になります(特にコーナーケースの場合)。 Mathematica(そしてSympy)では、 'Solve []'が有効な解決策を提示するかどうかを調べるために、私は30分以上待っています。 Mathematicaはあなたの例で*すべての*解決策を提供していないことに注意してください - 'Reduce []'がより適切でしょう。もしあなたが確信しているなら、あなたは方程式がうまく動作しているので、あなたの80%の解法は私の解答のように最初の4つの変数を取り除くことかもしれません。 – Dietrich

関連する問題