§
    &�’jñ‰  ã                   ó¾   — d dl Zd dlmZ d dlmZmZmZ dgZ G d„ de¦  «        Z	 G d„ de¦  «        Z
 G d„ d	e¦  «        Z G d
„ de¦  «        Z G d„ d¦  «        ZdS )é    N)ÚLinearOperator)ÚkronÚ	eye_arrayÚ	dia_arrayÚLaplacianNdc                   óz   ‡ — e Zd ZdZdej        dœˆ fd„
Zd„ Zdd„Zd„ Z	d	„ Z
dd
„Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zˆ xZS )r   ay"  
    The grid Laplacian in ``N`` dimensions and its eigenvalues/eigenvectors.

    Construct Laplacian on a uniform rectangular grid in `N` dimensions
    and output its eigenvalues and eigenvectors.
    The Laplacian ``L`` is square, negative definite, real symmetric array
    with signed integer entries and zeros otherwise.

    Parameters
    ----------
    grid_shape : tuple
        A tuple of integers of length ``N`` (corresponding to the dimension of
        the Lapacian), where each entry gives the size of that dimension. The
        Laplacian matrix is square of the size ``np.prod(grid_shape)``.
    boundary_conditions : {'neumann', 'dirichlet', 'periodic'}, optional
        The type of the boundary conditions on the boundaries of the grid.
        Valid values are ``'dirichlet'`` or ``'neumann'``(default) or
        ``'periodic'``.
    dtype : dtype
        Numerical type of the array. Default is ``np.int8``.

    Methods
    -------
    toarray()
        Construct a dense array from Laplacian data
    tosparse()
        Construct a sparse array from Laplacian data
    eigenvalues(m=None)
        Construct a 1D array of `m` largest (smallest in absolute value)
        eigenvalues of the Laplacian matrix in ascending order.
    eigenvectors(m=None):
        Construct the array with columns made of `m` eigenvectors (``float``)
        of the ``Nd`` Laplacian corresponding to the `m` ordered eigenvalues.

    .. versionadded:: 1.12.0

    Notes
    -----
    Compared to the MATLAB/Octave implementation [1] of 1-, 2-, and 3-D
    Laplacian, this code allows the arbitrary N-D case and the matrix-free
    callable option, but is currently limited to pure Dirichlet, Neumann or
    Periodic boundary conditions only.

    The Laplacian matrix of a graph (`scipy.sparse.csgraph.laplacian`) of a
    rectangular grid corresponds to the negative Laplacian with the Neumann
    conditions, i.e., ``boundary_conditions = 'neumann'``.

    All eigenvalues and eigenvectors of the discrete Laplacian operator for
    an ``N``-dimensional  regular grid of shape `grid_shape` with the grid
    step size ``h=1`` are analytically known [2].

    References
    ----------
    .. [1] https://github.com/lobpcg/blopex/blob/master/blopex_tools/matlab/laplacian/laplacian.m
    .. [2] "Eigenvalues and eigenvectors of the second derivative", Wikipedia
           https://en.wikipedia.org/wiki/Eigenvalues_and_eigenvectors_of_the_second_derivative

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.sparse.linalg import LaplacianNd
    >>> from scipy.sparse import diags_array, csgraph
    >>> from scipy.linalg import eigvalsh

    The one-dimensional Laplacian demonstrated below for pure Neumann boundary
    conditions on a regular grid with ``n=6`` grid points is exactly the
    negative graph Laplacian for the undirected linear graph with ``n``
    vertices using the sparse adjacency matrix ``G`` represented by the
    famous tri-diagonal matrix:

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

    Since all matrix entries of the Laplacian are integers, ``'int8'`` is
    the default dtype for storing matrix representations.

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

    Any number of extreme eigenvalues and/or eigenvectors can be computed.

    >>> 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.28867513,  0.40824829],
           [ 0.57735027,  0.40824829],
           [ 0.28867513,  0.40824829],
           [-0.28867513,  0.40824829],
           [-0.57735027,  0.40824829],
           [-0.28867513,  0.40824829]])
    >>> lap.eigenvectors()
    array([[ 0.40824829,  0.5       ,  0.28867513,  0.28867513,  0.5       ,
             0.40824829],
           [-0.40824829,  0.        , -0.57735027,  0.57735027,  0.        ,
             0.40824829],
           [ 0.40824829, -0.5       ,  0.28867513,  0.28867513, -0.5       ,
             0.40824829],
           [-0.40824829,  0.5       ,  0.28867513, -0.28867513, -0.5       ,
             0.40824829],
           [ 0.40824829,  0.        , -0.57735027, -0.57735027,  0.        ,
             0.40824829],
           [-0.40824829, -0.5       ,  0.28867513, -0.28867513,  0.5       ,
             0.40824829]])

    The two-dimensional Laplacian is illustrated on a regular grid with
    ``grid_shape = (2, 3)`` points in each dimension.

    >>> grid_shape = (2, 3)
    >>> n = np.prod(grid_shape)

    Numeration of grid points is as follows:

    >>> np.arange(n).reshape(grid_shape + (-1,))
    array([[[0],
            [1],
            [2]],
    <BLANKLINE>
           [[3],
            [4],
            [5]]])

    Each of the boundary conditions ``'dirichlet'``, ``'periodic'``, and
    ``'neumann'`` is illustrated separately; with ``'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

    with ``'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

    and with ``'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

    Úneumann)Úboundary_conditionsÚdtypec                óÄ   •— |dvrt          d|›d�¦  «        ‚|| _        || _        t          j        |¦  «        }t          ¦   «                              |||f¬¦  «         d S )N)Ú	dirichletr	   ÚperiodiczUnknown value zv is given for 'boundary_conditions' parameter. The valid options are 'dirichlet', 'periodic', and 'neumann' (default).)r   Úshape)Ú
ValueErrorÚ
grid_shaper
   ÚnpÚprodÚsuperÚ__init__)Úselfr   r
   r   ÚNÚ	__class__s        €úXC:\Projects\DSCons\.venv\Lib\site-packages\scipy\sparse\linalg\_special_sparse_arrays.pyr   zLaplacianNd.__init__õ   s…   ø€ ð Ð&JÐJÐJÝðDÐ!4ð Dð Dð Dñô ð ð %ˆŒØ#6ˆÔ åŒG�JÑÔˆÝ‰Œ×Ò˜u¨Q°¨FÐÑ3Ô3Ð3Ð3Ð3ó    c           
      ód  — | j         }|€)t          j        |¦  «        }t          j        |¦  «        }nZt	          |t          t          j        |¦  «        |z  ¦  «        ¦  «        }t          j        |¦  «        }t          j        |¦  «        }t          ||¦  «        D ]È\  }}| j        dk    r7|dt          j	        t          j
        |dz   z  d|dz   z  z  ¦  «        dz  z  z  }ŒG| j        dk    r1|dt          j	        t          j
        |z  d|z  z  ¦  «        dz  z  z  }Œƒ|dt          j	        t          j
        t          j        |dz   dz  ¦  «        z  |z  ¦  «        dz  z  z  }ŒÉ|                     ¦   «         }t          j        |¦  «        }	||	         }
