有没有一种有效的方法可以根据数组索引计算两个3D向量的点积?

时间:2019-03-05 13:51:50

标签: python algorithm dot-product

我正在执行两个3D向量的以下点积:

import numpy as np

Nk = 8
Ns = 15
k_box = np.zeros(Nk**3)
R_box = np.zeros(Ns**3)
for k in range(Nk**3):
        Kx = int(k / (Nk*Nk))
        Ky = int(k / Nk) % Nk
        Kz = k % Nk
        for R in range(Ns**3):
            Rx = int(R / (Ns*Ns))
            Ry = int(R / Ns) % Ns
            Rz = R % Ns
            # This is the only place these variables are used!
            dot_product = Rx*Kx + Ry*Ky + Rz*Kz
            k_box[k], R_box[R] = perform_some_calculation(dot_product)

是否有一种无需先显式计算x, y, z分量就可以计算点积的方法?将其转换为6个循环会起作用,但看起来很麻烦。这似乎是一种技巧。

我可能还需要将其扩展到非立方体积,因此,如果有一个窍门并且它适用于一般的盒子几何形状,那将是理想的选择。

2 个答案:

答案 0 :(得分:2)

点积应按以下步骤进行

import numpy as np

R = np.array([Rx,Ry,Rz])
K = np.array([Kx,Ky,Kz])
value = np.dot(R,K)

答案 1 :(得分:0)

使用itertools.product生成点列表,该列表等效于每个坐标范围的<笛卡尔笛卡尔积:

>>> list(itertools.product(range(3), range(3), range(3)))
[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 1, 0), (0, 1, 1), (0, 1, 2), (0, 2, 0), 
 (0, 2, 1), (0, 2, 2), (1, 0, 0), (1, 0, 1), (1, 0, 2), (1, 1, 0), (1, 1, 1), 
 (1, 1, 2), (1, 2, 0), (1, 2, 1), (1, 2, 2), (2, 0, 0), (2, 0, 1), (2, 0, 2), 
 (2, 1, 0), (2, 1, 1), (2, 1, 2), (2, 2, 0), (2, 2, 1), (2, 2, 2)]

您还可以将所有6个坐标组合为一个生成器:

coords = itertools.product(range(Nk), range(Nk), range(Nk), range(Ns), range(Ns), range(Ns))
for kz, ky, kx, rz, ry, rx in coords:
    k, r = Nk * (Nk * kz + ky) + kx, Ns * (Ns * rz + ry) + rx
    dot_product = kx * rx + ky * ry + kz * rz
    k_box[k], R_box[r] = perform_some_calculation(dot_product)

或者,为避免索引计算,请使用enumerate

for k, (kz, ky, kx) in enumerate(itertools.product(range(Nk), range(Nk), range(Nk))):
    for r, (rz, ry, rx) in enumerate(itertools.product(range(Ns), range(Ns), range(Ns))):
        dot_product = kx * rx + ky * ry + kz * rz
        k_box[k], R_box[r] = perform_some_calculation(dot_product)