Sympy scheint nicht in der Lage zu sein, einen Ausdruck zu vereinfachen, bei dem die Quadratwurzel eines Quadrats einer Variablen beteiligt ist:

In [28]: a = x**2
In [29]: b = a**(1/2)
In [30]: b
Out[30]: 
    0.5
⎛ 2⎞   
⎝x ⎠   
In [31]: b.simplify()
Out[31]: 
    0.5
⎛ 2⎞   
⎝x ⎠   

Ich bekomme das nicht mit anderen Varianten von simplify zum Laufen, insbesondere hätte ich gedacht, dass b.powsimp() funktionieren sollte.

In [32]: b.powsimp()
Out[32]: 
    0.5
⎛ 2⎞   
⎝x ⎠   

Weiß jemand, warum das nicht funktioniert oder was ich falsch mache?

3
Karl Yngve Lervåg 9 Okt. 2012 im 13:24

3 Antworten

Beste Antwort

Es gibt zwei Probleme mit Ihrem Beispiel.

Zuerst sqrt(x**2)==x nur für positive reelle Zahlen.

Zweitens sind für SymPy 1/2 und 0.5 nicht dieselben Dinge. Die erste ist eine Rational Instanz, die zweite ist eine float Instanz.

Zum Schluss noch ein Beispiel:

>>> x = Symbol('x', real=True)
>>> (x**2)**(1./2)
∣x∣**1.0
>>> (x**2)**(S(1)/2) # S() is short for sympify()
∣x∣

sympify wandelt Python-Objekte in geeignetere SymPy-Objekte um.

6
Krastanov 9 Okt. 2012 im 17:25

Die gewünschte Funktion ist powdenest. Wenn der Parameter force=True übergeben wird, werden Annahmen ignoriert

>>> powdenest(sqrt(x**2), force=True)
x
2
asmeurer 10 Okt. 2012 im 02:47

Ich gehe davon aus, dass Sie x als x = Symbol('x') deklarieren. Wenn Sie es in x = Symbol('x', real=True) ändern, sollte der Ausdruck vereinfacht werden. Den Grund, warum Sie explizit angeben müssen, dass Ihre Variable real ist, finden Sie in der Sympy Bugtracker.

3
halex 9 Okt. 2012 im 09:53