|�|
| d…         }
|	| d…         }	|
|	fS )z‘Compute `m` largest eigenvalues in each of the ``N`` directions,
        i.e., up to ``m * N`` total, order them and return `m` largest.
        Nr   éüÿÿÿé   é   r	   )r   r   ÚindicesÚzerosÚminÚtupleÚ	ones_likeÚzipr
   ÚsinÚpiÚfloorÚravelÚargsort)r   Úmr   r   ÚLeigÚgrid_shape_minÚjÚnÚ
Leig_ravelÚindÚeigenvaluess              r   Ú_eigenvalue_orderingz LaplacianNd._eigenvalue_ordering  s®  € ð ”_ˆ
Øˆ9Ý”j Ñ,Ô,ˆGÝ”8˜JÑ'Ô'ˆDˆDå  Ý!&¥r¤|°JÑ'?Ô'?À!Ñ'CÑ!DÔ!DñFô FˆNå”j Ñ0Ô0ˆGÝ”8˜NÑ+Ô+ˆDå˜ Ñ,Ô,ð 	Lð 	L‰DˆAˆqØÔ'¨;Ò6Ð6Ø˜�RœV¥B¤E¨Q°©U¡O°q¸AÀ¹E±{Ñ$CÑDÔDÈÑIÑIÑI��ØÔ)¨YÒ6Ð6Ø˜�RœV¥B¤E¨A¡I°°Q±Ñ$7Ñ8Ô8¸AÑ=Ñ=Ñ=��à˜�RœV¥B¤E­B¬H°a¸!±e¸q±[Ñ,AÔ,AÑ$AÀAÑ$EÑFÔFÈ!ÑKÑKÑK��à—Z’Z‘\”\ˆ
ÝŒj˜Ñ$Ô$ˆØ  ”oˆØˆ=Ø% q b c cÔ*ˆKØ�q�b�c�c”(ˆCà˜CÐÐr   Nc                 ó6   — |                       |¦  «        \  }}|S )aŽ  Return the requested number of eigenvalues.

        Parameters
        ----------
        m : int, optional
            The positive number of smallest eigenvalues to return.
            If not provided, then all eigenvalues will be returned.

        Returns
        -------
        eigenvalues : float array
            The requested `m` smallest or all eigenvalues, in ascending order.
        )r2   )r   r*   r1   Ú_s       r   r1   zLaplacianNd.eigenvalues%  s!   € ð ×2Ò2°1Ñ5Ô5‰ˆ�QØÐr   c                 ó–  — | j         dk    rat          j        t          j        |¦  «        dz   z  |dz   z  }t          j        d|dz   z  ¦  «        t          j        ||dz   z  ¦  «        z  }�n | j         dk    r`t          j        t          j        |¦  «        dz   z  |z  }t          j        |dk    rdnd|z  ¦  «        t          j        ||z  ¦  «        z  }�n5|dk    r.t          j        d|z  ¦  «        t          j        |¦  «        z  }�n|dz   |k    r<|dz  dk    r3t          j        d|z  ¦  «        t          j        dd	g|dz  ¦  «        z  }n¼|dz   dz  dk    rZt          j        t          j        |¦  «        dz   z  |z  }t          j        d|z  ¦  «        t          j        ||dz   z  ¦  «        z  }nVt          j        t          j        |¦  «        dz   z  |z  }t          j        d|z  ¦  «        t          j        ||z  ¦  «        z  }d
|t          j	        |¦  «        t          j
        t          j        ¦  «        j        k     <   |S )ziReturn 1 eigenvector in 1d with index `j`
        and number of grid points `n` where ``j < n``.
        r   r   g       @ç      ð?r	   ç      à?r   r   éÿÿÿÿg        )r
   r   r&   ÚarangeÚsqrtr%   ÚcosÚonesÚtileÚabsÚfinfoÚfloat64Úeps)r   r-   r.   ÚiÚevs        r   Ú_ev1dzLaplacianNd._ev1d6  sù  € ð Ô# {Ò2Ð2Ý”�œ 1™œ¨Ñ)Ñ*¨a°!©eÑ4ˆAÝ”˜˜q 2™v™Ñ'Ô'­"¬&°°a¸!±e±Ñ*=Ô*=Ñ=ˆB‰BØÔ%¨Ò2Ð2Ý”�œ 1™œ¨Ñ+Ñ,¨qÑ0ˆAÝ”  Q¢ ˜"˜"¨B°!Ñ3Ñ4Ô4µr´v¸aÀ!¹e±}´}ÑDˆB‰Bà�AŠvˆvÝ”W˜R !™V‘_”_¥r¤w¨q¡z¤zÑ1�‘Ø�Q‘˜!’�  A¡¨¢
 
Ý”W˜R !™V‘_”_¥r¤w°°2¨w¸¸1¹Ñ'=Ô'=Ñ=��Ø�a‘%˜1‘ Ò!Ð!Ý”E�RœY q™\œ\¨CÑ/Ñ0°1Ñ4�Ý”W˜R !™V‘_”_¥r¤v¨a°1°q±5©kÑ':Ô':Ñ:��å”E�RœY q™\œ\¨CÑ/Ñ0°1Ñ4�Ý”W˜R !™V‘_”_¥r¤v¨a°!©e¡}¤}Ñ4�ð 57ˆ�2Œ6�"‰:Œ:�œ¥¤Ñ,Ô,Ô0Ò0Ñ1Øˆ	r   c                 óê   ‡ — ˆ fd„t          |‰ j        ¦  «        D ¦   «         }|d         }|dd…         D ]}t          j        ||d¬¦  «        }Œt          j        |¦  «                             ¦   «         S )zzReturn 1 eigenvector in Nd with multi-index `j`
        as a tensor product of the corresponding 1d eigenvectors.
        c                 óB   •— g | ]\  }}‰                      ||¦  «        ‘ŒS © )rD   )Ú.0r-   r.   r   s      €r   ú
<listcomp>z(LaplacianNd._one_eve.<locals>.<listcomp>T  s+   ø€ ÐDÐDÐD¡D A qˆt�zŠz˜!˜QÑÔÐDÐDÐDr   r   r   N)Úaxes)r$   r   r   Ú	tensordotÚasarrayr(   )r   ÚkÚphiÚresults   `   r   Ú_one_evezLaplacianNd._one_eveP  s   ø€ ð EÐDÐDÐD­C°°4´?Ñ,CÔ,CÐDÑDÔDˆØ�Q”ˆØ�q�r�r”7ð 	7ð 	7ˆCÝ”\ &¨#°AÐ6Ñ6Ô6ˆFˆFÝŒz˜&Ñ!Ô!×'Ò'Ñ)Ô)Ð)r   c                 óT  ‡ — ‰                       |¦  «        \  }}|€‰ j        }n<t          ‰ j        t          t	          j        ‰ j        ¦  «        |z  ¦  «        ¦  «        }t	          j        ||¦  «        }d„ t          |Ž D ¦   «         }ˆ fd„|D ¦   «         }t	          j        |¦  «        S )añ  Return the requested number of eigenvectors for ordered eigenvalues.

        Parameters
        ----------
        m : int, optional
            The positive number of eigenvectors to return. If not provided,
            then all eigenvectors will be returned.

        Returns
        -------
        eigenvectors : float array
            An array with columns made of the requested `m` or all eigenvectors.
            The columns are ordered according to the `m` ordered eigenvalues.
        Nc                 ó,   — g | ]}t          |¦  «        ‘ŒS rG   )r"   ©rH   Úxs     r   rI   z,LaplacianNd.eigenvectors.<locals>.<listcomp>q  s   € Ð7Ð7Ð7 !•U˜1‘X”XÐ7Ð7Ð7r   c                 ó:   •— g | ]}‰                      |¦  «        ‘ŒS rG   )rP   )rH   rM   r   s     €r   rI   z,LaplacianNd.eigenvectors.<locals>.<listcomp>r  s%   ø€ ÐAÐAÐA°!˜TŸ]š]¨1Ñ-Ô-ÐAÐAÐAr   )	r2   r   r!   r"   r   r#   Úunravel_indexr$   Úcolumn_stack)r   r*   r4   r0   r,   Ú	N_indicesÚeigenvectors_lists   `      r   ÚeigenvectorszLaplacianNd.eigenvectorsZ  s±   ø€ ð ×*Ò*¨1Ñ-Ô-‰ˆˆ3Øˆ9Ø!œ_ˆNˆNå  ¤Ý %¥b¤l°4´?Ñ&CÔ&CÀaÑ&GÑ HÔ HñJô JˆNõ Ô$ S¨.Ñ9Ô9ˆ	Ø7Ð7¥s¨I Ð7Ñ7Ô7ˆ	ØAÐAÐAÐA°yÐAÑAÔAÐÝŒÐ0Ñ1Ô1Ð1r   c           
      ó  — | j         }t          j        |¦  «        }t          j        ||gt          j        ¬¦  «        }t          j        |¦  «        }t          j        |¦  «        }t          |¦  «        D �]ð\  }}d|dd…<   dt          j        d|d|…d|…f         ¦  «        dd…<   dt          j        d|d|dz
  …d|…f         ¦  «        dd…<   dt          j        d|d|…d|dz
  …f         ¦  «        dd…<   | j        dk    rd|d	<   d||dz
  |dz
  f<   nL| j        d
