np.float32 と組み込みの Python int および float の間でバイナリ演算 (加算や乗算など) を実行し、戻り値の型として np.float32 を取得したいと考えています。ただし、np.float64 に自動的にアップキャストされます。
コード例:
>>> a = np.float32(5)
>>> a.dtype
dtype('float32')
>>> b = a + 2
>>> b.dtype
dtype('float64')
np.float128 でこれを行うと、b も np.float128 になります。これにより、精度が維持されるため、これは良いことです。ただし、私の例では精度を維持するために np.float64 へのアップキャストは必要ありませんが、それでも発生します。2 ではなく 2.0 (Python float (64 ビット)) を a に追加した場合、キャストは理にかなっています。しかし、ここでも、私はそれを望んでいません。
私の質問は次のとおりです。二項演算子を np.float32 と組み込みの Python int/float に適用するときに行われるキャストを変更するにはどうすればよいですか? または、すべての計算で倍精度ではなく単精度を標準にすることも、解決策としてカウントされます。倍精度は必要ないからです。他の人がこれを求めており、解決策が見つかっていないようです。
私はnumpy配列とdtypesについて知っています。ここで、配列は常にその dtype を保持するため、必要な動作が得られます。ただし、配列の単一の要素に対して操作を行うと、望ましくない動作が発生します。np.ndarray (または np.float32) のサブクラス化と __array_priority__ の値の変更を含む、漠然とした解決策があります。これまでのところ、私はそれを機能させることができませんでした。
なぜ私は気にするのですか?Numba を使用して n-body コードを記述しようとしています。これが、配列全体に対して単純に操作を行うことができない理由です。すべての np.float64 を np.float32 に変更すると、速度が約 2 倍になります。これは重要です。np.float64 キャスト動作は、この高速化を完全に台無しにするのに役立ちます。これは、np.float32 配列に対するすべての操作が 64 精度で行われ、その後 32 精度にダウンキャストされるためです。