LaplacianNd#
- class scipy.sparse.linalg.LaplacianNd(*args, **kwargs)[source]#
網格拉普拉斯算符在
N
維度及其特徵值/特徵向量。在 N 維度的均勻矩形網格上建構拉普拉斯算符,並輸出其特徵值和特徵向量。拉普拉斯算符
L
是方形、負定、實對稱陣列,其元素為帶符號的整數,其餘為零。- 參數:
- grid_shapetuple
長度為
N
的整數 tuple (對應於拉普拉斯算符的維度),其中每個條目給出該維度的大小。拉普拉斯矩陣是大小為np.prod(grid_shape)
的方形矩陣。- boundary_conditions{‘neumann’, ‘dirichlet’, ‘periodic’}, 選項性
網格邊界上的邊界條件類型。有效值為
'dirichlet'
或'neumann'
(預設) 或'periodic'
。- dtypedtype
陣列的數值類型。預設為
np.int8
。
註解
與 MATLAB/Octave 實作 [1] 的 1-、2- 和 3-D 拉普拉斯算符相比,此程式碼允許任意 N-D 情況和無矩陣可調用選項,但目前僅限於純 Dirichlet、Neumann 或 Periodic 邊界條件。
矩形網格的圖 (
scipy.sparse.csgraph.laplacian
) 的拉普拉斯矩陣對應於具有 Neumann 條件的負拉普拉斯算符,即boundary_conditions = 'neumann'
。對於形狀為 grid_shape 且網格步長大小為
h=1
的N
維規則網格,離散拉普拉斯算符的所有特徵值和特徵向量都是解析已知的 [2]。參考文獻
[1][2]“二階導數的特徵值和特徵向量”,維基百科 https://en.wikipedia.org/wiki/Eigenvalues_and_eigenvectors_of_the_second_derivative
範例
>>> import numpy as np >>> from scipy.sparse.linalg import LaplacianNd >>> from scipy.sparse import diags, csgraph >>> from scipy.linalg import eigvalsh
下面示範的一維拉普拉斯算符,用於具有
n=6
個網格點的規則網格上的純 Neumann 邊界條件,它正是無向線性圖的負圖拉普拉斯算符,該圖具有n
個頂點,並使用著名的三對角矩陣表示的稀疏鄰接矩陣G
>>> n = 6 >>> G = diags(np.ones(n - 1), 1, format='csr') >>> Lf = csgraph.laplacian(G, symmetrized=True, form='function') >>> grid_shape = (n, ) >>> lap = LaplacianNd(grid_shape, boundary_conditions='neumann') >>> np.array_equal(lap.matmat(np.eye(n)), -Lf(np.eye(n))) True
由於拉普拉斯算符的所有矩陣元素都是整數,因此
'int8'
是儲存矩陣表示的預設 dtype。>>> lap.tosparse() <DIAgonal sparse array of dtype 'int8' with 16 stored elements (3 diagonals) and shape (6, 6)> >>> lap.toarray() array([[-1, 1, 0, 0, 0, 0], [ 1, -2, 1, 0, 0, 0], [ 0, 1, -2, 1, 0, 0], [ 0, 0, 1, -2, 1, 0], [ 0, 0, 0, 1, -2, 1], [ 0, 0, 0, 0, 1, -1]], dtype=int8) >>> np.array_equal(lap.matmat(np.eye(n)), lap.toarray()) True >>> np.array_equal(lap.tosparse().toarray(), lap.toarray()) True
可以計算任意數量的極端特徵值和/或特徵向量。
>>> lap = LaplacianNd(grid_shape, boundary_conditions='periodic') >>> lap.eigenvalues() array([-4., -3., -3., -1., -1., 0.]) >>> lap.eigenvalues()[-2:] array([-1., 0.]) >>> lap.eigenvalues(2) array([-1., 0.]) >>> lap.eigenvectors(1) array([[0.40824829], [0.40824829], [0.40824829], [0.40824829], [0.40824829], [0.40824829]]) >>> lap.eigenvectors(2) array([[ 0.5 , 0.40824829], [ 0. , 0.40824829], [-0.5 , 0.40824829], [-0.5 , 0.40824829], [ 0. , 0.40824829], [ 0.5 , 0.40824829]]) >>> lap.eigenvectors() array([[ 0.40824829, 0.28867513, 0.28867513, 0.5 , 0.5 , 0.40824829], [-0.40824829, -0.57735027, -0.57735027, 0. , 0. , 0.40824829], [ 0.40824829, 0.28867513, 0.28867513, -0.5 , -0.5 , 0.40824829], [-0.40824829, 0.28867513, 0.28867513, -0.5 , -0.5 , 0.40824829], [ 0.40824829, -0.57735027, -0.57735027, 0. , 0. , 0.40824829], [-0.40824829, 0.28867513, 0.28867513, 0.5 , 0.5 , 0.40824829]])
二維拉普拉斯算符在規則網格上示範,其中
grid_shape = (2, 3)
,每個維度中有點。>>> grid_shape = (2, 3) >>> n = np.prod(grid_shape)
網格點的編號如下
>>> np.arange(n).reshape(grid_shape + (-1,)) array([[[0], [1], [2]], [[3], [4], [5]]])
每個邊界條件
'dirichlet'
、'periodic'
和'neumann'
分別說明;使用'dirichlet'
>>> lap = LaplacianNd(grid_shape, boundary_conditions='dirichlet') >>> lap.tosparse() <Compressed Sparse Row sparse array of dtype 'int8' with 20 stored elements and shape (6, 6)> >>> lap.toarray() array([[-4, 1, 0, 1, 0, 0], [ 1, -4, 1, 0, 1, 0], [ 0, 1, -4, 0, 0, 1], [ 1, 0, 0, -4, 1, 0], [ 0, 1, 0, 1, -4, 1], [ 0, 0, 1, 0, 1, -4]], dtype=int8) >>> np.array_equal(lap.matmat(np.eye(n)), lap.toarray()) True >>> np.array_equal(lap.tosparse().toarray(), lap.toarray()) True >>> lap.eigenvalues() array([-6.41421356, -5. , -4.41421356, -3.58578644, -3. , -1.58578644]) >>> eigvals = eigvalsh(lap.toarray().astype(np.float64)) >>> np.allclose(lap.eigenvalues(), eigvals) True >>> np.allclose(lap.toarray() @ lap.eigenvectors(), ... lap.eigenvectors() @ np.diag(lap.eigenvalues())) True
使用
'periodic'
>>> lap = LaplacianNd(grid_shape, boundary_conditions='periodic') >>> lap.tosparse() <Compressed Sparse Row sparse array of dtype 'int8' with 24 stored elements and shape (6, 6)> >>> lap.toarray() array([[-4, 1, 1, 2, 0, 0], [ 1, -4, 1, 0, 2, 0], [ 1, 1, -4, 0, 0, 2], [ 2, 0, 0, -4, 1, 1], [ 0, 2, 0, 1, -4, 1], [ 0, 0, 2, 1, 1, -4]], dtype=int8) >>> np.array_equal(lap.matmat(np.eye(n)), lap.toarray()) True >>> np.array_equal(lap.tosparse().toarray(), lap.toarray()) True >>> lap.eigenvalues() array([-7., -7., -4., -3., -3., 0.]) >>> eigvals = eigvalsh(lap.toarray().astype(np.float64)) >>> np.allclose(lap.eigenvalues(), eigvals) True >>> np.allclose(lap.toarray() @ lap.eigenvectors(), ... lap.eigenvectors() @ np.diag(lap.eigenvalues())) True
使用
'neumann'
>>> lap = LaplacianNd(grid_shape, boundary_conditions='neumann') >>> lap.tosparse() <Compressed Sparse Row sparse array of dtype 'int8' with 20 stored elements and shape (6, 6)> >>> lap.toarray() array([[-2, 1, 0, 1, 0, 0], [ 1, -3, 1, 0, 1, 0], [ 0, 1, -2, 0, 0, 1], [ 1, 0, 0, -2, 1, 0], [ 0, 1, 0, 1, -3, 1], [ 0, 0, 1, 0, 1, -2]], dtype=int8) >>> np.array_equal(lap.matmat(np.eye(n)), lap.toarray()) True >>> np.array_equal(lap.tosparse().toarray(), lap.toarray()) True >>> lap.eigenvalues() array([-5., -3., -3., -2., -1., 0.]) >>> eigvals = eigvalsh(lap.toarray().astype(np.float64)) >>> np.allclose(lap.eigenvalues(), eigvals) True >>> np.allclose(lap.toarray() @ lap.eigenvectors(), ... lap.eigenvectors() @ np.diag(lap.eigenvalues())) True
方法
toarray()
從拉普拉斯資料建構密集陣列
tosparse()
從拉普拉斯資料建構稀疏陣列
eigenvalues(m=None)
建構一個 1D 陣列,其中包含 m 個拉普拉斯矩陣的最大 (絕對值最小) 特徵值,並按升序排列。
eigenvectors(m=None)
建構陣列,其列由 m 個特徵向量 (
float
) 組成,這些特徵向量對應於 m 個已排序的特徵值的Nd
拉普拉斯算符。.. versionadded:: 1.12.0