scipy.sparse.linalg.

LaplacianNd#

класс scipy.sparse.linalg.LaplacianNd(*args, **kwargs)[источник]#

Сеточный лапласиан в N размерности и его собственные значения/собственные векторы.

Построение лапласиана на равномерной прямоугольной сетке в N размерности и вывести его собственные значения и собственные векторы. Лапласиан L является квадратной, отрицательно определенной, вещественной симметричной матрицей с целочисленными элементами со знаком и нулями в остальных случаях.

Параметры:
grid_shapeкортеж

Кортеж целых чисел длиной N (соответствующий размерности Лапласиана), где каждая запись указывает размер этой размерности. Матрица Лапласа квадратная размером np.prod(grid_shape).

граничные_условия{‘neumann’, ‘dirichlet’, ‘periodic’}, опционально

Тип граничных условий на границах сетки. Допустимые значения: 'dirichlet' или 'neumann'``(default) or ``'periodic'.

dtypedtype

Числовой тип массива. По умолчанию np.int8.

Атрибуты:
H

Эрмитово сопряженный.

T

Транспонировать этот линейный оператор.

Методы

toarray()

Построение плотного массива из данных Лапласа

tosparse()

Постройте разреженный массив из данных Лапласа

eigenvalues(m=None)

Создайте одномерный массив из m наибольшие (наименьшие по абсолютному значению) собственные значения матрицы Лапласа в порядке возрастания.

eigenvectors(m=None):

Построить массив со столбцами, состоящими из m собственные векторы (float) из Nd Лапласиан, соответствующий m упорядоченные собственные значения.

.. versionadded:: 1.12.0

Примечания

По сравнению с реализацией MATLAB/Octave [1] для 1-, 2- и 3-мерного оператора Лапласа, этот код позволяет произвольный N-мерный случай и опцию безматричного вызова, но в настоящее время ограничен только чистыми граничными условиями Дирихле, Неймана или Периодическими.

Матрица Лапласа графа (scipy.sparse.csgraph.laplacian) прямоугольной сетки соответствует отрицательному лапласиану с условиями Неймана, т.е., boundary_conditions = 'neumann'.

Все собственные значения и собственные векторы дискретного оператора Лапласа для N-мерная регулярная сетка формы grid_shape с шагом сетки h=1 аналитически известны [2].

Ссылки

[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_array, csgraph
>>> from scipy.linalg import eigvalsh

Одномерный лапласиан, показанный ниже для чистых граничных условий Неймана на регулярной сетке с n=6 точек сетки в точности является отрицательным лапласианом графа для ненаправленного линейного графа с n вершины с использованием разреженной матрицы смежности G представлена известной трёхдиагональной матрицей:

>>> 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

Поскольку все элементы матрицы лапласиана являются целыми числами, 'int8' является типом данных по умолчанию для хранения матричных представлений.

>>> lap.tosparse()

    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()

    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()

    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()

    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