14

おそらくこれはアルゴリズムの問​​題ですが、次のコードの一部

numpy.power((-1+0j),0.5)

次の出力を生成します

(6.1230317691118863e-17+1j)

類似の式、たとえばnumpy.power(complex(-1),.5)、同じ結果がnumpy.sqrt(complex(-1))得られますが、 - の期待される結果が得られ1jます。明らかに、結果には実際の部分がないはずなので、重要なものが欠けているか、これをnumpy開発者に報告する必要があります.

誰かが尋ねた場合、いいえ、実数部を四捨五入することはできません(この計算には完全な精度が必要です)。はい、累乗関数を使用する必要があります。

4

3 に答える 3

15

-1 の平方根は exp(i phase/2) として計算され、(-1 の) 位相はπ です。実際には、

>>> import cmath, math
>>> z = -1+0j
>>> cmath.phase(z)
3.141592653589793
>>> math.cos(_/2)
6.123233995736766e-17

これは、-1 の位相が 1e-17 の数までだけ π であることを示しています。位相を 2 で割った値も約 π/2 にすぎず、そのコサインは約 0 にすぎないため、結果が得られます (結果の実部はこのコサインです)。

問題は、固定された有限数の浮動小数点数しかないという事実から最終的に生じます。数値 π は浮動小数点数のリストにないため、近似的にしか表現できません。π/2 も正確に表すことができないため、-1 の平方根の実部は π/2 の浮動小数点近似のコサインです (したがって、0 とは異なるコサイン)。

したがって、Python の近似値numpy.power(complex(-1), .5)は、最終的には浮動小数点数の制限によるものであり、多くの言語で見られる可能性があります。

あなたが観察したことは、数の累乗の実装を通じて、この浮動小数点の制限に関連しています。あなたの例では、平方根は、モジュールと複素数の引数を評価することによって計算されます(基本的に、log(module)+ iフェーズを返すlog関数を介して)。一方、異なる方法を使用し、 (TonyK が示唆するように)の浮動小数点近似の問題に悩まされていないため、cmath.sqrt(-1)正確に与えられます。1j(-1+0j)**0.5

于 2011-06-09T13:11:05.997 に答える
9

numpy.power()これはfor 複素数の実装の副作用です。stdlib にも同じ問題があります。

>>> numpy.power(-1+0j, 0.5)
(6.123233995736766e-17+1j)
>>> cmath.exp(cmath.log(-1)/2)
(6.123233995736766e-17+1j)
于 2011-06-09T08:51:26.020 に答える
5

numpy.real_if_close() を試してください。

参照:近い場合はリアル

于 2011-06-27T13:16:17.860 に答える