向量化计算-点对之间的Bravais向量

时间:2019-06-28 15:39:12

标签: python numpy vectorization

向量化计算后产生的答案与原始答案有很大不同,我认为这是正确的。我可以正确向量化此计算吗?

我正在处理形状为(2,91)的n数组(mean_pos),并且正在使用for循环执行上述计算。因为Python中的for循环速度很慢(而且这不是执行操作的笨拙方式),所以我试图对代码进行向量化。

具有for循环:

def bravais_vector(natoms_i, mean_pos):
   b_matrix = []
   b_matrix_row = []

   lx = mean_pos[0].max() - mean_pos[0].min()
   ly = mean_pos[1].max() - mean_pos[1].min()

   for i in range(natoms_i):
       for j in range(natoms_i):

           dist_ij_x = mean_pos[0][i] - mean_pos[0][j]
           dist_ij_y = mean_pos[1][i] - mean_pos[1][j]

           if dist_ij_x > lx/2:
                dist_ij_x = -(lx - dist_ij_x)

           if dist_ij_y > ly/2:
                dist_ij_y = - (ly - dist_ij_y)

           if dist_ij_x < -lx/2:
               dist_ij_x = (lx + dist_ij_x)

           if dist_ij_y < -ly/2:
               dist_ij_y =  (ly + dist_ij_y)

           a2_opt = 2/np.sqrt(3) * dist_ij_y
           a1_opt = dist_ij_x - 0.5 * a2_opt

           b_matrix_row.append(np.array([ np.rint(a1_opt), np.rint(a2_opt) ]))

       b_matrix.append(b_matrix_row)
       b_matrix_row = []
   return np.array(b_matrix)

矢量化:

def bravais_vector(natoms_i, mean_pos):

    b_matrix = []
    b_matrix_row = []

    lx = mean_pos[0].max() - mean_pos[0].min()
    ly = mean_pos[1].max() - mean_pos[1].min()

    mean_pos_x = np.reshape(mean_pos[0], (len(mean_pos[0]),1))
    mean_pos_y = np.reshape(mean_pos[1], (len(mean_pos[1]),1))

    tiled_mean_pos_x = np.tile(np.transpose(mean_pos_x), (len(mean_pos_x) , 1))
    tiled_mean_pos_y = np.tile(np.transpose(mean_pos_y), (len(mean_pos_y) , 1))

    dist_ij_x = mean_pos_x - tiled_mean_pos_x
    dist_ij_y = mean_pos_y - tiled_mean_pos_y

    dist_ij_x = np.where(dist_ij_x > lx/2, -(lx - dist_ij_x), dist_ij_x)
    dist_ij_y = np.where(dist_ij_y > ly/2, -(ly - dist_ij_y), dist_ij_y)

    dist_ij_x = np.where(dist_ij_x < -lx/2, lx + dist_ij_x, dist_ij_x)
    dist_ij_y = np.where(dist_ij_y < -ly/2, ly + dist_ij_y, dist_ij_y)


    a2_opt = np.rint(np.multiply(2 / (np.sqrt(3)), dist_ij_x))
    a1_opt = np.rint(dist_ij_x - np.multiply(0.5, a2_opt))

    return np.stack((a1_opt, a2_opt), axis=2)

1 个答案:

答案 0 :(得分:0)

要小心,因为在矢量化版本中,您写道:

a2_opt = np.rint(np.multiply(2 / (np.sqrt(3)), dist_ij_x))

代替(根据第一个版本)

a2_opt = np.rint(np.multiply(2 / (np.sqrt(3)), dist_ij_y))

希望对您有帮助。