LaplacianNd#
- class scipy.sparse.linalg.LaplacianNd(*args, **kwargs)[Quelle]#
Der Gitter-Laplace-Operator in
NDimensionen und seine Eigenwerte/Eigenvektoren.Konstruiert den Laplace-Operator auf einem gleichmäßigen rechteckigen Gitter in N Dimensionen und gibt seine Eigenwerte und Eigenvektoren aus. Die Laplace-Matrix
List eine quadratische, negativ definite, reell symmetrische Matrix mit vorzeichenbehafteten ganzzahligen Einträgen und ansonsten Nullen.- Parameter:
- grid_shapetuple
Ein Tupel von ganzen Zahlen der Länge
N(entsprechend der Dimension des Laplace-Operators), wobei jeder Eintrag die Größe dieser Dimension angibt. Die Laplace-Matrix ist quadratisch mit der Größenp.prod(grid_shape).- boundary_conditions{‘neumann’, ‘dirichlet’, ‘periodic’}, optional
Der Typ der Randbedingungen an den Rändern des Gitters. Gültige Werte sind
'dirichlet'oder'neumann'``(Standard) oder ``'periodic'.- dtypedtype
Numerischer Typ des Arrays. Standard ist
np.int8.
- Attribute:
Methoden
toarray()
Konstruiert ein dichtes Array aus Laplace-Daten
tosparse()
Konstruiert ein spärliches Array aus Laplace-Daten
eigenvalues(m=None)
Konstruiert ein 1D-Array der m größten (kleinsten im Betrag) Eigenwerte der Laplace-Matrix in aufsteigender Reihenfolge.
eigenvectors(m=None)
Konstruiert das Array mit Spalten, die aus den m Eigenvektoren (
float) desNd-Laplace-Operators gebildet werden, die den m geordneten Eigenwerten entsprechen... versionadded:: 1.12.0
Hinweise
Im Vergleich zur MATLAB/Octave-Implementierung [1] des 1-, 2- und 3-D-Laplace-Operators erlaubt dieser Code den beliebigen N-D-Fall und die matrixfreie Callable-Option, ist aber derzeit auf reine Dirichlet-, Neumann- oder Periodische Randbedingungen beschränkt.
Die Laplace-Matrix eines Graphen (
scipy.sparse.csgraph.laplacian) eines rechteckigen Gitters entspricht dem negativen Laplace-Operator mit Neumann-Bedingungen, d.h.boundary_conditions = 'neumann'.Alle Eigenwerte und Eigenvektoren des diskreten Laplace-Operators für ein
N-dimensionales reguläres Gitter der Form grid_shape mit dem Gitter-Schrittweiteh=1sind analytisch bekannt [2].Referenzen
[1][2]„Eigenwerte und Eigenvektoren der zweiten Ableitung“, Wikipedia https://en.wikipedia.org/wiki/Eigenvalues_and_eigenvectors_of_the_second_derivative
Beispiele
>>> import numpy as np >>> from scipy.sparse.linalg import LaplacianNd >>> from scipy.sparse import diags_array, csgraph >>> from scipy.linalg import eigvalsh
Der eindimensionale Laplace-Operator, der im Folgenden für reine Neumann-Randbedingungen auf einem regulären Gitter mit
n=6Gitterpunkten demonstriert wird, ist genau der negative Graph-Laplace-Operator für den ungerichteten linearen Graphen mitnKnoten unter Verwendung der spärlichen AdjazenzmatrixG, die durch die berühmte tridiagonale Matrix dargestellt wird.>>> n = 6 >>> G = diags_array(np.ones(n - 1), offsets=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
Da alle Matrixeinträge des Laplace-Operators ganze Zahlen sind, ist
'int8'der Standard-Datentyp für die Speicherung von Matrixdarstellungen.>>> 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
Es können beliebig viele extreme Eigenwerte und/oder Eigenvektoren berechnet werden.
>>> 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]])
Der zweidimensionale Laplace-Operator wird auf einem regulären Gitter mit
grid_shape = (2, 3)Punkten in jeder Dimension illustriert.>>> grid_shape = (2, 3) >>> n = np.prod(grid_shape)
Die Nummerierung der Gitterpunkte erfolgt wie folgt:
>>> np.arange(n).reshape(grid_shape + (-1,)) array([[[0], [1], [2]], [[3], [4], [5]]])
Jede der Randbedingungen
'dirichlet','periodic'und'neumann'wird separat illustriert; mit'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
mit
'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
und mit
'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