鉴于两个矩阵
A: m * r
B: n * r
Run Code Online (Sandbox Code Playgroud)
我想以产生另一矩阵C: m * n,每个条目C_ij是由外积计算的矩阵A_i和B_j.
例如,
A: [[1, 2],
[3, 4]]
B: [[3, 1],
[1, 2]]
Run Code Online (Sandbox Code Playgroud)
给
C: [[[3, 1], [[1 ,2],
[6, 2]], [2 ,4]],
[9, 3], [[3, 6],
[12,4]], [4, 8]]]
Run Code Online (Sandbox Code Playgroud)
我可以使用for循环来做,比如
for i in range (A.shape(0)):
for j in range (B.shape(0)):
C_ij = np.outer(A_i, B_j)
Run Code Online (Sandbox Code Playgroud)
我想知道是否有一种矢量化的方法来进行此计算以加快速度?
一般问题
假设我有一个ndarray v形状(nrow,ncols,3).我想计算outer_array形状的ndarray ,(nrow,ncols,3,3)其中包含(3)每个索引处的形状向量的所有外积(nrow,ncol).当然,这就是numpy.einsum存在的问题.现在,我尝试过的是:
outer_array = numpy.einsum("xyi,xyj->xyij",v,v.conjugate())
Run Code Online (Sandbox Code Playgroud)
现在,我不确定这是否有效:尽管outer_array具有预期形状的事实,外部产品矩阵的元素与我期望的不一致.
我认为这是由于einsum表达式中标签的选择:产品应该被总结x并y因为索引被重复,但由于我在输出表达式中重用它们,因此总和的结果是以某种方式广播的.
另一方面,如果我写:
outer_array = numpy.einsum("xyi,uvj->...ij",v,v.conjugate())
Run Code Online (Sandbox Code Playgroud)
numpy将为每对计算外部产品的所有可能组合,(x,y)并(u,v)产生一个形状阵列(ncols,nrow,ncols,nrow,3,3),其中对角线 (u,v) = (x,y)将包含所需的输出.
精确的问题
如何在einsum表示法中选择前两个索引以获得一个数组,在每个索引处x,y我得到vector的外积v而不必求助于第二个表达式?
显然编辑,这个表单似乎也有效:
outer_array = numpy.einsum("...i,...j->...ij",v,v.conjugate())
Run Code Online (Sandbox Code Playgroud)
我只能欣赏numpy广播的有用性!