代码之家  ›  专栏  ›  技术社区  ›  mchaudh4

用numpy表示三对角矩阵

  •  0
  • mchaudh4  · 技术社区  · 4 月前

    我试图使用numpy解决一个与矩阵相关的数学问题,如下所示: enter image description here

    我真的发现很难用numpy来表示这种矩阵结构。我真的不想键入这些值,因为我想了解如何使用python表示这种结构。将空白处视为零。谢谢你的大力帮助。

    2 回复  |  直到 4 月前
        1
  •  1
  •   Mercury    4 月前

    矩阵必须分解成几个部分。首先,中间区域形成块对角矩阵,其中每个块是4x4 Toeplitz矩阵。

    # makes a shifted diagonal matrix
    def E(n, v, k):
        return v * np.eye(n, k=k)
    
    def toeplitz_block(n, v_list, k_list):
        return sum(E(n, v, k) for v, k in zip(v_list, k_list))
    

    然后我们可以执行以下操作:

    n = 4 # size of block
    m = 3 # how many blocks
    
    # Make block diagonal matrix A
    A = np.zeros((m, n, m, n))
    u, v = np.diag_indices(m)
    A[u, :, v, :] = toeplitz_block(n, [-1, 3, -1], [-1, 0, 1])
    A = A.reshape(m * n, m * n)
    
    print(A.astype(int))
    
    # Output:
    [[ 3 -1  0  0  0  0  0  0  0  0  0  0]
     [-1  3 -1  0  0  0  0  0  0  0  0  0]
     [ 0 -1  3 -1  0  0  0  0  0  0  0  0]
     [ 0  0 -1  3  0  0  0  0  0  0  0  0]
     [ 0  0  0  0  3 -1  0  0  0  0  0  0]
     [ 0  0  0  0 -1  3 -1  0  0  0  0  0]
     [ 0  0  0  0  0 -1  3 -1  0  0  0  0]
     [ 0  0  0  0  0  0 -1  3  0  0  0  0]
     [ 0  0  0  0  0  0  0  0  3 -1  0  0]
     [ 0  0  0  0  0  0  0  0 -1  3 -1  0]
     [ 0  0  0  0  0  0  0  0  0 -1  3 -1]
     [ 0  0  0  0  0  0  0  0  0  0 -1  3]]
    

    为了得到最终的期望矩阵,我们可以添加另一个对角线为-1的Toeplitz矩阵。

    B = A + E(n * m, -1, -4)
    print(B.astype(int))
    
    # Output:
    [[ 3 -1  0  0  0  0  0  0  0  0  0  0]
     [-1  3 -1  0  0  0  0  0  0  0  0  0]
     [ 0 -1  3 -1  0  0  0  0  0  0  0  0]
     [ 0  0 -1  3  0  0  0  0  0  0  0  0]
     [-1  0  0  0  3 -1  0  0  0  0  0  0]
     [ 0 -1  0  0 -1  3 -1  0  0  0  0  0]
     [ 0  0 -1  0  0 -1  3 -1  0  0  0  0]
     [ 0  0  0 -1  0  0 -1  3  0  0  0  0]
     [ 0  0  0  0 -1  0  0  0  3 -1  0  0]
     [ 0  0  0  0  0 -1  0  0 -1  3 -1  0]
     [ 0  0  0  0  0  0 -1  0  0 -1  3 -1]
     [ 0  0  0  0  0  0  0 -1  0  0 -1  3]]
    
        2
  •  0
  •   ThomasIsCoding    4 月前

    这是另一种选择

    n = 12
    msk = (v:=np.arange(n))-v[:,None]
    A = 3*(msk==0) - (np.logical_or(abs(msk)==1,msk==-4))
    

    这样

    A=
     [[ 3 -1  0  0  0  0  0  0  0  0  0  0]
     [-1  3 -1  0  0  0  0  0  0  0  0  0]
     [ 0 -1  3 -1  0  0  0  0  0  0  0  0]
     [ 0  0 -1  3 -1  0  0  0  0  0  0  0]
     [-1  0  0 -1  3 -1  0  0  0  0  0  0]
     [ 0 -1  0  0 -1  3 -1  0  0  0  0  0]
     [ 0  0 -1  0  0 -1  3 -1  0  0  0  0]
     [ 0  0  0 -1  0  0 -1  3 -1  0  0  0]
     [ 0  0  0  0 -1  0  0 -1  3 -1  0  0]
     [ 0  0  0  0  0 -1  0  0 -1  3 -1  0]
     [ 0  0  0  0  0  0 -1  0  0 -1  3 -1]
     [ 0  0  0  0  0  0  0 -1  0  0 -1  3]]