【问题标题】:How do I build this block matrix in python?如何在 python 中构建这个块矩阵?
【发布时间】:2017-07-06 19:30:05
【问题描述】:

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

【问题讨论】:

标签: python numpy matrix scipy


【解决方案1】:

我们可以使用np.identity 为我们提供一个“方形”数组(两个轴的维度相同),其中包含您指定的 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.]])

【讨论】:

    【解决方案2】:

    这是一种计算 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]])
    

    【讨论】:

      【解决方案3】:

      下面是适合你的代码:

      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 替换为前四个变量的列表和 @ 987654325@ 与您最后四个变量的列表。

      【讨论】:

        猜你喜欢
        • 2019-03-23
        • 2016-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-26
        相关资源
        最近更新 更多