作者: 機械伯爵
日時: 2009/8/14(10:38)
Zazel writes:

> >> >>> sol = lambda a,b,c:[(-b+k*(b*b-4*a*c)**(1/2))/(2*a) for k in (1,-1)]
> >> >>> sol(1,2,3)
> >> [(-0.9999999999999999+1.4142135623730951j), (-1-1.4142135623730951j)]
> 
> これを
> 
> >>> import cmath
> >>> sol = lambda a,b,c:[(-b+k*cmath.sqrt(b*b-4*a*c))/(2*a) for k in (1,-1)]
> >>> sol(1,2,3)
> [(-1+1.4142135623730951j), (-1-1.4142135623730951j)]
> 
> にすると問題ないところがあれですね。

 しかも、mathだと……

>>> import math
>>> math.sqrt(-1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: math domain error

 虚数は扱わないそうで(泣)

※cmath = Mathematical functions for complex numbers.なのか……
 cPickleとか同じでc実装のMathかと……ならcMathだよなぁ……
 (高速バージョンを表すc-という名前は、3.xでは廃止されました)

> おかしな挙動というか手抜きなんじゃないかと思っています。
> 
> 普通に複素数でべき算を計算しようとすればオイラーの公式を使うと
> 思うので、それで誤差が現れるのではないかとの考えに至りました。
> 虚部だけの複素数だったら、一時的に虚数をはずして実数のべき乗の
> アルゴリズムを使えばいいのに、それをしていないのではないかとね。
> 
> というわけで、cmath.pow がないのが変ということで。(^_^;)

 オイラーの公式:e^(iθ)=cosθ+isinθ

 ……知らなかった(オイラーの等式の元なんですね)
 でも、素の計算でまがいなりにも-1**0.5が出来るのに、
math.sqrt(-1)のほうがきっちり領域(domain)を守ってるってのも、
不思議な感じがしますけどね……いや、それが正しいのか……

 /機械伯爵/