2017-07-06 56 views
2

我想为一个有n个点的方程组建立一个块矩阵。 结果是(2n + 2)x(2n + 2)矩阵。在例如,对于2点矩阵是:如何在python中构建这个块矩阵?

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,但是这些都没有达到我想要的。

+0

此链接可能会有所帮助:https://stackoverflow.com/questions/26506204/replace-sub-part-of-matrix-by-another-small-matrix-in-numpy –

+0

已发布的解决方案是否有效为你? – Divakar

回答

1

我们可以使用np.identity给我们用1和0一“方”阵列(在这两个轴相同的尺寸)为您指定:

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 

编辑:这是对于i选择了啊一些随机值的输出:

>>> 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.]]) 
+0

这对我有效,谢谢。 – astromonerd

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]]) 
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你最后的四个变量。