k    rA|dk    r+|d|dz
  fxx         dz  cc<   ||dz
  dfxx         dz  cc<   n|d	xx         dz  cc<   |}|dk    r]t          j        |d|…         ¦  «        }	t          d|	¦  «        D ]0}
|d|…d|…f         ||
|z  |
dz   |z  …|
|z  |
dz   |z  …f<   ||z  }Œ1|d|…d|…f         |d|…d|…f<   t          t          j        ||dz   d…         ¦  «        ¦  «        }	d|d|…d|…f<   d„ t          |	¦  «        D ¦   «         }|d|…d|…f         |                     ||	||	f¦  «        dd…|dd…|f<   ||z  }�Œò|                     | j        ¦  «        S )z¼
        Converts the Laplacian data to a dense array.

        Returns
        -------
        L : ndarray
            The shape is ``(N, N)`` where ``N = np.prod(grid_shape)``.

        ©r   r   Néþÿÿÿzii->ir   r	   r8   ©r   r   r   c                 ó   — g | ]}|‘ŒS rG   rG   rS   s     r   rI   z'LaplacianNd.toarray.<locals>.<listcomp>«  s   € Ð+Ð+Ð+˜�1Ð+Ð+Ð+r   )r   r   r   r    Úint8Ú
empty_likeÚ	enumerateÚeinsumr
   ÚrangeÚintÚreshapeÚastyper   )r   r   r.   ÚLÚL_iÚLtempr0   ÚdimÚnew_dimÚtilesr-   Úidxs               r   ÚtoarrayzLaplacianNd.toarrayu  s  € ð ”_ˆ
