Numpy创建NXNX2阵列的NX2 DOT乘积的NXN数组



我的目的是为所有粒子创建一个粒子和其他粒子之间的角度的NXN阵列。然后,蒙版阵列可以在特定视野中选择所有粒子。

我的问题是如何行采取两个NXN阵列(DX/距离和DY/距离),然后将DOT乘积带有一排NX2向量以导致一个粒子和其他所有粒子之间的NX1阵列粒子。重复所有行,并导致所有角度的NXN阵列。

上下文 - 位置(x,y)和速度(x,y)的n粒子。每个粒子之间的偏移矢量可以通过创建N X N阵列DX和N X N阵列DY来计算。偏移矢量(从粒子i到粒子j)为(xi -xj,yi -yj),我们可以从(dx,dy)中获得。创建单位矢量组件DX/距离和DY/距离。

n = 4
k = 10
width = 50
boid_radius = 8
dim = 2
position = np.random.rand(n, dim) * width  # random dataset
velocity = 0.5 * np.random.random_sample((n, dim)) + 1
from sklearn import preprocessing as pp
velocity_normalized = pp.normalize(velocity)
dx = np.subtract.outer(position[:, 0], position[:, 0])
dy = np.subtract.outer(position[:, 1], position[:, 1])
distance = np.hypot(dx, dy)
# mask zeros
ox = dx/distance
ox = dy/distance

示例数据:

position
Out[233]: 
array([[  6.68625116,  34.35642605],
       [ 18.96766714,  45.61291941],
       [ 49.49921981,  37.95450382],
       [ 28.22272906,  42.90652135]])
dx
Out[234]: 
array([[  0.        , -12.28141597, -42.81296865, -21.5364779 ],
       [ 12.28141597,   0.        , -30.53155268,  -9.25506192],
       [ 42.81296865,  30.53155268,   0.        ,  21.27649075],
       [ 21.5364779 ,   9.25506192, -21.27649075,   0.        ]])
dy
Out[235]: 
array([[  0.        , -11.25649336,  -3.59807777,  -8.5500953 ],
       [ 11.25649336,   0.        ,   7.65841559,   2.70639806],
       [  3.59807777,  -7.65841559,   0.        ,  -4.95201753],
       [  8.5500953 ,  -2.70639806,   4.95201753,   0.        ]])

形成偏移单元向量组件:

distance = np.hypot(dx, dy).round()
array([[  0.,  17.,  43.,  23.],
       [ 17.,   0.,  31.,  10.],
       [ 43.,  31.,   0.,  22.],
       [ 23.,  10.,  22.,   0.]])
zeros = ma.masked_where(distance==0, distance)
masked_array(data =
 [[-- 17.0 43.0 23.0]
 [17.0 -- 31.0 10.0]
 [43.0 31.0 -- 22.0]
 [23.0 10.0 22.0 --]],
             mask =
 [[ True False False False]
 [False  True False False]
 [False False  True False]
 [False False False  True]],
       fill_value = 1e+20)
ox = dx / zeros
masked_array(data =
 [[-- -0.7224362336046727 -0.9956504337130146 -0.9363686041759272]
 [0.7224362336046727 -- -0.9848887960767806 -0.9255061924766889]
 [0.9956504337130146 0.9848887960767806 -- 0.9671132160733322]
 [0.9363686041759272 0.9255061924766889 -0.9671132160733322 --]],
             mask =
 [[ True False False False]
 [False  True False False]
 [False False  True False]
 [False False False  True]],
       fill_value = 1e+20)

下一步是在单位速度向量和单位偏移矢量之间取点乘积。那就是我卡住的地方。

velocity
Out[239]: 
array([[ 1.08980931,  1.10142992],
       [ 1.42378512,  1.31445528],
       [ 1.4599431 ,  1.34567875],
       [ 1.45934809,  1.03997269]])
pp.normalize(velocity)
Out[242]: 
array([[ 0.70334695,  0.71084672],
       [ 0.73475404,  0.67833363],
       [ 0.73529551,  0.67774665],
       [ 0.81437139,  0.58034407]])

下一步?我无法弄清楚如何以numpy使其看起来像魔术的方式索引向量来完成所有操作。

谢谢@kazemakase,回答我的脸……试图寻找过度复杂的。

import numpy as np
import sklearn.preprocessing as pp
import numpy.ma as ma
n = 4 # number of particles
dim = 2 # x and y coords
pos = np.random.randint(0,9,(n,2))
vel = np.random.randint(0,9,(n,2))
vel_unit = pp.normalize(vel)
dx = np.subtract.outer(pos[:,0], pos[:,0])
dy = np.subtract.outer(pos[:,1], pos[:,1])
distance = np.hypot(dx, dy).round()
m = ma.masked_where(distance==0, distance)
o_unit_x = dx/m
o_unit_y = dy/m
angles = o_unit_y * vel_unit[:,1] + o_unit_x * vel_unit[:,0]

只需要测试正确的事情,它正在做我认为的事情。

样本输出:

pos
Out[154]: 
array([[6, 1],
       [5, 7],
       [0, 7],
       [5, 2]])
vel
Out[155]: 
array([[6, 3],
       [7, 5],
       [5, 4],
       [2, 2]])
distance
Out[156]: 
array([[ 0.,  6.,  8.,  1.],
       [ 6.,  0.,  5.,  5.],
       [ 8.,  5.,  0.,  7.],
       [ 1.,  5.,  7.,  0.]])
angles.round(3)
Out[158]: 
masked_array(data =
 [[-- -0.446 0.117 0.0]
 [0.298 -- 0.781 0.707]
 [-0.335 -0.814 -- 0.0]
 [-0.447 -0.581 0.112 --]],
             mask =
 [[ True False False False]
 [False  True False False]
 [False False  True False]
 [False False False  True]],
       fill_value = 1e+20)

最新更新