特に入力が順番にある場合、@Danielによる答えは正しいとは思いません[Fx, Fy, Fz, ...]
。
簡単なテストケース
MATLAB コードを参照してください。
a = [1 2 3;1 2 3; 1 2 3];
b = [[7 8 9] ;[1 5 8] ;[2 4 7]];
divergence(a,b)
結果は次のとおりです。
ans =
-5.0000 -2.0000 0
-1.5000 -1.0000 0
2.0000 0 0
そしてダニエルの解決策:
def divergence(f):
"""
Daniel's solution
Computes the divergence of the vector field f, corresponding to dFx/dx + dFy/dy + ...
:param f: List of ndarrays, where every item of the list is one dimension of the vector field
:return: Single ndarray of the same shape as each of the items in f, which corresponds to a scalar field
"""
num_dims = len(f)
return np.ufunc.reduce(np.add, [np.gradient(f[i], axis=i) for i in range(num_dims)])
if __name__ == '__main__':
a = np.array([[1, 2, 3]] * 3)
b = np.array([[7, 8, 9], [1, 5, 8], [2, 4, 7]])
div = divergence([a, b])
print(div)
pass
与える:
[[1. 1. 1. ]
[4. 3.5 3. ]
[2. 2.5 3. ]]
説明
ダニエルの解決策の間違いは、Numpy では、x 軸が最初の軸ではなく最後の軸であることです。を使用するnp.gradient(x, axis=0)
と、Numpy は実際にy 方向の勾配を与えます(x が 2 次元配列の場合)。
私の解決策
ダニエルの答えに基づく私の解決策があります。
def divergence(f):
"""
Computes the divergence of the vector field f, corresponding to dFx/dx + dFy/dy + ...
:param f: List of ndarrays, where every item of the list is one dimension of the vector field
:return: Single ndarray of the same shape as each of the items in f, which corresponds to a scalar field
"""
num_dims = len(f)
return np.ufunc.reduce(np.add, [np.gradient(f[num_dims - i - 1], axis=i) for i in range(num_dims)])
divergence
私のテスト ケースでは、MATLAB と同じ結果が得られます。