有没有一种有效的方法可以用numpy或scipy形成这个块矩阵?

有没有一种有效的方法可以用numpy或scipy形成这个块矩阵?,numpy,matrix,scipy,Numpy,Matrix,Scipy,A是NxN,B是NxM。它们是动力系统x=Ax+Bu的矩阵。我可以使用np.block()来传播矩阵,但我希望有一种形成矩阵的方法可以根据N的大小进行缩放。我想kronecker乘积np.kron()可能会有所帮助,但我想不出一种方法。任何建议都会有帮助,如果有人知道这个矩阵叫什么,请让我知道,谢谢 编辑:我可以执行以下操作来生成硬编码的解决方案 N = 3 A = np.random.random((N, N)) B = np.random.random((N, 1)) print("A:",

A是NxN,B是NxM。它们是动力系统x=Ax+Bu的矩阵。我可以使用np.block()来传播矩阵,但我希望有一种形成矩阵的方法可以根据N的大小进行缩放。我想kronecker乘积np.kron()可能会有所帮助,但我想不出一种方法。任何建议都会有帮助,如果有人知道这个矩阵叫什么,请让我知道,谢谢

编辑:我可以执行以下操作来生成硬编码的解决方案

N = 3
A = np.random.random((N, N))
B = np.random.random((N, 1))
print("A:", A)
print("B:", B)
np.block([ [B, np.zeros((B.shape[0], B.shape[1]*(N-1)))],
           [A@B, B, np.zeros((B.shape[0], B.shape[1]*(N-1-1)))],
           [np.linalg.matrix_power(A,N-1)@B, np.linalg.matrix_power(A,N-1-1)@B, B]
         ] )
输入:

A: [[0.35227098 0.98853832 0.42468451]
 [0.49288462 0.34457356 0.79954007]
 [0.52171255 0.63167711 0.27997043]]
B: [[0.53736681]
 [0.05086935]
 [0.42558792]]
输出:

array([[0.53736681, 0.        , 0.        ],
       [0.05086935, 0.        , 0.        ],
       [0.42558792, 0.        , 0.        ],
       [0.42032564, 0.53736681, 0.        ],
       [0.62266266, 0.05086935, 0.        ],
       [0.43163605, 0.42558792, 0.        ],
       [0.94690357, 0.42032564, 0.53736681],
       [0.76683544, 0.62266266, 0.05086935],
       [0.73345624, 0.43163605, 0.42558792]])
array([[0.53736681, 0.        , 0.        ],
       [0.05086935, 0.        , 0.        ],
       [0.42558792, 0.        , 0.        ],
       [0.42032564, 0.53736681, 0.        ],
       [0.62266266, 0.05086935, 0.        ],
       [0.43163605, 0.42558792, 0.        ],
       [0.94690357, 0.42032564, 0.53736681],
       [0.76683544, 0.62266266, 0.05086935],
       [0.73345624, 0.43163605, 0.42558792]])
我希望通过一种有效的方法来生成这样一个以N为单位的矩阵,我可以用np.block()和list来实现,但对我来说似乎效率不高

mat_list = [] 
for i in range(N): # generate row
    tmp = []
    for j in range(N): # loop through A^j*B
        if j <= i:
            tmp.append(np.linalg.matrix_power(A,i-j)@B)
    if i < N-1:
        tmp.append(np.zeros((B.shape[0], B.shape[1]*(N-1-i))))
    mat_list.append(tmp)

np.block(mat_list)
可以使用计算在整个阵列中重复出现的块矩阵:

import itertools as it

AB = list(it.accumulate(it.chain([B], it.repeat(A, N-1)), lambda x, y: y @ x))
zero = np.zeros_like(B)
result = np.block([AB[i::-1] + [zero]*(N-1-i) for i in range(N)])
可以使用计算在整个阵列中重复出现的块矩阵:

import itertools as it

AB = list(it.accumulate(it.chain([B], it.repeat(A, N-1)), lambda x, y: y @ x))
zero = np.zeros_like(B)
result = np.block([AB[i::-1] + [zero]*(N-1-i) for i in range(N)])

你的矩阵定义对我来说没有意义。你真的应该发布一个小样本的输入/输出,回顾一下,暂时忘记“高效”,专注于让一个小样本起作用。然后我们可以讨论改进。任何有意义的答案都必须对照您的基准来证明自己。@user3483203我更新了一个生成这样一个矩阵的简短示例。@hpaulj我得到了一个N=3的小示例,以及可以相对于N放大的解决方案。查看
np.block
的代码,以讨论速度替代方案。在一个列表中收集片段并进行连接(或两个)是常见的数组构造。它不如使用某种“广播”外部操作快,但这可能不适用于这里
np.tri
是使用“外部”计算的一个示例。
np.kron
使用
outer
连接
。您的矩阵定义对我来说没有意义。你真的应该发布一个小样本的输入/输出,回顾一下,暂时忘记“高效”,专注于让一个小样本起作用。然后我们可以讨论改进。任何有意义的答案都必须对照您的基准来证明自己。@user3483203我更新了一个生成这样一个矩阵的简短示例。@hpaulj我得到了一个N=3的小示例,以及可以相对于N放大的解决方案。查看
np.block
的代码,以讨论速度替代方案。在一个列表中收集片段并进行连接(或两个)是常见的数组构造。它不如使用某种“广播”外部操作快,但这可能不适用于这里
np.tri
是使用“外部”计算的一个示例。
np.kron
使用
外部
连接