Python Kronecker乘积的置换串
我正在编写的函数将接收一个矩阵H=A x B x I x I作为输入,其中每个矩阵都是正方形,尺寸为d,十字表示Kronecker乘积Python Kronecker乘积的置换串,python,numpy,matrix,Python,Numpy,Matrix,我正在编写的函数将接收一个矩阵H=A x B x I x I作为输入,其中每个矩阵都是正方形,尺寸为d,十字表示Kronecker乘积np.kron,I表示标识np.eye(d)。因此 I = np.eye(d) H = np.kron(A, B) H = np.kron(H, I) H = np.kron(H, I) 给定H和上述形式,但不知道A和B,我想构造G=I x A x I x B,例如 G = np.kron(I, A) G = np.kron(G, I) G = np.kron(
np.kron
,I表示标识np.eye(d)
。因此
I = np.eye(d)
H = np.kron(A, B)
H = np.kron(H, I)
H = np.kron(H, I)
给定H和上述形式,但不知道A和B,我想构造G=I x A x I x B,例如
G = np.kron(I, A)
G = np.kron(G, I)
G = np.kron(G, B)
应该可以通过对H应用一些置换来实现这一点。我如何实现该置换?使用(2,0,3,1,6,4,7,5)进行转置(扩展到8个轴后)似乎可以做到:
>>> from functools import reduce
>>>
>>> A = np.random.randint(0,10,(10,10))
>>> B = np.random.randint(0,10,(10,10))
>>> I = np.identity(10, int)
>>> G = reduce(np.kron, (A,B,I,I))
>>> H = reduce(np.kron, (I,A,I,B))
>>>
>>>
>>> (G.reshape(*8*(10,)).transpose(2,0,3,1,6,4,7,5).reshape(10**4,10**4) == H).all()
True
说明:让我们看一个简单的例子来了解Kronecker产品与重塑和轴洗牌的关系
两个1D因素:
>>> A, B = np.arange(1,5), np.array(list("abcd"), dtype=object)
>>> np.kron(A, B)
array(['a', 'b', 'c', 'd', 'aa', 'bb', 'cc', 'dd', 'aaa', 'bbb', 'ccc',
'ddd', 'aaaa', 'bbbb', 'cccc', 'dddd'], dtype=object)
我们可以观察到,这种排列是按行排列的,因此,如果我们重新塑形,我们实际上得到的是外积:
>>> np.kron(A, B).reshape(4, 4)
array([['a', 'b', 'c', 'd'],
['aa', 'bb', 'cc', 'dd'],
['aaa', 'bbb', 'ccc', 'ddd'],
['aaaa', 'bbbb', 'cccc', 'dddd']], dtype=object)
>>> np.outer(A, B)
array([['a', 'b', 'c', 'd'],
['aa', 'bb', 'cc', 'dd'],
['aaa', 'bbb', 'ccc', 'ddd'],
['aaaa', 'bbbb', 'cccc', 'dddd']], dtype=object)
如果我们对交换的因子进行同样的处理,我们得到了转置:
>>> np.kron(B, A).reshape(4, 4)
array([['a', 'aa', 'aaa', 'aaaa'],
['b', 'bb', 'bbb', 'bbbb'],
['c', 'cc', 'ccc', 'cccc'],
['d', 'dd', 'ddd', 'dddd']], dtype=object)
对于2D因素,情况是相似的
>>> A2, B2 = A.reshape(2,2), B.reshape(2,2)
>>>
>>> np.kron(A2, B2)
array([['a', 'b', 'aa', 'bb'],
['c', 'd', 'cc', 'dd'],
['aaa', 'bbb', 'aaaa', 'bbbb'],
['ccc', 'ddd', 'cccc', 'dddd']], dtype=object)
>>> np.kron(A2, B2).reshape(2,2,2,2)
array([[[['a', 'b'],
['aa', 'bb']],
[['c', 'd'],
['cc', 'dd']]],
[[['aaa', 'bbb'],
['aaaa', 'bbbb']],
[['ccc', 'ddd'],
['cccc', 'dddd']]]], dtype=object)
但有一个小的复杂性,即相应的外部产品具有不同的轴排列:
>>> np.multiply.outer(A2, B2)
array([[[['a', 'b'],
['c', 'd']],
[['aa', 'bb'],
['cc', 'dd']]],
[[['aaa', 'bbb'],
['ccc', 'ddd']],
[['aaaa', 'bbbb'],
['cccc', 'dddd']]]], dtype=object)
我们需要交换中间轴以获得相同的结果
>>> np.multiply.outer(A2, B2).swapaxes(1,2)
array([[[['a', 'b'],
['aa', 'bb']],
[['c', 'd'],
['cc', 'dd']]],
[[['aaa', 'bbb'],
['aaaa', 'bbbb']],
[['ccc', 'ddd'],
['cccc', 'dddd']]]], dtype=object)
因此,如果我们想要交换Kronecker产品,我们可以交换中间轴:(0,2,1,3)
现在我们有了外积。交换因子将前两个轴与后两个轴交换:(1,3,0,2)
回到克罗内克,交换中轴线
=>全轴置换:(1,0,3,2)
使用相同的原则,我们可以得出四因素原始问题的答案。这个答案扩展了保罗·潘泽的正确答案,记录了如何更普遍地解决类似问题 假设我们希望将矩阵字符串
reduce(kron,ABCD)
映射到例如reduce(kron,CADB)
,其中每个矩阵都有维度d
列。因此,这两个字符串都是d**4,d**4
矩阵。或者,它们是[d,]*8
形状的阵列
np.kron
排列数据的方式意味着ABDC
的索引顺序对应于其组成部分的索引顺序,如下所示:du0c\u0b\u0a\u0d\u1c\u1b\u1a\u1
,例如du0
(du1
)是D
中振荡最快(最慢)的索引。对于CADB
,索引顺序改为(B_0 D_0 A_0 C_0 B_1 D_1 A_1 C_1
);您只需对较快的索引向后读取字符串一次,对较慢的索引向后读取字符串一次。因此,在这种情况下,合适的排列字符串是(2,0,3,1,6,4,7,5)
您熟悉vec
操作吗?你们需要解一个线性系统,而不是一个置换。这似乎是可行的,尽管为什么它对我来说很神秘。你能解释一下你是怎么想出来的吗?
>>> np.all(np.kron(A2, B2).reshape(2,2,2,2).transpose(1,0,3,2).reshape(4,4) == np.kron(B2, A2))
True