ÝŒG�JÑÔˆÝŒH�a˜�V¥2¤7Ð+Ñ+Ô+ˆåŒm˜AÑÔˆÝ”˜aÑ Ô ˆå! *Ñ-Ô-ð +	ñ +	‰HˆC�àˆC���‰Fð 68�BŒI�g˜s 4 C 4¨¨#¨ :œÑ/Ô/°°°Ñ2Ø;<�BŒI�g˜s 9 S¨1¡W 9¨a°¨eÐ#3Ô4Ñ5Ô5°a°a°aÑ8Ø;<�BŒI�g˜s 1 S 5¨)¨C°!©G¨)Ð#3Ô4Ñ5Ô5°a°a°aÑ8àÔ'¨9Ò4Ð4Ø��D‘	Ø(*��C˜!‘G˜S 1™WÐ$Ñ%Ð%ØÔ)¨ZÒ7Ð7Ø˜’7�7Ø˜˜3 ™7˜
�O�O”O qÑ(�O�O‘OØ˜˜a™ ˜
�O�O”O qÑ(�O�O‘O�Oà˜�I�I”I ‘N�I�I‘Ið ˆGà�QŠwˆwÝœ 
¨4¨C¨4Ô 0Ñ1Ô1�Ý˜q %™œð #ð #�AØ<?ÀÀÀÀdÀsÀdÀ
¼O�C˜˜#™˜q ™s C™i˜¨¨3©°°!±°S©y¨Ð8Ñ9Ø˜s‘N�G�Gð ),¨H¨W¨H°h°w°hÐ,>Ô(?ˆE�(�7�(˜H˜W˜HÐ$Ñ%Ý�œ 
¨3¨q©5¨6¨6Ô 2Ñ3Ô3Ñ4Ô4ˆEà&'ˆC���˜(˜7˜(Ð"Ñ#Ø+Ð+�e E™lœlÐ+Ñ+Ô+ˆCð %*¨(¨7¨(°H°W°HÐ*<Ô$=ð �KŠKØ˜%Ø˜%ð!ñô ð �!�!�S˜!˜!˜!˜S�.ñ"ð
 �‰HˆA‰Aà�xŠx˜œ
Ñ#Ô#Ð#r   c           	      óØ  — t          | j        ¦  «        }t          j        | j        ¦  «        }t	          ||ft          j        ¬¦  «        }t          |¦  «        D �]v}| j        |         }t          j        d|gt          j        ¬¦  «        }|ddd…fxx         dz  cc<   | j        dk    r
d|d<   d|d	<   t	          |g d
¢f||ft          j        ¬¦  «        }| j        dk    rYt	          ||ft          j        ¬¦  «        }| 	                    dg| dz   ¬¦  «         | 	                    dg|dz
  ¬¦  «         ||z  }t          |¦  «        D ]6}	t          t          | j        |	         t          j        ¬¦  «        |¦  «        }Œ7t          |dz   |¦  «        D ]6}	t          |t          | j        |	         t          j        ¬¦  «        ¦  «        }Œ7||z  }�Œx|                     | j        ¦  «        S )a)  
        Constructs a sparse array from the Laplacian data. The returned sparse
        array format is dependent on the selected boundary conditions.

        Returns
        -------
        L : scipy.sparse.sparray
            The shape is ``(N, N)`` where ``N = np.prod(grid_shape)``.

        r\   é   r   Nr]   r	   r8   ©r   r   )r   r8   ©r8   r   r   )r   r   r   )rM   )Úlenr   r   r   r   r`   rd   r<   r
   Úsetdiagr   r   rg   r   )
r   r   Úprh   rB   rk   Údatari   Útr-   s
             r   ÚtosparsezLaplacianNd.tosparseµ  së  € õ �”Ñ Ô ˆÝŒG�D”OÑ$Ô$ˆÝ�q˜!�f¥B¤GÐ,Ñ,Ô,ˆå�q‘”ð 	ñ 	ˆAØ”/ !Ô$ˆCÝ”7˜A˜s˜8­2¬7Ð3Ñ3Ô3ˆDØ��A�A�A�ˆJˆJŒJ˜"ÑˆJˆJ‰JàÔ'¨9Ò4Ð4Ø��T‘
Ø ��U‘å˜T : : :Ð.°s¸C°jÝ"$¤'ðñ ô ˆCð Ô'¨:Ò5Ð5Ý˜s C˜jµ´Ð8Ñ8Ô8�Ø—	’	˜1˜# #  a¡�	Ñ(Ô(Ð(Ø—	’	˜1˜#  Q¡�	Ñ'Ô'Ð'Ø�q‘�å˜1‘X”Xð Nð N�Ý�9 T¤_°QÔ%7½r¼wÐGÑGÔGÈÑMÔM��Ý˜1˜q™5 !‘_”_ð Nð N�Ý˜3¥	¨$¬/¸!Ô*<ÅBÄGÐ LÑ LÔ LÑMÔM��Ø�‰HˆA‰AØ�xŠx˜œ
Ñ#Ô#Ð#r   c           	      ó¤  — | j         }t          |¦  «        }|                     |dz   ¦  «        }d|z  |z  }t          |¦  «        D �]i}|t	          j        |d|¬¦  «        z  }|t	          j        |d|¬¦  «        z  }| j        dv �r(|t          d ¦  «        f|z  dz   t          d ¦  «        f||z
  dz
  z  z   xx         t	          j        |d|¬¦  «        t          d ¦  «        f|z  dz   t          d ¦  «        f||z
  dz
  z  z            z  cc<   |t          d ¦  «        f|z  dz   t          d ¦  «        f||z
  dz
  z  z   xx         t	          j        |d|¬¦  «        t          d ¦  «        f|z  dz   t          d ¦  «        f||z
  dz
  z  z            z  cc<   | j        dk    �r|t          d ¦  «        f|z  dz   t          d ¦  «        f||z
  dz
  z  z   xx         t	          j        |d	|¬¦  «        t          d ¦  «        f|z  dz   t          d ¦  «        f||z
  dz
  z  z            z  cc<   |t          d ¦  «        f|z  dz   t          d ¦  «        f||z
  dz
  z  z   xx         t	          j        |d	|¬¦  «        t          d ¦  «        f|z  dz   t          d ¦  «        f||z
  dz
  z  z            z  cc<   �Œk|                     d|j        d         ¦  «        S )
N)r8   r]   r   )Úaxisr8   )r	   r   )r   r	   r   )	r   rt   rf   rd   r   Úrollr
   Úslicer   )r   rT   r   r   ÚXÚYrB   s          r   Ú_matveczLaplacianNd._matvecÞ  s5  € Ø”_ˆ
Ý�
‰OŒOˆØ�IŠI�j 5Ñ(Ñ)Ô)ˆØ�‰F�Q‰JˆÝ�q‘”ð 	ñ 	ˆAØ•”˜˜A AÐ&Ñ&Ô&Ñ&ˆAØ•”˜˜B QÐ'Ñ'Ô'Ñ'ˆAØÔ'Ð+CÐCÑCØ•5˜‘;”;�. Ñ" TÑ)­U°4©[¬[¨N¸A¸a¹CÀ¹EÑ,BÑBð ð ô Ý”w˜q !¨!Ð,Ñ,Ô,Ý˜4‘[”[�N QÑ&¨Ñ-µ°t±´°À!ÀAÁ#ÀaÁ%Ñ0HÑHôñð ð ñ ð Ý˜4‘[”[�N QÑ&¨Ñ.µ%¸±+´+°À1ÀQÁ3ÀqÁ5Ñ1IÑIðð ô å”W˜Q ¨Ð+Ñ+Ô+Ý˜4‘[”[�N QÑ&¨Ñ.µ%¸±+´+°À1ÀQÁ3ÀqÁ5Ñ1IÑIôñð ð ñ ð Ô+¨yÒ8Ñ8ØÝ˜t™œ˜¨Ñ*¨TÑ1µU¸4±[´[°NÀaÈÁcÈ!ÁeÑ4LÑLðð ô åœ  A¨AÐ.Ñ.Ô.Ý˜t™œ˜¨Ñ*¨TÑ1µU¸4±[´[°NÀaÈÁcÈ!ÁeÑ4LÑLôñð ð ñ ð
 Ý˜t™œ˜¨Ñ*¨UÑ2µe¸D±k´k°^ÀqÈÁsÈ1ÁuÑ5MÑMðð ô åœ  A¨AÐ.Ñ.Ô.Ý˜t™œ˜¨Ñ*¨UÑ2µe¸D±k´k°^ÀqÈÁsÈ1ÁuÑ5MÑMôñð ð ñ ùð �yŠy˜˜QœW Rœ[Ñ)Ô)Ð)r   c                 ó,   — |                       |¦  «        S ©N©r€   ©r   rT   s     r   Ú_matmatzLaplacianNd._matmatÿ  s   € Ø�|Š|˜A‰ŒÐr   c                 ó   — | S r‚   rG   ©r   s    r   Ú_adjointzLaplacianNd._adjoint  ó   € Øˆr   c                 ó   — | S r‚   rG   r‡   s    r   Ú
_transposezLaplacianNd._transpose  r‰   r   r‚   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r`   r   r2   r1   rD   rP   rZ   ro   ry   r€   r…   rˆ   r‹   Ú__classcell__©r   s   @r   r   r   
   s  ø€ € € € € ðhð hðV &/Ø”wð4ð 4ð 4ð 4ð 4ð 4ð 4ð" ð  ð  ð>ð ð ð ð"ð ð ð4*ð *ð *ð2ð 2ð 2ð 2ð6>$ð >$ð >$ð@'$ð '$ð '$ðR*ð *ð *ðBð ð ðð ð ðð ð ð ð ð ð r   c                   ób   ‡ — e Zd ZdZej        fˆ fd„	Zdd„Zd„ Zd„ Z	d„ Z
