简体   繁体   English

numpy:广播到多个内部乘积和逆

[英]numpy: broadcasting into multiple inner products and inverses

I have arrays e , (shape q by l ) f (shape n by l ), and w (shape n by l ), and I want to create an array M where M[s,i,j] = np.sum(w[s, :] * e[i, :] * e[j, :]) , and an array F , where F[s,j] = np.sum(w[s, :] * f[s, :] * e[j, :]) . 我有数组e ,(形状ql ), f (形状nl )和w (形状nl ),我想创建一个数组M ,其中M[s,i,j] = np.sum(w[s, :] * e[i, :] * e[j, :]) F[s,j] = np.sum(w[s, :] * f[s, :] * e[j, :]) M[s,i,j] = np.sum(w[s, :] * e[i, :] * e[j, :]) F[s,j] = np.sum(w[s, :] * f[s, :] * e[j, :]) M[s,i,j] = np.sum(w[s, :] * e[i, :] * e[j, :]) F[s,j] = np.sum(w[s, :] * f[s, :] * e[j, :]) M[s,i,j] = np.sum(w[s, :] * e[i, :] * e[j, :])和数组F ,其中F[s,j] = np.sum(w[s, :] * f[s, :] * e[j, :])

Both are easy enough to do by, for instance, looping through elements of M , but I want to be more efficient (my real data has something like 1M entries of length 5k). 两者都很容易做到,例如,通过遍历M元素,但是我想提高效率(我的真实数据有1M项,长度为5k)。 For F , I can use F = np.inner(w * f, e) (which I verified produces the same answer as the loop). 对于F ,我可以使用F = np.inner(w * f, e) (我验证了产生与循环相同的答案)。 M is more difficult, so the first step is to loop through dimension zero of with a list comprehension, saying that M = np.stack([np.inner(r[:] * e, e) for r in w]) (I have verified this also works the same as the loop). M较为困难,因此第一步是使用列表理解力遍历维度的零,即M = np.stack([np.inner(r[:] * e, e) for r in w]) (我已验证这也与循环相同)。 np.inner() doesn't take any axes arguments, so it's not clear to me how to tell the arrays to just broadcast over all rows of w . np.inner()不带任何轴参数,因此我不清楚如何告诉数组仅在w所有行上广播。

Finally, I need to use elements of M and F to create a matrix A , where A[s,i] = np.sum(np.linalg.inv(M[s, :, :])[i, :] * F[i, :]) . 最后,我需要使用MF元素来创建矩阵A ,其中A[s,i] = np.sum(np.linalg.inv(M[s, :, :])[i, :] * F[i, :]) This also looks inner-product-ish, but taking lots of individual inverses is time-consuming, so is there a way to compute inverses of slices, short of looping? 这看起来也很像乘积,但是要进行大量的单个逆运算很耗时,那么有没有一种方法可以计算切片的逆运算,而无需循环?

Some test values in my arrays are as follows: 我的数组中的一些测试值如下:

e = array([[-0.9840087 , -0.17812043],
           [ 0.17812043, -0.9840087 ]])

w = array([[  1.12545297e+01,   1.48690140e+02],
           [  7.30718244e+00,   4.07840612e+02],
           [  2.62753065e+02,   2.27085711e+02],
           [  1.53045364e+01,   5.63025281e+02],
           [  8.00555079e+00,   2.16207407e+02],
           [  1.54070190e+01,   1.87213209e+06],
           [  2.71802081e+01,   1.06392902e+02],
           [  3.46300255e+01,   1.29404438e+03],
           [  7.77638140e+00,   4.18759293e+03],
           [  1.12874849e+01,   5.75023379e+02]])

f = array([[ 0.48907404,  0.06111084],
           [-0.21899297, -0.02207311],
           [ 0.58688524,  0.05156326],
           [ 0.57407751,  0.10004592],
           [ 0.94172351,  0.03895357],
           [-0.7489003 , -0.08911183],
           [-0.7043736 , -0.19014227],
           [ 0.58950925,  0.16587887],
           [-0.35557142, -0.14530267],
           [ 0.24548714,  0.03221844]])
M[s,i,j] = np.sum(w[s, :] * e[i, :] * e[j, :])

translates to 转换为

M = np.einsum('sk,ik,jk->sij',w,e,e)

and

F[s,j] = np.sum(w[s, :] * f[s, :] * e[j, :])
F = np.einsum('sk,sk,jk->sj', w, f, e)

I haven't tested these with your samples, but the translation is simple enough. 我没有用您的样本测试过这些,但是翻译非常简单。

With real large arrays you may have to break the expressions up into pieces. 对于真正的大型数组,您可能必须将表达式分解成碎片。 With 4 iteration variables the overall iteration space can be very big. 使用4个迭代变量,整个迭代空间可能会很大。 But first see if these expressions work with modest sized arrays. 但是首先要看看这些表达式是否适用于中等大小的数组。

As for 至于

A[s,i] = np.sum(np.linalg.inv(M[s, :, :])[i, :] * F[i, :])

I looks like np.linalg.inv(M) works, performing the s ixi inverses 我看起来像np.linalg.inv(M)作品,执行s ixi逆

If so then 如果是这样

 IM = np.linalg.inv(M)
 A = np.einsum('skm,ik,im->si', IM, F)

I'm guessing more here. 我想在这里更多。

Again, dimension might get too large, but try it small first. 同样,尺寸可能会太大,但请先尝试减小尺寸。

Typically linear equation solutions are recommended over direct inverses, something like 通常,建议对线性逆方程进行线性求解,例如

  A = F/M
  A = np.linalg.solve(M, F)

since you probably want A such that M@A=F (@ matrix product). 因为您可能希望A等于M@A=F (@矩阵乘积)。 But I'm kind of rusty on these matters. 但是我在这些事情上有些生疏。 Also check tensorsolve and tensorinv . 还要检查tensorsolvetensorinv

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM