从块构建矩阵

时间:2015-04-20 15:40:20

标签: python numpy matrix

我有一个由两个量A和B描述的对象(实际上它们可以多于两个)。对象根据A和B的值相关。特别是我知道A和B的相关矩阵。就像例子一样:

a = np.array([[1, 1, 0, 0],
              [1, 1, 0, 0],
              [0, 0, 1, 1],
              [0, 0, 1, 1]])
b = np.array([[1, 1, 0],
              [1, 1, 1],
              [0, 1, 1]])
na = a.shape[0]
nb = b.shape[0]

A:

的相关性

correlation A

因此,如果一个元素的A == 0.5而另一个元素等于A == 1.5则它们是完全相关的(红色)。否则,如果一个元素的A == 0.5且第二个项目的A == 3.5则它们是不相关的(蓝色)。

同样对于B:

correlation B

现在我想要将两个相关矩阵相乘,但我想得到一个带有两个轴的矩阵作为最终矩阵,其中新轴是原始轴的折叠版本:

def get_folded_bin(ia, ib):
    return ia * nb + ib

这里我在做什么:

result = np.swapaxes(np.tensordot(a, b, axes=0), 1, 2).reshape(na* nb, na * nb)

目视:

enter image description here

特别是这必须坚持:

for ia1 in xrange(na):
    for ia2 in xrange(na):
        for ib1 in xrange(nb):
            for ib2 in xrange(nb):
                assert(a[ia1, ia2] * b[ib1, ib2] == result[get_folded_bin(ia1, ib1), get_folded_bin(ia2, ib2)])

实际上我的问题是以一般方式用更多的数量(A,B,C,......)来做。也许在numpy中还有一个更简单的功能来做到这一点。

2 个答案:

答案 0 :(得分:0)

np.einsum可让您简化tensordot表达式:

result = np.einsum('ij,kl->ikjl',a,b).reshape(-1, na * nb)

我认为没有办法消除reshape

可能更容易推广到更多数组,但我不会在一个einsum表达式中使用过多的迭代变量。

答案 1 :(得分:0)

我想我最终找到了解决方案:

np.kron(a,b)

然后我可以用

撰写
np.kron(np.kron(a,b), c)