d„ Zd	„ Zd
„ Zd„ Zˆ xZS )ÚSakuraiaˆ  
    Construct a Sakurai matrix in various formats and its eigenvalues.

    Constructs the "Sakurai" matrix motivated by reference [1]_:
    square real symmetric positive definite and 5-diagonal
    with the main diagonal ``[5, 6, 6, ..., 6, 6, 5], the ``+1`` and ``-1``
    diagonals filled with ``-4``, and the ``+2`` and ``-2`` diagonals
    made of ``1``. Its eigenvalues are analytically known to be
    ``16. * np.power(np.cos(0.5 * k * np.pi / (n + 1)), 4)``.
    The matrix gets ill-conditioned with its size growing.
    It is useful for testing and benchmarking sparse eigenvalue solvers
    especially those taking advantage of its banded 5-diagonal structure.
    See the notes below for details.

    Parameters
    ----------
    n : int
        The size of the matrix.
    dtype : dtype
        Numerical type of the array. Default is ``np.int8``.

    Methods
    -------
    toarray()
        Construct a dense array from Laplacian data
    tosparse()
        Construct a sparse array from Laplacian data
    tobanded()
        The Sakurai matrix in the format for banded symmetric matrices,
        i.e., (3, n) ndarray with 3 upper diagonals
        placing the main diagonal at the bottom.
    eigenvalues
        All eigenvalues of the Sakurai matrix ordered ascending.

    Notes
    -----
    Reference [1]_ introduces a generalized eigenproblem for the matrix pair
    `A` and `B` where `A` is the identity so we turn it into an eigenproblem
    just for the matrix `B` that this function outputs in various formats
    together with its eigenvalues.

    .. versionadded:: 1.12.0

    References
    ----------
    .. [1] T. Sakurai, H. Tadano, Y. Inadomi, and U. Nagashima,
       "A moment-based method for large-scale generalized
       eigenvalue problems",
       Appl. Num. Anal. Comp. Math. Vol. 1 No. 2 (2004).

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.sparse.linalg._special_sparse_arrays import Sakurai
    >>> from scipy.linalg import eig_banded
    >>> n = 6
    >>> sak = Sakurai(n)

    Since all matrix entries are small integers, ``'int8'`` is
    the default dtype for storing matrix representations.

    >>> sak.toarray()
    array([[ 5, -4,  1,  0,  0,  0],
           [-4,  6, -4,  1,  0,  0],
           [ 1, -4,  6, -4,  1,  0],
           [ 0,  1, -4,  6, -4,  1],
           [ 0,  0,  1, -4,  6, -4],
           [ 0,  0,  0,  1, -4,  5]], dtype=int8)
    >>> sak.tobanded()
    array([[ 1,  1,  1,  1,  1,  1],
           [-4, -4, -4, -4, -4, -4],
           [ 5,  6,  6,  6,  6,  5]], dtype=int8)
    >>> sak.tosparse()
    <DIAgonal sparse array of dtype 'int8'
        with 24 stored elements (5 diagonals) and shape (6, 6)>
    >>> np.array_equal(sak.dot(np.eye(n)), sak.tosparse().toarray())
    True
    >>> sak.eigenvalues()
    array([0.03922866, 0.56703972, 2.41789479, 5.97822974,
           10.54287655, 14.45473055])
    >>> sak.eigenvalues(2)
    array([0.03922866, 0.56703972])

    The banded form can be used in scipy functions for banded matrices, e.g.,

    >>> e = eig_banded(sak.tobanded(), eigvals_only=True)
    >>> np.allclose(sak.eigenvalues(), e, atol= n * n * n * np.finfo(float).eps)
    True

    c                 óp   •— || _         || _        ||f}t          ¦   «                              ||¦  «         d S r‚   )r.   r   r   r   )r   r.   r   r   r   s       €r   r   zSakurai.__init__d  s:   ø€ ØˆŒØˆŒ
Ø�A�ˆÝ‰Œ×Ò˜ Ñ&Ô&Ð&Ð&Ð&r   Nc           
      ó  — |€| j         }t          j        | j         dz   |z
  | j         dz   ¦  «        }t          j        dt          j        t          j        d|z  t          j        z  | j         dz   z  ¦  «        d¦  «        z  ¦  «        S )a•  Return the requested number of eigenvalues.

        Parameters
        ----------
        m : int, optional
            The positive number of smallest eigenvalues to return.
            If not provided, then all eigenvalues will be returned.

        Returns
        -------
        eigenvalues : `np.float64` array
            The requested `m` smallest or all eigenvalues, in ascending order.
        Nr   g      0@r7   é   )r.   r   r9   ÚflipÚpowerr;   r&   )r   r*   rM   s      r   r1   zSakurai.eigenvaluesj  sq   € ð ˆ9Ø”ˆAÝŒI�d”f˜q‘j !‘m T¤V¨a¡ZÑ0Ô0ˆÝŒw�s�RœX¥b¤f¨S°1©Wµr´u©_ÀÄÈÁ
Ñ-KÑ&LÔ&LÈaÑPÔPÑPÑQÔQÐQr   c                 óX  — t           j        ddt          j        | j        dz
  | j        ¬¦  «        z  df         }dt          j        | j        | j        ¬¦  «        z  }t          j        | j        | j        ¬¦  «        }t          j        |||g¦  «                             | j        ¦  «        S )zA
        Construct the Sakurai matrix as a banded array.
        é   é   r   r\   r   )r   Úr_r<   r.   r   Úarrayrg   )r   Úd0Úd1Úd2s       r   ÚtobandedzSakurai.tobanded}  sŽ   € õ ŒU�1�a�"œ' $¤&¨1¡*°D´JÐ?Ñ?Ô?Ñ?ÀÐBÔCˆØ•"”'˜$œ&¨¬
