web-dev-qa-db-ja.com

PythonでNaNを引き起こす可能性のある計算はすべて何ですか?

私はさまざまなプログラミング言語のNaNsについて、いくつかの特定のケースを含むさまざまな議論を行っているようですが、網羅的または明確なものはありません。

NumPyまたはSciPyでの作業中に発生する、PythonでNaNを引き起こす最も一般的な操作は何ですか?

53
user961627

浮動小数点環境をいじらずに次のいずれかを実行する場合、以前は持っていなかった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_以上の場合はNaNsを取得し、入力値が_1e-1010_以下。ただし、本当に途方もなくスケーリングされた入力は別として、fftを使用すると非常に安全です。

行列演算が関係している場合、数値が非常に大きいまたは行列が非常に悪い場合、NaNは(通常_inf - inf_ルートを介して)切り抜けることができます-条件付け。数値線形代数によってどのようにねじ込まれ得るかについての完全な議論は、答えに属するには長すぎます。代わりに、数ヶ月のうちに数値線形代数の本(TrefethenとBauが人気)を調べることをお勧めします。

NaNを「生成すべきではない」コードを記述およびデバッグするときに役立つことがわかった1つのことは、NaNが発生した場合にトラップするようにマシンに指示することです。 GNU Cでは、これを行います:

_#include <fenv.h>
feenableexcept(FE_INVALID);
_
55
tmyklebu