2016-04-12 5 views
11

Ich habe über einige verwirrende Verhalten mit Quadratwurzeln komplexer Zahlen in Python gerannt. Das Ausführen dieses Code:Quadratwurzel von komplexen Zahlen in Python

from cmath import sqrt 
a = 0.2 
b = 0.2 + 0j 
print(sqrt(a/(a - 1))) 
print(sqrt(b/(b - 1))) 

der Ausgang

0.5j 
-0.5j 

Ähnliches passiert mit

print(sqrt(-1 * b)) 
print(sqrt(-b)) 

ergibt Es scheint, diese Paare von Aussagen sollten die gleiche Antwort geben?

+0

Nach [Wolfram] (https://www.wolframalpha.com/) sind Sie richtig. Das erste Paar ([link] (https://www.wolframalpha.com/input/?i=sqrt (0.2 +% 2F + (0.2 + - + 1))) und [link] (https: //www.wolframalpha .com/input /? i = sqrt (+ (0,2% 2B0i) +% 2F + (+ (0,2% 2B0i) + - 1+)))) beide sollten '0,5i' sein, und das zweite Paar ([link] (https://www.wolframalpha.com/input/?i=sqrt(-1+*+(0.2+%2B+0i))) und [link] (https://www.wolframalpha.com/input/ ? i = sqrt (-1 + * + (0.2 +% 2B + 0i)))) sollten beide "0.447214 ... i" sein. Die Quelle für 'cmath.sqrt()' ist [hier] (https://hg.python.org/cpython/file/tip/Modules/cmathmodule.c#l732) ... – Jens

+6

Beide Antworten sind richtig, die Frage Deshalb gibt es verschiedene Konjugate zurück. – tzaman

+0

FWIW das Verhalten erscheint das gleiche in 2.7 und 3.5. – tzaman

Antwort

8

Beide Antworten (+0.5j und -0.5j) sind korrekt, da sie complex conjugates sind - d. H. Der Realteil ist identisch und der Imaginärteil ist Vorzeichen-gekippt.

am code Blick macht das Verhalten klar - der imaginäre Teil des Ergebnisses immer die gleichen Vorzeichen als imaginären Teil des Eingangs hat, wie in den Zeilen 790 und 793 gesehen:

r.imag = copysign(d, z.imag); 

Seit a/(a-1) ist 0.25 was implizit ist 0.25+0j Sie erhalten ein positives Ergebnis; b/(b-1) produziert 0.25-0j (aus irgendeinem Grund; nicht sicher, warum es nicht 0.25+0j tbh ergibt), so ist Ihr Ergebnis ähnlich negativ.

EDIT: This question hat einige nützliche Diskussion über das gleiche Problem.

+0

'a/(a ​​- 1)' ist '-0,25'. Konvertiert man es in einen Komplex, erhält man "-0,25 + 0j". Mit b erhalten Sie '-0.25-0j'. – Seth

+0

Die [Dokumentation] (https://docs.python.org/2/library/cmath.html#cmath.sqrt) gibt außerdem an, dass der Verzweigungsschnitt so gewählt wird, dass er entlang eines Strahls von 0 bis -∞ verläuft, was das beobachtete Verhalten ergeben würde. Es ist interessant, dass 'b/(b-1)' eine negative Null für die imaginäre Komponente ergibt. – user2357112

+0

@ user2357112 Ja, das ist ziemlich seltsam, ich bin mir nicht sicher, warum es das tut. Einfach '1-0j' als Literal in IDLE eingeben, ergibt' 1 + 0j' als Wert. Interessanterweise erzeugt "-0j" selbst "-0-0j". – tzaman

1

Ich kann beantworten, warum das passiert, aber nicht, warum das Verhalten gewählt wurde.

a/(a - 1) 

auswertet bis 0,2/-0.8 die -0.25 ist, die von cmath.sqrt in eine komplexe Zahl umgewandelt wird, während

b/(b - 1) 

auswertet bis (0,2 + 0j)/(- 0,8 + 0j) was (-0.25-0j) ist, das in eine komplexe Zahl mit einer negativen komplexen Komponente umgewandelt wird.

Für ein einfacheres Beispiel

cmath.sqrt(0j) == 0j 
cmath.sqrt(-0j) == -0j