2016-09-05 5 views
1

私はいくつかの長い数式での作業ではなく、本当に複雑で、私はそれらを簡素化し、「因数分解」するsympyを使用していたのです。しかし、私はいくつかの問題に遭遇しました。Sympyの潜水艦の制限

問題1:ここではいくつかの最小限の例のリストである第二1で何の置換はありませんが対称

from sympy import * 
from __future__ import division 
a = symbols('a') 
b = symbols('b') 
expr = 1/12*b + 1 
expr.subs(1/12*b, a) 
expr.subs(b*1/12, a) 

は、最初の行は、予想される結果(すなわちa+1)を提供します。

問題2:因数分解表現

表現の一部は、因数分解されていると私は表現を展開すると、彼らはこのように置換が不可能、単純化され得ます。例えば

(((x+1)**2-x).expand()).subs(x**2+2*x, y+1) 

x^2+x+1を与え、私が探していますと、y+2-xあるでしょう。これらの問題を解決する方法は

質問

ありますか?あるいは、別の記号的な数学的ツールを使うべきでしょうか?どんな提案も歓迎されます。

答えて

4

あなたは、Pythonを使用している場合ので、Pythonが動作する方法を、number/numberは浮動小数点(あるいはない整数の割り算を与える、ということであるSymPyに大きな落とし穴があります2であり、from __future__ import divisionはありません)。

最初のケースでは、元の式では、Pythonは1/12*bを左から右に評価します。 1/12はPythonによって評価されて0.08333333333333333となり、次にbが乗算されます。 2番目のケースでは、b*1bと評価されます。次にb/12はSymPyによって評価されます(bはSymPyオブジェクトです)。Rational(1, 12)*bとなります。

浮動小数点数が不正確であるため、SymPyでは浮動小数点0.08333333333333333が有理数1/12と同じではありません。

この問題の詳細は、hereです。回避策として、直接integer/integerを回避して、何らかの形でラップすることは避けてください。そうすれば、SymPyは合理的なものを作成できます。以下はすべて合理的に作成されます:

b/12 
Rational(1, 12)*b 
S(1)/12*b 

(((x+1)**2-x).expand()).subs(x**2+2*x, y+1)について問題がx**2 + 2*xx**2 + x + 1ある表現で正確に表示されていないということです。 SymPyは、通常、正確に見えるものだけを置き換えます。

交換作業のためにxを追加したり削除したりしても構いません。だから私は代わりに(((x+1)**2-x).expand()).subs(x**2, y+1 - 2*x)をやってお勧めします。単一の用語(x**2)を置換するだけで、置換は常に機能し、はキャンセルされ、xの用語が残っています(この場合は-x)。

1

ここではあなたの問題を可能なソリューションです:

from sympy import * 

a = symbols('a') 
b = symbols('b') 
expr = 1/12 * b + 1 
print(expr.subs((1/12) * b, a)) 
print(expr.subs(b * (1/12), a)) 

x = symbols('x') 
y = symbols('y') 
expr = ((x + 1)**2 - x).expand() 
print(expr.subs(x**2 + x, y - x + 1)) 
+0

最初の問題については、私はそこから '_ __future__インポート部門 'があると思いますが、これを追加して試してみました。しかし、なぜ私は理解していない。 2番目の問題については、これは本当に私の問題を解決しません。私がここで与えたことは、最小の例ですが、実際には方程式は実際には長いです。私は本当に結果を「不正にする」ことはできません。そして私は間違いなく値を変更することはできません... お返事ありがとう! – lasofivec

+0

2番目の質問では、おそらく私の質問は「単純化せずに拡張することは可能ですか」です。 – lasofivec

1

問題1については、1/12*bb*1/12はsympyでない同じものであることに注意してください。最初は浮動小数点数が記号で置き換えられ、2番目は厳密な記号式です(簡単なprint文で確認できます)。 exprには1/12*bが含まれているため、2番目のsubsは機能しません。

問題2については、あなたが提供するsubsルールがあいまいです。特に、置換規則は、方程式x**2+2*x==y+1を意味します。しかし、この式は、例えば、このため

x**2 == y + 1 - 2*x(これはあなたが考えるものです)、

x**2 + x == y + 1 - x

x == (y + 1 - x**2)/2

を多くの解釈を持って、私はsympy拒否を実行するために考えます実際には代替が正しいアプローチです。

それはあなたがしたい最初の解釈であるならば、すなわち、明示的subsルールでそれを提供することをお勧めします、

(((x+1)**2-x).expand()).subs(x**2, -2*x + y + 1) 

-x + y + 2

関連する問題