[英]row-wise matrix multiplication using numpy
I want to implement a "row wise" matrix multiplication.我想实现“逐行”矩阵乘法。
More specifically speaking, I want to plot a set of arrows whose directions range from (-pi, pi).更具体地说,我想要 plot 一组箭头,其方向范围为(-pi,pi)。 The following code is how I implemented it.以下代码是我实现它的方式。
scan_phi = np.linspace(-np.pi*0.5, np.pi*0.5, 450)
points = np.ones((450, 2), dtype=np.float)
points[..., 0] = 0.0
n_pts = len(points)
sin = np.sin(scan_phi)
cos = np.cos(scan_phi)
rot = np.append(np.expand_dims(np.vstack([cos, -sin]).T, axis=1),
np.expand_dims(np.vstack([sin, cos]).T, axis=1),
axis=1)
points_rot = []
for idx, p in enumerate(points):
points_rot.append(np.matmul(rot[idx], p.T))
points_rot = np.array(points_rot)
sample = points_rot[::10]
ax = plt.axes()
ax.set_xlim(-2, 2)
ax.set_ylim(-2, 2)
for idx, p in enumerate(sample):
if idx == 0:
ax.arrow(0, 0, p[0], p[1], head_width=0.05, head_length=0.1, color='red')
else:
ax.arrow(0, 0, p[0], p[1], head_width=0.05, head_length=0.1, fc='k', ec='k')
plt.show()
In my code, "rot" ends up being an array of (450, 2, 2) meaning for each arrow, I have created a corresponding rotation matrix to rotate it.在我的代码中,“rot”最终成为 (450, 2, 2) 的数组,表示每个箭头,我创建了一个相应的旋转矩阵来旋转它。 I have 450 points stored in "points" (450, 2) that I want to draw arrows with.我有 450 个点存储在“点”(450, 2) 中,我想用这些点来绘制箭头。 (Here the arrows are all initialized with [0, 1]. However, it can be initialized with different values which is why I want to have 450 individual points instead of just rotating a single point by 450 different angles) (这里的箭头都是用 [0, 1] 初始化的。但是,它可以用不同的值初始化,这就是为什么我想要有 450 个单独的点,而不是仅仅将一个点旋转 450 个不同的角度)
The way I did is using a for-loop, ie for each arrow, I transform it individually.我所做的方法是使用for循环,即对于每个箭头,我单独对其进行转换。
points_rot = []
for idx, p in enumerate(points):
points_rot.append(np.matmul(rot[idx], p.T))
points_rot = np.array(points_rot)
However, I wonder if there's any nicer and easy way to do this completely through numpy, such as some operations that can perform matrix multiplication row-wise.但是,我想知道是否有更好更简单的方法可以通过 numpy 完全做到这一点,例如一些可以逐行执行矩阵乘法的操作。 Any idea will be grateful, thanks in advance!任何想法将不胜感激,在此先感谢!
This is a nice use-case for np.einsum
:这是np.einsum
的一个很好的用例:
aa = np.random.normal(size=(450, 2, 2))
bb = np.random.normal(size=(450, 2))
cc = np.einsum('ijk,ik->ij', aa, bb)
So that each row of cc
is the product of corresponding rows of aa
and bb
:因此cc
的每一行都是aa
和bb
对应行的乘积:
np.allclose(aa[3].dot(bb[3]), cc) # returns True
Explanation: the Einstein notation ijk,ik->ij
is saying:解释:爱因斯坦记法ijk,ik->ij
是说:
cc[i,j] = sum(aa[i,j,k] * bb[i,k] for k in range(2))
Ie, all variables that do not appear in the right-hand side are summed away.即,将所有未出现在右侧的变量相加。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.