我需要构造一个特定的矩阵,其中一些元素本身就是矩阵[python]。块三对角矩阵

时间:2018-05-20 11:16:37

标签: python numpy

我有生成B和I的那部分代码:

import numpy as np
import scipy.sparse.linalg as sc

size = 10

#1. create the matrix B and I
def matrix(size):
    dx = size / (size - 1)
    B = np.identity(size ) * (-4)
    counter = 0
    sizeCounter = size
    for i in range(1, size):
        B[i, counter] = 1
        B[counter, i] = 1
        counter += 1
    B[0,:]=0
    B[:,0]=0
    B[size-1,:]=0
    B[:,size-1]=0

    I=np.identity(size)
    I[0,:]=0
    I[:,0]=0
    I[size-1,:]=0
    I[:,size-1]=0


    return B,I

我想生成一个平方(大小^ 2)x(大小^ 2)矩阵M.因此,如果大小为10,则M将为100x100。 M将在附图中显示以下表格。M matrix, size=n。我怎么能这样做?

2 个答案:

答案 0 :(得分:1)

以下是三种可能性:

首先,构建构建块:

我使用einsum来编写对角线。

>>> import numpy as np
>>> 
>>> size = 6
>>> 
>>> O, B, I = OBI = np.zeros((3, size, size))
>>> np.einsum('ii->i', I[1:-1, 1:-1])[:] = 1
>>> np.einsum('ii->i', B[1:-1, 1:-1])[:] = -4
>>> np.einsum('ii->i', B[1:-2, 2:-1])[:] = 1
>>> np.einsum('ii->i', B[2:-1, 1:-2])[:] = 1

接下来,构建容器:

我使用toeplitz构建(标量)三对角矩阵。

>>> from scipy import linalg
>>>
>>> T = np.zeros((size,), dtype=int)
>>> T[:2] = 1, 2
>>> T = linalg.toeplitz(T)

解决方案1:

使用np.block结合

>>> M1 = np.block(list(map(list, OBI[T])))

解决方案2:

使用reshape结合

>>> M2 = OBI[T].swapaxes(1, 2).reshape(size*size, size*size)

解决方案3:

使用np.kron

>>> Tm1 = np.zeros((size,))
>>> Tm1[1] = 1
>>> Tm1 = linalg.toeplitz(Tm1)
>>> 
>>> M3 = np.kron(np.identity(size,), B) + np.kron(Tm1, I)

答案 1 :(得分:0)

您可以使用np.concatenate构建矩阵矩阵的每一行。

B, I = matrix(size)
A = np.zeros((size, size))

M = []
for i in range(size):
    if i == 0:
        M.append(np.concatenate([ B, I, np.tile(A, (1, size-2)) ], axis = -1 ))
    elif i == size-1:
        M.append(np.concatenate([ np.tile(A, (1, size-2)), I, B ], axis = -1))
    else:
        M.append(np.concatenate([ np.tile(A, (1, i-1)), I, B, I, np.tile(A, (1, size-i-2))], axis = -1))
M = np.concatenate(M, axis = 0)

使用列表理解:

M = np.concatenate([
        np.concatenate([ B, I, np.tile(A, (1, size-2)) ], axis = -1 ) if i == 0 else
        np.concatenate([ np.tile(A, (1, size-2)), I, B ], axis = -1) if i == size-1
        else np.concatenate([ np.tile(A, (1, i-1)), I, B, I, np.tile(A, (1, size-i-2))], axis = -1)
        for i in range(size)], axis = 0)