Ð3Ñ3Ô3Ñ3ˆÝŒW�T”V 4¤:Ð.Ñ.Ô.ˆÝŒx˜˜R ˜Ñ%Ô%×,Ò,¨T¬ZÑ8Ô8Ð8r   c                 óÀ   — ddl m} |                      ¦   «         } ||d         |d         |d         |d         |d         gg d¢| j        | j        f|j        ¬¦  «        S )zB
        Construct the Sakurai matrix in a sparse format.
        r   ©Údiags_arrayr   r   )r]   r8   r   r   r   ©Úoffsetsr   r   )Úscipy.sparser¤   r¡   r.   r   )r   r¤   Úds      r   ry   zSakurai.tosparse†  s|   € ð 	-Ð,Ð,Ð,Ð,Ð,Ø�MŠM‰OŒOˆð ˆ{˜A˜aœD ! A¤$¨¨!¬¨a°¬d°A°a´DÐ9ÐCTÐCTÐCTØ"&¤&¨$¬&Ð!1¸¼ðBñ Bô Bð 	Br   c                 óN   — |                       ¦   «                              ¦   «         S r‚   ©ry   ro   r‡   s    r   ro   zSakurai.toarray‘  ó   € Ø�}Š}‰Œ×&Ò&Ñ(Ô(Ð(r   c                 óp  — |                      | j        d¦  «        }t          j        |j        | j        ¦  «        }t          j        ||¬¦  «        }d|ddd…f         z  d|ddd…f         z  z
  |ddd…f         z   |ddd…f<   d|ddd…f         z  d|d	dd…f         z  z
  |d
dd…f         z   |ddd…f<   d|dd…dd…f         z  d|dd	…dd…f         |dd…dd…f         z   z  z
  t          j        |dd
…dd…f         d¦  «        z   t          j        |dd…dd…f         d¦  «        z   |dd…dd…f<   |S )zê
        Construct matrix-free callable banded-matrix-vector multiplication by
        the Sakurai matrix without constructing or storing the matrix itself
        using the knowledge of its entries and the 5-diagonal format.
        r8   r\   rš   r   Nr–   r   r   r]   éýÿÿÿr›   )rr   r^   rq   ))r   r   r^   )rf   r.   r   Úpromote_typesr   Ú
zeros_likeÚpad)r   rT   Úresult_dtypeÚsxs       r   r€   zSakurai._matvec”  sz  € ð �IŠI�d”f˜bÑ!Ô!ˆÝÔ'¨¬°´Ñ<Ô<ˆÝŒ]˜1 LÐ1Ñ1Ô1ˆØ�q˜˜A˜A˜A˜”w‘;  Q q¨!¨!¨! t¤W¡Ñ,¨q°°A°A°A°¬wÑ6ˆˆ1ˆaˆaˆaˆ4‰Ø˜˜"˜a˜a˜a˜%œ‘L 1 q¨¨Q¨Q¨Q¨¤x¡<Ñ/°!°B¸¸¸°E´(Ñ:ˆˆ2ˆqˆqˆqˆ5‰	Ø˜A˜a ˜e Q Q Q˜hœK™¨!¨q°°"°°a°a°a°¬y¸1¸Q¸R¸RÀÀÀ¸U¼8Ñ/CÑ*DÑDÝœ˜q  "  a a a œyÐ*:Ñ;Ô;ñ<åœ˜q    Q Q Q œxÐ)9Ñ:Ô:ñ;ˆˆ1ˆbˆ5�!�!�!ˆ8‰ð ˆ	r   c                 ó,   — |                       |¦  «        S )zî
        Construct matrix-free callable matrix-matrix multiplication by
        the Sakurai matrix without constructing or storing the matrix itself
        by reusing the ``_matvec(x)`` that supports both 1D and 2D arrays ``x``.
        rƒ   r„   s     r   r…   zSakurai._matmat¤  ó   € ð �|Š|˜A‰ŒÐr   c                 ó   — | S r‚   rG   r‡   s    r   rˆ   zSakurai._adjoint¬  r‰   r   c                 ó   — | S r‚   rG   r‡   s    r   r‹   zSakurai._transpose¯  r‰   r   r‚   )rŒ   r�   rŽ   r�   r   r`   r   r1   r¡   ry   ro   r€   r…   rˆ   r‹   r�   r‘   s   @r   r“   r“   	  sÕ   ø€ € € € € ðYð Yðt !#¤ð 'ð 'ð 'ð 'ð 'ð 'ðRð Rð Rð Rð&9ð 9ð 9ð	Bð 	Bð 	Bð)ð )ð )ðð ð ð ð ð ðð ð ðð ð ð ð ð ð r   r“   c                   ó`   ‡ — e Zd ZdZej        fˆ fd„	Zd„ Zd„ Zd„ Z	d„ Z
d„ Zd„ Zd	„ Zd
„ Zˆ xZS )ÚMikotaMas  
    Construct a mass matrix in various formats of Mikota pair.

    The mass matrix `M` is square real diagonal
    positive definite with entries that are reciprocal to integers.

    Parameters
    ----------
    shape : tuple of int
        The shape of the matrix.
    dtype : dtype
        Numerical type of the array. Default is ``np.float64``.

    Methods
    -------
    toarray()
        Construct a dense array from Mikota data
    tosparse()
        Construct a sparse array from Mikota data
    tobanded()
        The format for banded symmetric matrices,
        i.e., (1, n) ndarray with the main diagonal.
    c                 óh   •— || _         || _        t          ¦   «                              ||¦  «         d S r‚   )r   r   r   r   )r   r   r   r   s      €r   r   zMikotaM.__init__Ë  s1   ø€ ØˆŒ
