私はさまざまなプログラミング言語のNaN
sについて、いくつかの特定のケースを含むさまざまな議論を行っているようですが、網羅的または明確なものはありません。
NumPyまたはSciPyでの作業中に発生する、PythonでNaN
を引き起こす最も一般的な操作は何ですか?
浮動小数点環境をいじらずに次のいずれかを実行する場合、以前は持っていなかったNaNを取得する必要があります。
0/0
_(上下どちらかの記号)inf/inf
_(上下どちらかの記号)inf - inf
_または_(-inf) + inf
_またはinf + (-inf)
または_(-inf) - (-inf)
_0 * inf
_および_inf * 0
_(両方の要因でいずれかのサイン)sqrt(x)
when _x < 0
_fmod(x, y)
_y = 0
_またはx
が無限の場合。ここでfmod
は浮動小数点剰余です。機械演算のこれらの側面の標準的な参照は、 IEEE 754仕様 です。セクション7.1では、無効な操作の例外について説明します。これは、NaNを取得しようとしているときに発生する例外です。 IEEE 754の「例外」は、プログラミング言語のコンテキストでの例外とは異なることを意味します。
特別な関数の実装の多くは、実装しようとしている関数の特異点での動作を文書化します。たとえば、_atan2
_およびlog
のマニュアルページを参照してください。
特にNumPyとSciPyについて質問しています。これが単に「NumPyの内部で発生する機械演算について尋ねている」のか、「eig()
などについて尋ねているのか」ということだけなのかわかりません。前者を想定していますが、この回答の残りの部分では、NumPyの上位レベルの関数へのあいまいな接続を試みます。基本的なルールは次のとおりです:関数の実装が上記のいずれかの罪を犯した場合、NaNを取得します。
たとえば、fft
の場合、入力値が_1e1010
_以上の場合はNaN
sを取得し、入力値が_1e-1010
_以下。ただし、本当に途方もなくスケーリングされた入力は別として、fft
を使用すると非常に安全です。
行列演算が関係している場合、数値が非常に大きいまたは行列が非常に悪い場合、NaNは(通常_inf - inf
_ルートを介して)切り抜けることができます-条件付け。数値線形代数によってどのようにねじ込まれ得るかについての完全な議論は、答えに属するには長すぎます。代わりに、数ヶ月のうちに数値線形代数の本(TrefethenとBauが人気)を調べることをお勧めします。
NaNを「生成すべきではない」コードを記述およびデバッグするときに役立つことがわかった1つのことは、NaNが発生した場合にトラップするようにマシンに指示することです。 GNU Cでは、これを行います:
_#include <fenv.h>
feenableexcept(FE_INVALID);
_