2016-04-12 4 views
11

私はPythonの複素数の平方根を使っていくつかの混乱した振る舞いを経験しました。このコードを実行すると:Pythonの複素数の平方根

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

出力に

0.5j 
-0.5j 

を与える同じようなことは、文のこれらのペアは、同じ答えを与えるべきで表示されます

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

とどうなりますか?

+0

[ウォルフラム(https://www.wolframalpha.com/)によれば、あなたは正しいです。最初のペア([link](https://www.wolframalpha.com/input/?i=sqrt(0.2 +%2F +(0.2 + - + 1))と[link](https://www.wolframalpha .COM /入力/ I =のSQRT((+ 0.2%2B0i)+%2F +(+(0.2%2B0i)+ - 1+))?))の両方が '0.5i'、及び第二の対であるべきである([リンク] (https://www.wolframalpha.com/input/?i=sqrt(-1+*+(0.2+%2B+0i)))と[link](https://www.wolframalpha.com/input/) ?i = sqrt(-1 + * +(0.2 +%2B + 0i))))は両方とも0.447214 ... iでなければならない。 cmath.sqrt() ''のソースは[こちら](https://hg.python.org/cpython/file/tip/Modules/cmathmodule.c#l732)... – Jens

+6

どちらの答えが正しいか、疑問です異なるコンジュゲートを返す理由です。 – tzaman

+0

FWIWの動作は2.7と3.5で同じように見えます。 – tzaman

答えて

8

complex conjugatesであるため、両方の回答(+0.5j-0.5j)は正しいです。つまり、実数部は同一で、虚数部は符号反転されています。 codeを見ると

は行動が明らかに - 結果の虚部は常にライン790と793に見られるように、入力の虚数部として同じ符号があります

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

ので、 a/(a-1)0.25です。これは暗黙的に0.25+0jです。 b/(b-1)0.25-0jを生成します(なんらかの理由で、なぜそれが0.25+0j tbhにならないのかわかりません)ので、結果も同様に否定的です。

編集:This questionは、同じ問題についていくつかの有用な議論があります。

+0

'a /(a - 1)'は '-0.25'です。それをコンプレックスに変換すると '-0.25 + 0j'が得られます。 bでは '-0.25-0j'が得られます。 – Seth

+0

[documentation](https://docs.python.org/2/library/cmath.html#cmath)。sqrt)はまた、ブランチカットが0から-∞までのレイに沿って選択され、観測された振る舞いを与えることを指定します。興味深いことに、 'b /(b-1)'は虚数成分に対して負のゼロを与えます。 – user2357112

+0

@ user2357112ええ、それはかなり奇妙です、なぜ私はそれをしないのか分かりません。 IDLEにリテラルとして '1-0j'を入力するだけで、値として' 1 + 0j'が生成されます。興味深いことに、 '-0j'自体は' -0-0j'を生成します。 – tzaman

1

私はこれがなぜ起こっているのか、なぜ行動が選択されたのかについて答えることができます。 ( - 0.8 + 0J)

b/(b - 1) 

は(0.2 + 0jを)/に評価しながら

a/(a - 1) 

は、cmath.sqrtによって複素数に変換さ-0.25 0.2/-0.8、と評価しますこれは(-0.25-0j)であり、負の複素数成分を有する複素数に変換される。単純例えば

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