4

大きなベクトル フィールドがあり、フィールドが大きく (たとえば 512^3; ただし、必ずしも正方形であるとは限りません)、ベクトルは 2D または 3D のいずれかです (たとえば、形状は [512, 512, 512, 2] または [512, 512, 512, 3])。

ベクトルの大きさの 2 乗のスカラー場を計算する最速の方法は何ですか?

各方向にループするだけです。

import numpy as np
shp = [256,256,256,3]                       # Shape of vector field
vf = np.arange(3*(256**3)).reshape(shp)     # Create vector field
sf = np.zeros(shp[:3])                      # Create scalar field for result

for ii in range(shp[0]):
    for jj in range(shp[1]):
        for kk in range(shp[2]):
            sf[ii,jj,kk] = np.dot( vf[ii,jj,kk,:] , vf[ii,jj,kk,:] )

しかし、それはかなり遅いです。もっと速いものはありますか?

4

1 に答える 1

6

最速はおそらく次のようになりますnp.einsum

np.einsum('...j,...j->...', vf, vf)

上記のコードは、対応する値を乗算してそれらを加算することにより、その入力を取得し、それぞれの最後の次元を減らすように numpy に指示します。マグニチュードが のデフォルトの戻り値である 32 ビット整数に収まらないため、データセットにはオーバーフローの問題がありますnp.arangenp.int64またはのいずれかとして、戻り値の dtype を指定することで解決できますnp.double

>>> np.einsum('...j,...j->...', vf,vf)[-1, -1, -1]
-603979762
>>> np.einsum('...j,...j->...', vf,vf).dtype
dtype('int32')

>>> np.einsum('...j,...j->...', vf,vf, dtype=np.int64)[-1, -1, -1]
7599823767207950
>>> np.einsum('...j,...j->...', vf,vf, dtype=np.double)[-1, -1, -1]
7599823767207950.0
于 2013-11-08T16:32:57.167 に答える