使用SciPy模块构建稀疏的二维拉普拉斯矩阵

时间:2016-01-20 09:20:21

标签: python numpy scipy sparse-matrix

我需要构建如下所示的2D拉普拉斯:

2D_Laplacian

,其中

enter image description here

,我是单位矩阵。到目前为止,我已经使用diags method of scipy完成了它,但我想知道是否有一种更聪明的方法可以使用block_diag method来完成它。有没有人试图用这种方法建立2D拉普拉斯?

我目前创建此方法的方法是使用此函数:

from scipy.sparse import diags
# Defining the size of the matrix
nx = 3
ny = 3
N  = nx*ny
main_diag = [-4.0 for i in xrange(N)]
side_diag = []
for i in xrange(1,N):
    if i%4 == 0:
        side_diag.append(0)
    else:
        side_diag.append(1)
up_down_diag = [1.0 for i in xrange(N-4)]
diagonals = [main_diag,side_diag,side_diag,up_down_diag,up_down_diag]
laplacian = diags(diagonals, [0, -1, 1,nx,-nx], format="csr")
print laplacian.toarray()

2 个答案:

答案 0 :(得分:2)

我用数组替换了你对列表的使用:

import numpy as np
from scipy import sparse

nx, ny = 3, 3
N  = nx*ny
main_diag = np.ones(N)*-4.0
side_diag = np.ones(N-1)
side_diag[np.arange(1,N)%4==0] = 0
up_down_diag = np.ones(N-3)
diagonals = [main_diag,side_diag,side_diag,up_down_diag,up_down_diag]
laplacian = sparse.diags(diagonals, [0, -1, 1,nx,-nx], format="csr")
print laplacian.toarray()
制造

[[-4.  1.  0.  1.  0.  0.  0.  0.  0.]
 [ 1. -4.  1.  0.  1.  0.  0.  0.  0.]
 [ 0.  1. -4.  1.  0.  1.  0.  0.  0.]
 [ 1.  0.  1. -4.  0.  0.  1.  0.  0.]
 [ 0.  1.  0.  0. -4.  1.  0.  1.  0.]
 [ 0.  0.  1.  0.  1. -4.  1.  0.  1.]
 [ 0.  0.  0.  1.  0.  1. -4.  1.  0.]
 [ 0.  0.  0.  0.  1.  0.  1. -4.  0.]
 [ 0.  0.  0.  0.  0.  1.  0.  0. -4.]]

对角线的右侧是[1 1 1 0 1 1 1 0]模式吗?

对于像这样的小例子,它可能运行相同的速度,但是使用数组而不是列表的大尺寸应该更快 - 而且它与稀疏的基础代码更加一致。

diags这样的均匀对角线看起来相当不错。

我只使用了另一个SO问题的块格式。 https://stackoverflow.com/a/34124377/901925

coo适用于由重叠较小的基质组成的基质,例如有限元刚度。但是将对角线重新编入coo是很乏味的。

对于它的价值,sparse.diags使用dia_matrix,已将对角线列表转换为dia data矩阵。你可以看一下,但它的布局并不那么明显。要制作csr矩阵,diags会将此dia格式转换为coo,然后转换为csr。但通常你不应该担心所有这些转换。使用在您的问题中最有意义的格式,让sparse处理转换详细信息。

如果您想更多地探索块格式,您需要概述如何将问题视为块。

答案 1 :(得分:0)

N维拉普拉斯算子可以表示为一维拉普拉斯算子的Kronecker积:

import scipy.sparse as sp
def laplacian2D(N):
    diag=np.ones([N*N])
    mat=sp.spdiags([diag,-2*diag,diag],[-1,0,1],N,N)
    I=sp.eye(N)
    return sp.kron(I,mat,format='csr')+sp.kron(mat,I)

Connectivity pattern of 2D Laplacian - img