ØˆŒ
Ý‰Œ×Ò˜ Ñ&Ô&Ð&Ð&Ð&r   c                 ó~   — dt          j        d| j        d         dz   ¦  «        z                       | j        ¦  «        S )Nr6   r   r   )r   r9   r   rg   r   r‡   s    r   Ú_diagzMikotaM._diagÐ  s6   € ð •R”Y˜q $¤*¨Q¤-°!Ñ"3Ñ4Ô4Ñ4×<Ò<¸T¼ZÑHÔHÐHr   c                 ó*   — |                       ¦   «         S r‚   )r»   r‡   s    r   r¡   zMikotaM.tobandedÕ  s   € Ø�zŠz‰|Œ|Ðr   c                 óh   — ddl m}  ||                      ¦   «         gdg| j        | j        ¬¦  «        S )Nr   r£   r¥   )r§   r¤   r»   r   r   ©r   r¤   s     r   ry   zMikotaM.tosparseØ  sF   € Ø,Ð,Ð,Ð,Ð,Ð,Øˆ{˜DŸJšJ™LœL˜>°A°3Ø!%¤°4´:ð?ñ ?ô ?ð 	?r   c                 ó~   — t          j        |                      ¦   «         ¦  «                             | j        ¦  «        S r‚   )r   Údiagr»   rg   r   r‡   s    r   ro   zMikotaM.toarrayÝ  s*   € ÝŒw�t—z’z‘|”|Ñ$Ô$×+Ò+¨D¬JÑ7Ô7Ð7r   c                 óš   — |                      | j        d         d¦  «        }|                      ¦   «         dd…t          j        f         |z  S )zì
        Construct matrix-free callable banded-matrix-vector multiplication by
        the Mikota mass matrix without constructing or storing the matrix itself
        using the knowledge of its entries and the diagonal format.
        r   r8   N)rf   r   r»   r   Únewaxisr„   s     r   r€   zMikotaM._matvecà  s?   € ð �IŠI�d”j ”m RÑ(Ô(ˆØ�zŠz‰|Œ|˜A˜A˜A�rœz˜MÔ*¨QÑ.Ð.r   c                 ó,   — |                       |¦  «        S )zò
        Construct matrix-free callable matrix-matrix multiplication by
        the Mikota mass matrix without constructing or storing the matrix itself
        by reusing the ``_matvec(x)`` that supports both 1D and 2D arrays ``x``.
        rƒ   r„   s     r   r…   zMikotaM._matmaté  r´   r   c                 ó   — | S r‚   rG   r‡   s    r   rˆ   zMikotaM._adjointñ  r‰   r   c                 ó   — | S r‚   rG   r‡   s    r   r‹   zMikotaM._transposeô  r‰   r   )rŒ   r�   rŽ   r�   r   r@   r   r»   r¡   ry   ro   r€   r…   rˆ   r‹   r�   r‘   s   @r   r¸   r¸   ³  sÉ   ø€ € € € € ðð ð. %'¤Jð 'ð 'ð 'ð 'ð 'ð 'ð
Ið Ið Ið
ð ð ð?ð ?ð ?ð
8ð 8ð 8ð/ð /ð /ðð ð ðð ð ðð ð ð ð ð ð r   r¸   c                   óZ   ‡ — e Zd ZdZej        fˆ fd„	Zd„ Zd„ Zd„ Z	d„ Z
d„ Zd„ Zd	„ Zˆ xZS )
ÚMikotaKa¡  
    Construct a stiffness matrix in various formats of Mikota pair.

    The stiffness matrix `K` is square real tri-diagonal symmetric
    positive definite with integer entries.

    Parameters
    ----------
    shape : tuple of int
        The shape of the matrix.
    dtype : dtype
        Numerical type of the array. Default is ``np.int32``.

    Methods
    -------
    toarray()
        Construct a dense array from Mikota data
    tosparse()
        Construct a sparse array from Mikota data
    tobanded()
        The format for banded symmetric matrices,
        i.e., (2, n) ndarray with 2 upper diagonals
        placing the main diagonal at the bottom.
    c                 ó  •— || _         || _        t          ¦   «                              ||¦  «         |d         }t	          j        d|z  dz
  dd| j        ¬¦  «        | _        t	          j        |dz
  dd| j        ¬¦  «         | _        d S )Nr   r   r   r]   r\   r8   )r   r   r   r   r   r9   Ú_diag0Ú_diag1)r   r   r   r.   r   s       €r   r   zMikotaK.__init__  s�   ø€ ØˆŒ
