如何在python中构建这个块矩阵?

时间:2017-07-06 19:30:06

标签: python numpy matrix scipy

我想为具有n个点的等式系统构建块矩阵。 结果是(2n + 2)x(2n + 2)矩阵。例如,对于2个点,矩阵是:

1 0 0 0 0 0
a b c d 0 0
e f g h 0 0
0 0 a b c d
0 0 e f g h
0 0 0 0 0 1

对于3分,矩阵是

1 0 0 0 0 0 0 0
a b c d 0 0 0 0
e f g h 0 0 0 0
0 0 a b c d 0 0
0 0 e f g h 0 0
0 0 0 0 a b c d
0 0 0 0 e f g h
0 0 0 0 0 0 0 1

这里,a,b,c,d,e,f,g,h是提前已知的浮点值。 但我不提前知道n的价值。在python中有一个库可以做到这一点吗?我看过scipy.sparse.diag,scipy.linalg.block_diag和numpy.bat,但这些都达不到我想要的效果。

3 个答案:

答案 0 :(得分:1)

我们可以使用np.identity为我们提供一个" square"数组(两个轴的尺寸相同),指定的是1和0:

myarr = np.identity(2*n+2)

然后,我们为a-h定义了我们的小子集值:

subset = np.array([[a,b,c,d],[e,f,g,h]])

现在替换更大数组中的相应值:

for i in range(1, 2*n+2-1, 2):
    myarr[i:i+2, i-1:i+3] = subset

编辑:这是我为a-h选择的一些随机值的输出:

>>> myarr = np.identity(2*n+2)
>>> subset = np.array([[a,b,c,d],[e,f,g,h]])
>>> for i in range(1, 2*n+2-1, 2):
...     myarr[i:i+2, i-1:i+3] = subset
... 
>>> myarr
array([[  1.,   0.,   0.,   0.,   0.,   0.,   0.,   0.],
       [ 11.,   2.,   3.,   4.,   0.,   0.,   0.,   0.],
       [  5.,   6.,   7.,   9.,   0.,   0.,   0.,   0.],
       [  0.,   0.,  11.,   2.,   3.,   4.,   0.,   0.],
       [  0.,   0.,   5.,   6.,   7.,   9.,   0.,   0.],
       [  0.,   0.,   0.,   0.,  11.,   2.,   3.,   4.],
       [  0.,   0.,   0.,   0.,   5.,   6.,   7.,   9.],
       [  0.,   0.,   0.,   0.,   0.,   0.,   0.,   1.]])

答案 1 :(得分:0)

这是一种在broadcasted manner中计算这些线性指数然后分配到zeros-initialized数组中的方法 -

def block_mat(list_, n = 2):
    input_arr = np.array(list_).reshape(-1,4)
    N = 2*n + 2
    M = 2*N + 2

    p,q = input_arr.shape
    I,J,K = np.ix_(M*np.arange(n), N*np.arange(p), np.arange(q))
    idx = I + J + K + N

    out = np.zeros((N,N),dtype=input_arr.dtype)
    out.flat[idx] = input_arr
    out.flat[[0,-1]] = 1
    return out

样品运行 -

1)输入元素:

In [497]: a,b,c,d,e,f,g,h = range(3,11)

In [498]: a,b,c,d,e,f,g,h
Out[498]: (3, 4, 5, 6, 7, 8, 9, 10)

2)各种n案例:

In [499]: block_mat([a,b,c,d,e,f,g,h], n = 2)
Out[499]: 
array([[ 1,  0,  0,  0,  0,  0],
       [ 3,  4,  5,  6,  0,  0],
       [ 7,  8,  9, 10,  0,  0],
       [ 0,  0,  3,  4,  5,  6],
       [ 0,  0,  7,  8,  9, 10],
       [ 0,  0,  0,  0,  0,  1]])

In [500]: block_mat([a,b,c,d,e,f,g,h], n = 3)
Out[500]: 
array([[ 1,  0,  0,  0,  0,  0,  0,  0],
       [ 3,  4,  5,  6,  0,  0,  0,  0],
       [ 7,  8,  9, 10,  0,  0,  0,  0],
       [ 0,  0,  3,  4,  5,  6,  0,  0],
       [ 0,  0,  7,  8,  9, 10,  0,  0],
       [ 0,  0,  0,  0,  3,  4,  5,  6],
       [ 0,  0,  0,  0,  7,  8,  9, 10],
       [ 0,  0,  0,  0,  0,  0,  0,  1]])

In [501]: block_mat([a,b,c,d,e,f,g,h], n = 4)
Out[501]: 
array([[ 1,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 3,  4,  5,  6,  0,  0,  0,  0,  0,  0],
       [ 7,  8,  9, 10,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  3,  4,  5,  6,  0,  0,  0,  0],
       [ 0,  0,  7,  8,  9, 10,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  3,  4,  5,  6,  0,  0],
       [ 0,  0,  0,  0,  7,  8,  9, 10,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  3,  4,  5,  6],
       [ 0,  0,  0,  0,  0,  0,  7,  8,  9, 10],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  1]])

答案 2 :(得分:0)

以下是适合您的代码:

import string
n = 3
letters = string.ascii_lowercase
block1 = letters[:4]
block2 = letters[4:8]
matrix = [[1 if b == 0 and i == 0 or b == 2*n+1 and i == 2*n + 1 else 0 for b in range(2*n+2)] for i in range(2*n+2)]
count = 0

for i, a in enumerate(matrix[1:-1]): #fix to account for the fact that we are starting at 2, not 0

    if i%2 == 0:
        matrix[i+1][count:count+4] = list(block1)


    else:
        matrix[i+1][count:count+4] = list(block2)


        count += 2

for i in matrix:
    print i

当n == 3时的输出:

[1, 0, 0, 0, 0, 0, 0, 0]
['a', 'b', 'c', 'd', 0, 0, 0, 0]
['e', 'f', 'g', 'h', 0, 0, 0, 0]
[0, 0, 'a', 'b', 'c', 'd', 0, 0]
[0, 0, 'e', 'f', 'g', 'h', 0, 0]
[0, 0, 0, 0, 'a', 'b', 'c', 'd']
[0, 0, 0, 0, 'e', 'f', 'g', 'h']
[0, 0, 0, 0, 0, 0, 0, 1]

当n == 2时的输出:

[1, 0, 0, 0, 0, 0]
['a', 'b', 'c', 'd', 0, 0]
['e', 'f', 'g', 'h', 0, 0]
[0, 0, 'a', 'b', 'c', 'd']
[0, 0, 'e', 'f', 'g', 'h']
[0, 0, 0, 0, 0, 1]

我意识到你实际上并没有使用字符串“a”,“b”,“c”等,但是当你想使用变量时,将block1替换为前四个变量的列表和block2以及最近四个变量的列表。