ØˆŒ
Ý‰Œ×Ò˜ Ñ&Ô&Ð&ð �!ŒHˆÝ”i  A¡¨¡	¨1¨b¸¼
ÐCÑCÔCˆŒÝœ	 ! a¡%¨¨B°d´jÐAÑAÔAÐAˆŒˆˆr   c                 ój   — t          j        t          j        | j        dd¦  «        | j        g¦  «        S )Nrr   Úconstant)r   r�   r°   rÊ   rÉ   r‡   s    r   r¡   zMikotaK.tobanded  s)   € ÝŒx�œ ¤¨V°ZÑ@Ô@À$Ä+ÐNÑOÔOÐOr   c                 óh   — ddl m}  || j        | j        | j        gg d¢| j        | j        ¬¦  «        S )Nr   r£   rs   r¥   )r§   r¤   rÊ   rÉ   r   r   r¾   s     r   ry   zMikotaK.tosparse  sK   € Ø,Ð,Ð,Ð,Ð,Ð,Øˆ{˜DœK¨¬°d´kÐBÈJÈJÈJØ!%¤°4´:ð?ñ ?ô ?ð 	?r   c                 óN   — |                       ¦   «                              ¦   «         S r‚   rª   r‡   s    r   ro   zMikotaK.toarray#  r«   r   c                 óN  — |                      | j        d         d¦  «        }t          j        |j        | j        ¦  «        }t          j        ||¬¦  «        }| j        }| j        }|d         |ddd…f         z  |d         |ddd…f         z  z   |ddd…f<   |d         |ddd…f         z  |d         |ddd…f         z  z   |ddd…f<   |dd…df         |dd…dd…f         z  |dd…df         |dd…dd…f         z  z   |dd…df         |dd…dd…f         z  z   |dd…dd…f<   |S )zó
        Construct matrix-free callable banded-matrix-vector multiplication by
        the Mikota stiffness matrix without constructing or storing the matrix
        itself using the knowledge of its entries and the 3-diagonal format.
        r   r8   r\   Nr   r]   r   )rf   r   r   r®   r   r¯   rÊ   rÉ   )r   rT   r±   ÚkxrŸ   rž   s         r   r€   zMikotaK._matvec&  sb  € ð �IŠI�d”j ”m RÑ(Ô(ˆÝÔ'¨¬°´Ñ<Ô<ˆÝŒ]˜1 LÐ1Ñ1Ô1ˆØŒ[ˆØŒ[ˆØ�a”5˜1˜Q   ˜Tœ7‘? R¨¤U¨Q¨q°!°!°!¨t¬W¡_Ñ4ˆˆ1ˆaˆaˆaˆ4‰Ø�r”F˜Q˜r 1 1 1˜uœXÑ%¨¨2¬°°2°q°q°q°5´Ñ(9Ñ9ˆˆ2ˆqˆqˆqˆ5‰	Ø˜3˜B˜3 ˜9œ¨¨$¨B¨$°°°¨'¬
Ñ2Ø˜Q ˜U D˜[œ/¨A¨a°¨e°Q°Q°Q¨h¬KÑ7ñ8à˜Q˜R˜R ˜Xœ,¨¨1¨2¨2¨q¨q¨q¨5¬Ñ1ñ2ˆˆ1ˆbˆ5�!�!�!ˆ8‰ð ˆ	r   c                 ó,   — |                       |¦  «        S )zõ
        Construct matrix-free callable matrix-matrix multiplication by
        the Stiffness mass matrix without constructing or storing the matrix itself
        by reusing the ``_matvec(x)`` that supports both 1D and 2D arrays ``x``.
        rƒ   r„   s     r   r…   zMikotaK._matmat8  r´   r   c                 ó   — | S r‚   rG   r‡   s    r   rˆ   zMikotaK._adjoint@  r‰   r   c                 ó   — | S r‚   rG   r‡   s    r   r‹   zMikotaK._transposeC  r‰   r   )rŒ   r�   rŽ   r�   r   Úint32r   r¡   ry   ro   r€   r…   rˆ   r‹   r�   r‘   s   @r   rÇ   rÇ   ø  sÀ   ø€ € € € € ðð ð0 %'¤Hð Bð Bð Bð Bð Bð BðPð Pð Pð?ð ?ð ?ð
)ð )ð )ðð ð ð$ð ð ðð ð ðð ð ð ð ð ð r   rÇ   c                   ó.   — e Zd ZdZej        fd„Zdd„ZdS )Ú
MikotaPaira¬  
    Construct the Mikota pair of matrices in various formats and
    eigenvalues of the generalized eigenproblem with them.

    The Mikota pair of matrices [1, 2]_ models a vibration problem
    of a linear mass-spring system with the ends attached where
    the stiffness of the springs and the masses increase along
    the system length such that vibration frequencies are subsequent
    integers 1, 2, ..., `n` where `n` is the number of the masses. Thus,
    eigenvalues of the generalized eigenvalue problem for
    the matrix pair `K` and `M` where `K` is the system stiffness matrix
    and `M` is the system mass matrix are the squares of the integers,
    i.e., 1, 4, 9, ..., ``n * n``.

    The stiffness matrix `K` is square real tri-diagonal symmetric
    positive definite. The mass matrix `M` is diagonal with diagonal
    entries 1, 1/2, 1/3, ...., ``1/n``. Both matrices get
    ill-conditioned with `n` growing.

    Parameters
    ----------
    n : int
        The size of the matrices of the Mikota pair.
    dtype : dtype
        Numerical type of the array. Default is ``np.float64``.

    Attributes
    ----------
    eigenvalues : 1D ndarray, ``np.uint64``
        All eigenvalues of the Mikota pair ordered ascending.

    Methods
    -------
    MikotaK()
        A `LinearOperator` custom object for the stiffness matrix.
    MikotaM()
        A `LinearOperator` custom object for the mass matrix.

    .. versionadded:: 1.12.0

    References
    ----------
    .. [1] J. Mikota, "Frequency tuning of chain structure multibody oscillators
       to place the natural frequencies at omega1 and N-1 integer multiples
       omega2,..., omegaN", Z. Angew. Math. Mech. 81 (2001), S2, S201-S202.
       Appl. Num. Anal. Comp. Math. Vol. 1 No. 2 (2004).
    .. [2] Peter C. Muller and Metin Gurgoze,
       "Natural frequencies of a multi-degree-of-freedom vibration system",
       Proc. Appl. Math. Mech. 6, 319-320 (2006).
       http://dx.doi.org/10.1002/pamm.200610141.

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.sparse.linalg._special_sparse_arrays import MikotaPair
    >>> n = 6
    >>> mik = MikotaPair(n)
    >>> mik_k = mik.k
    >>> mik_m = mik.m
    >>> mik_k.toarray()
    array([[11., -5.,  0.,  0.,  0.,  0.],
           [-5.,  9., -4.,  0.,  0.,  0.],
           [ 0., -4.,  7., -3.,  0.,  0.],
           [ 0.,  0., -3.,  5., -2.,  0.],
           [ 0.,  0.,  0., -2.,  3., -1.],
           [ 0.,  0.,  0.,  0., -1.,  1.]])
    >>> mik_k.tobanded()
    array([[ 0., -5., -4., -3., -2., -1.],
           [11.,  9.,  7.,  5.,  3.,  1.]])
    >>> mik_m.tobanded()
    array([1.        , 0.5       , 0.33333333, 0.25      , 0.2       ,
        0.16666667])
    >>> mik_k.tosparse()
    <DIAgonal sparse array of dtype 'float64'
        with 16 stored elements (3 diagonals) and shape (6, 6)>
    >>> mik_m.tosparse()
    <DIAgonal sparse array of dtype 'float64'
        with 6 stored elements (1 diagonals) and shape (6, 6)>
    >>> np.array_equal(mik_k(np.eye(n)), mik_k.toarray())
    True
    >>> np.array_equal(mik_m(np.eye(n)), mik_m.toarray())
    True
    >>> mik.eigenvalues()
    array([ 1,  4,  9, 16, 25, 36])
    >>> mik.eigenvalues(2)
    array([ 1,  4])

    c                 ó°   — || _         || _        ||f| _        t          | j        | j        ¦  «        | _        t          | j        | j        ¦  «        | _        d S r‚   )r.   r   r   r¸   r*   rÇ   rM   )r   r.   r   s      r   r   zMikotaPair.__init__   sI   € ØˆŒØˆŒ
Ø˜�VˆŒ
Ý˜œ T¤ZÑ0Ô0ˆŒÝ˜œ T¤ZÑ0Ô0ˆŒˆˆr   Nc                 óf   — |€| j         }t          j        d|dz   t          j        ¬¦  «        }||z  S )a”  Return the requested number of eigenvalues.

        Parameters
        ----------
        m : int, optional
            The positive number of smallest eigenvalues to return.
            If not provided, then all eigenvalues will be returned.

        Returns
        -------
        eigenvalues : `np.uint64` array
            The requested `m` smallest or all eigenvalues, in ascending order.
        Nr   r\   )r.   r   r9   Úuint64)r   r*   Úarange_plus1s      r   r1   zMikotaPair.eigenvalues§  s7   € ð ˆ9Ø”ˆAÝ”y  A¨¡Eµ´Ð;Ñ;Ô;ˆØ˜lÑ*Ð*r   r‚   )rŒ   r�   rŽ   r�   r   r@   r   r1   rG   r   r   rÖ   rÖ   G  sP   € € € € € ðWð Wðp !#¤
ð 1ð 1ð 1ð 1ð+ð +ð +ð +ð +ð +r   rÖ   )Únumpyr   Úscipy.sparse.linalgr   r§   r   r   r   Ú__all__r   r“   r¸   rÇ   rÖ   rG   r   r   ú<module>rÞ      sP  ðØ Ð Ð Ð Ø .Ð .Ð .Ð .Ð .Ð .Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3àˆ/€ð
|ð |ð |ð |ð |�.ñ |ô |ð |ð~gð gð gð gð gˆnñ gô gð gðTBð Bð Bð Bð Bˆnñ Bô Bð BðJLð Lð Lð Lð Lˆnñ Lô Lð Lð^q+ð q+ð q+ð q+ð q+ñ q+ô q+ð q+ð q+ð q+r   