Ë
    âQ(h±…  ã                   óž   — 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y)é    N)ÚLinearOperator)ÚkronÚeyeÚ	dia_arrayÚLaplacianNdc                   ó„   ‡ — 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   ai"  
    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, 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(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

    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.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]])

    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¬«       y )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        €úh/var/www/skyplay_api_hub/venv/lib/python3.12/site-packages/scipy/sparse/linalg/_special_sparse_arrays.pyr   zLaplacianNd.__init__õ   se   ø€ ð Ð&JÑJÜØ Ð!4Ð 7ð 8Dð Dóð ð %ˆŒØ#6ˆÔ ä�G‰G�JÓˆÜ‰Ñ˜u¨Q°¨FÐÕ3ó    c           
      ót  — | j                   }|€+t        j                  |«      }t        j                  |«      }nUt	        |t        t        j                  |«      |z  «      «      }t        j                  |«      }t        j                  |«      }t        ||«      D ]à  \  }}| j                  dk(  r<|dt        j                  t        j                  |dz   z  d|dz   z  z  «      dz  z  z  }ŒQ| j                  dk(  r6|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  }Œâ |j                  «       }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‘j Ó,ˆGÜ—8‘8˜JÓ'‰Dä  Ü!&¤r§|¡|°JÓ'?À!Ñ'CÓ!DóFˆNä—j‘j Ó0ˆGÜ—8‘8˜NÓ+ˆDä˜ Ó,ò 	L‰DˆAˆqØ×'Ñ'¨;Ò6Ø˜œRŸV™V¤B§E¡E¨Q°©U¡O°q¸AÀ¹E±{Ñ$CÓDÈÑIÑIÑI‘Ø×)Ñ)¨YÒ6Ø˜œRŸV™V¤B§E¡E¨A¡I°°Q±Ñ$7Ó8¸AÑ=Ñ=Ñ=‘à˜œRŸV™V¤B§E¡E¬B¯H©H°a¸!±e¸q±[Ó,AÑ$AÀAÑ$EÓFÈ!ÑKÑKÑK‘ð	Lð —Z‘Z“\ˆ
Ü�j‰j˜Ó$ˆØ  ‘oˆØˆ=Ø% q b cÐ*ˆKØ�q�b�c�(ˆCà˜CÐÐr   c                 ó.   — | j                  |«      \  }}|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‰ˆ�QØÐr   c                 óL  — | j                   dk(  rht        j                  t        j                  |«      dz   z  |dz   z  }t        j                  d|dz   z  «      t        j
                  ||dz   z  «      z  }�nf| j                   dk(  ret        j                  t        j                  |«      dz   z  |z  }t        j                  |dk(  rdnd|z  «      t        j                  ||z  «      z  }nò|dk(  r/t        j                  d|z  «      t        j                  |«      z  }n¾|dz   |k(  r=|dz  dk(  r5t        j                  d|z  «      t        j                  dd	g|dz  «      z  }nydt        j                  z  t        j                  |«      dz   z  |z  }t        j                  d|z  «      t        j                  |t        j                  |dz   dz  «      z  «      z  }d
|t        j                  |«      t        j                  t        j                  «      j                  k  <   |S )zjReturn 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Útiler'   ÚabsÚfinfoÚfloat64Úeps)r   r-   r.   ÚiÚevs        r   Ú_ev1dzLaplacianNd._ev1d6  s©  € ð ×#Ñ# {Ò2Ü—‘œŸ™ 1›¨Ñ)Ñ*¨a°!©eÑ4ˆAÜ—‘˜˜q 2™v™Ó'¬"¯&©&°°a¸!±e±Ó*=Ñ=ŠBØ×%Ñ%¨Ò2Ü—‘œŸ™ 1›¨Ñ+Ñ,¨qÑ0ˆAÜ—‘  Q¢™"¨B°!Ñ3Ó4´r·v±v¸aÀ!¹e³}ÑD‰Bà�AŠvÜ—W‘W˜R !™V“_¤r§w¡w¨q£zÑ1‘Ø�Q‘˜!’  A¡¨¢
Ü—W‘W˜R !™V“_¤r§w¡w°°2¨w¸¸1¹Ó'=Ñ=‘àœŸ™‘J¤"§)¡)¨A£,°Ñ"4Ñ5¸Ñ9�Ü—W‘W˜R !™V“_¤r§v¡v¨a´"·(±(¸AÀ¹EÀQ¹;Ó2GÑ.GÓ'HÑH�ð 57ˆŒ2�6‰6�"‹:œŸ™¤§¡Ó,×0Ñ0Ñ0Ñ1Øˆ	r   c                 ó  — t        || j                  «      D ��cg c]  \  }}| j                  ||«      ‘Œ }}}|d   }|dd D ]  }t        j                  ||d¬«      }Œ t        j
                  |«      j                  «       S c c}}w )z{Return 1 eigenvector in Nd with multi-index `j`
        as a tensor product of the corresponding 1d eigenvectors. 
        r   r   N)Úaxes)r$   r   rD   r   Ú	tensordotÚasarrayr(   )r   Úkr-   r.   ÚphiÚresults         r   Ú_one_evezLaplacianNd._one_eveM  s   € ô -0°°4·?±?Ó,C×D¡D A qˆt�z‰z˜!˜QÕÐDˆÑDØ�Q‘ˆØ�q�r�7ò 	7ˆCÜ—\‘\ &¨#°AÔ6‰Fð	7ä�z‰z˜&Ó!×'Ñ'Ó)Ð)ùó	 Es   šBc                 ó¨  — | j                  |«      \  }}|€| j                  }n?t        | j                  t        t	        j
                  | j                  «      |z  «      «      }t	        j                  ||«      }t        |Ž D �cg c]  }t        |«      ‘Œ }}|D �cg c]  }| j                  |«      ‘Œ }}t	        j                  |«      S c c}w c c}w )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. 
        )
r2   r   r!   r"   r   r#   Úunravel_indexr$   rL   Úcolumn_stack)	r   r*   r4   r0   r,   Ú	N_indicesÚxrI   Úeigenvectors_lists	            r   ÚeigenvectorszLaplacianNd.eigenvectorsW  sµ   € ð ×*Ñ*¨1Ó-‰ˆˆ3Øˆ9Ø!Ÿ_™_‰Nä  §¡Ü %¤b§l¡l°4·?±?Ó&CÀaÑ&GÓ HóJˆNô ×$Ñ$ S¨.Ó9ˆ	Ü'*¨I Ö7 !”U˜1•XÐ7ˆ	Ð7Ø7@ÖA°!˜TŸ]™]¨1Õ-ÐAÐÐAÜ�‰Ð0Ó1Ð1ùò 8ùÚAs   ÂC
ÂC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<   nF| j                  d
k(  r7|dkD  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kD  rTt        j                  |d| «      }	t        d|	«      D ]-  }
|d|…d|…f   ||
|z  |
dz   |z  …|
|z  |
dz   |z  …f<   ||z  }Œ/ |d|…d|…f   |d|…d|…f<   t        t        j                  ||dz   d «      «      }	d|d|…d|…f<   t        |	«      D �cg c]  }|‘Œ }}|d|…d|…f   |j                  ||	||	f«      dd…|dd…|f<   ||z  }�ŒÆ |j                  | j                  «      S c c}w )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   )r   r   r   r    Úint8Ú
empty_likeÚ	enumerateÚeinsumr
   ÚrangeÚintÚreshapeÚastyper   )r   r   r.   ÚLÚL_iÚLtempr0   ÚdimÚnew_dimÚtilesr-   rQ   Úidxs                r   ÚtoarrayzLaplacianNd.toarrayr  sÍ  € ð —_‘_ˆ
Ü�G‰G�JÓˆÜ�H‰H�a˜�V¤2§7¡7Ô+ˆä�m‰m˜AÓˆÜ—‘˜aÓ ˆä! *Ó-ó +	‰HˆC�àˆC‘ˆFð 68ŒB�I‰I�g˜s 4 C 4¨¨#¨ :™Ó/±Ð2Ø;<ŒB�I‰I�g˜s 9 S¨1¡W 9¨a°¨eÐ#3Ñ4Ó5±aÐ8Ø;<ŒB�I‰I�g˜s 1 S 5¨)¨C°!©G¨)Ð#3Ñ4Ó5±aÐ8à×'Ñ'¨9Ò4Ø��D‘	Ø(*��C˜!‘G˜S 1™WÐ$Ò%Ø×)Ñ)¨ZÒ7Ø˜’7Ø˜˜3 ™7˜
“O qÑ(“OØ˜˜a™ ˜
“O qÑ(”Oà˜“I ‘N“Ið ˆGà�QŠwÜŸ™ 
¨4¨CÐ 0Ó1�Ü˜q %›ò #�AØ<?ÀÀÀÀdÀsÀdÀ
¹O�C˜˜#™˜q ™s C™i˜¨¨3©°°!±°S©y¨Ð8Ñ9Ø˜s‘N‘Gð#ð
 ),¨H¨W¨H°h°w°hÐ,>Ñ(?ˆE�(�7�(˜H˜W˜HÐ$Ñ%ÜœŸ™ 
¨3¨q©5¨6Ð 2Ó3Ó4ˆEà&'ˆC���˜(˜7˜(Ð"Ñ#Ü# E›lÖ+˜’1Ð+ˆCÐ+ð %*¨(¨7¨(°H°W°HÐ*<Ñ$=ð �K‰KØ˜%Ø˜%ð!óò �Sš!˜S�.ñ"ð
 �‰HŠAðW+	ðZ �x‰x˜Ÿ
™
Ó#Ð#ùò ,s   È		I c           	      óÜ  — t        | j                  «      }t        j                  | j                  «      }t	        ||ft        j
                  ¬«      }t        |«      D �]r  }| 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(  rQt	        ||ft        j
                  ¬«      }|j                  dg| dz   ¬«       |j                  dg|dz
  ¬«       ||z  }t        |«      D ]4  }	t        t        | j                  |	   t        j
                  ¬«      |«      }Œ6 t        |dz   |«      D ]4  }	t        |t        | j                  |	   t        j
                  ¬«      «      }Œ6 ||z  }�Œu |j                  | 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)``.

        rU   é   r   NrV   r	   r8   ©r   r   )r   r8   ©r8   r   r   ©r   r   r   )rI   )Úlenr   r   r   r   rX   r\   r<   r
   Úsetdiagr   r   r_   r   )
r   r   Úpr`   rB   rc   Údatara   Útr-   s
             r   ÚtosparsezLaplacianNd.tosparse²  sª  € ô �—‘Ó ˆÜ�G‰G�D—O‘OÓ$ˆÜ�q˜!�f¤B§G¡GÔ,ˆä�q“ó 	ˆAØ—/‘/ !Ñ$ˆCÜ—7‘7˜A˜s˜8¬2¯7©7Ô3ˆDØ�’A�‹J˜"Ñ‹Jà×'Ñ'¨9Ò4Ø��T‘
Ø ��U‘ä˜T¢:Ð.°s¸C°jÜ"$§'¡'ôˆCð ×'Ñ'¨:Ò5Ü˜s C˜j´·±Ô8�Ø—	‘	˜1˜# #  a¡�	Ô(Ø—	‘	˜1˜#  Q¡�	Ô'Ø�q‘�ä˜1“Xò H�Üœ3˜tŸ™¨qÑ1¼¿¹ÔAÀ3ÓG‘ðHä˜1˜q™5 !“_ò H�Ü˜3¤ D§O¡O°AÑ$6¼b¿g¹gÔ FÓG‘ðHà�‰HŠAð/	ð0 �x‰x˜Ÿ
™
Ó#Ð#r   c           	      ó  — | j                   }t        |«      }|j                  |dz   «      }d|z  |z  }t        |«      D �]!  }|t	        j
                  |d|¬«      z  }|t	        j
                  |d|¬«      z  }| j                  dv sŒI|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(  s�Œ>|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|j                  d   «      S )
N)r8   rV   r   )Úaxisr8   )r	   r   )r   r	   r   )	r   rm   r^   r\   r   Úrollr
   Úslicer   )r   rQ   r   r   ÚXÚYrB   s          r   Ú_matveczLaplacianNd._matvecÛ  s¦  € Ø—_‘_ˆ
Ü�
‹OˆØ�I‰I�j 5Ñ(Ó)ˆØ�‰F�Q‰JˆÜ�q“ó 	ˆAØ”—‘˜˜A AÔ&Ñ&ˆAØ”—‘˜˜B QÔ'Ñ'ˆAØ×'Ñ'Ð+CÒCØ”5˜“;�. Ñ" TÑ)¬U°4«[¨N¸A¸a¹CÀ¹EÑ,BÑBó Ü—w‘w˜q !¨!Ô,Ü˜4“[�N QÑ&¨Ñ-´°t³°À!ÀAÁ#ÀaÁ%Ñ0HÑHññó ð Ü˜4“[�N QÑ&¨Ñ.´%¸³+°À1ÀQÁ3ÀqÁ5Ñ1IÑIóä—W‘W˜Q ¨Ô+Ü˜4“[�N QÑ&¨Ñ.´%¸³+°À1ÀQÁ3ÀqÁ5Ñ1IÑIññó ð ×+Ñ+¨yÔ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°^ÀqÈÁsÈ1ÁuÑ5MÑMóäŸ™  A¨AÔ.Ü˜t›˜¨Ñ*¨UÑ2´e¸D³k°^ÀqÈÁsÈ1ÁuÑ5MÑMññõ ð)	ð4 �y‰y˜˜QŸW™W R™[Ó)Ð)r   c                 ó$   — | j                  |«      S ©N©ry   ©r   rQ   s     r   Ú_matmatzLaplacianNd._matmatü  s   € Ø�|‰|˜A‹Ðr   c                 ó   — | S r{   © ©r   s    r   Ú_adjointzLaplacianNd._adjointÿ  ó   € Øˆr   c                 ó   — | S r{   r€   r�   s    r   Ú
_transposezLaplacianNd._transpose  rƒ   r   r{   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   rX   r   r2   r1   rD   rL   rS   rg   rr   ry   r~   r‚   r…   Ú__classcell__©r   s   @r   r   r   
   sU   ø„ ñhðV &/Ø—w‘wö4ò" ó>ò"ò.*ó2ò6>$ò@'$òR*òBòör   c                   ól   ‡ — 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                 óJ   •— || _         || _        ||f}t        ‰| �  ||«       y r{   )r.   r   r   r   )r   r.   r   r   r   s       €r   r   zSakurai.__init__a  s)   ø€ ØˆŒØˆŒ
Ø�A�ˆÜ‰Ñ˜ Õ&r   c           
      óJ  — |€| 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.
        r   g      0@r7   é   )r.   r   r9   ÚflipÚpowerr;   r&   )r   r*   rI   s      r   r1   zSakurai.eigenvaluesg  sw   € ð ˆ9Ø—‘ˆAÜ�I‰I�d—f‘f˜q‘j !‘m T§V¡V¨a¡ZÓ0ˆÜ�w‰w�sœRŸX™X¤b§f¡f¨S°1©W´r·u±u©_ÀÇÁÈÁ
Ñ-KÓ&LÈaÓPÑPÓQÐQr   c                 ó   — 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                  | j                  «      S )zA
        Construct the Sakurai matrix as a banded array.
        é   é   r   rU   r   )r   Úr_r<   r.   r   Úarrayr_   )r   Úd0Úd1Úd2s       r   ÚtobandedzSakurai.tobandedz  sŽ   € ô �U‰U�1�aœ"Ÿ'™' $§&¡&¨1¡*°D·J±JÔ?Ñ?ÀÐBÑCˆØ”"—'‘'˜$Ÿ&™&¨¯
©
Ô3Ñ3ˆÜ�W‰W�T—V‘V 4§:¡:Ô.ˆÜ�x‰x˜˜R ˜Ó%×,Ñ,¨T¯Z©ZÓ8Ð8r   c                 ó˜   — ddl m} | j                  «       } ||d   |d   |d   |d   |d   gg d¢| j                  | j                  «      S )zB
        Construct the Sakurai matrix is a sparse format.
        r   )Úspdiagsr   r   )rV   r8   r   r   r   )Úscipy.sparser�   r›   r.   )r   r�   Úds      r   rr   zSakurai.tosparseƒ  sR   € õ 	)Ø�M‰M‹Oˆñ ˜˜!™˜a ™d A a¡D¨!¨A©$°°!±Ð5Ò7HØ—v‘v˜tŸv™vó'ð 	'r   c                 ó>   — | j                  «       j                  «       S r{   ©rr   rg   r�   s    r   rg   zSakurai.toarrayŽ  ó   € Ø�}‰}‹×&Ñ&Ó(Ð(r   c                 óL  — |j                  | 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   rU   r”   r   Nr�   r   r   rV   éýÿÿÿr•   )rj   rW   ri   ))r   r   rW   )r^   r.   r   Úpromote_typesr   Ú
zeros_likeÚpad)r   rQ   Úresult_dtypeÚsxs       r   ry   zSakurai._matvec‘  s;  € ð �I‰I�d—f‘f˜bÓ!ˆÜ×'Ñ'¨¯©°·±Ó<ˆÜ�]‰]˜1 LÔ1ˆØ�q˜šA˜‘w‘;  Q qª! t¡W¡Ñ,¨q°²A°©wÑ6ˆˆ1Šaˆ4‰Ø˜˜"ša˜%™‘L 1 q¨ªQ¨¡x¡<Ñ/°!°Bº°E±(Ñ:ˆˆ2Šqˆ5‰	Ø˜A˜a ˜e¢Q˜h™K™¨!¨q°°"°²a°©y¸1¸Q¹RÂ¸U¹8Ñ/CÑ*DÑDÜŸ™˜q  " ¢a ™yÐ*:Ó;ñ<äŸ™˜q ¡¢Q ™xÐ)9Ó:ñ;ˆˆ1ˆbˆ5’!ˆ8‰ð ˆ	r   c                 ó$   — | j                  |«      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{   r€   r�   s    r   r‚   zSakurai._adjoint©  rƒ   r   c                 ó   — | S r{   r€   r�   s    r   r…   zSakurai._transpose¬  rƒ   r   r{   )r†   r‡   rˆ   r‰   r   rX   r   r1   r›   rr   rg   ry   r~   r‚   r…   rŠ   r‹   s   @r   r�   r�     sA   ø„ ñYðt !#§¡õ 'óRò&9ò	'ò)òò òör   r�   c                   ój   ‡ — 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                 óB   •— || _         || _        t        ‰| �  ||«       y r{   )r   r   r   r   )r   r   r   r   s      €r   r   zMikotaM.__init__È  s    ø€ ØˆŒ
ØˆŒ
Ü‰Ñ˜ Õ&r   c                 ó†   — dt        j                  d| j                  d   dz   «      z  j                  | j                  «      S )Nr6   r   r   )r   r9   r   r_   r   r�   s    r   Ú_diagzMikotaM._diagÍ  s6   € ð ”R—Y‘Y˜q $§*¡*¨Q¡-°!Ñ"3Ó4Ñ4×<Ñ<¸T¿Z¹ZÓHÐHr   c                 ó"   — | j                  «       S r{   )r²   r�   s    r   r›   zMikotaM.tobandedÒ  s   € Ø�z‰z‹|Ðr   c                 ón   — ddl m}  || j                  «       gdg| j                  | j                  ¬«      S )Nr   ©Údiagsrl   )rž   r¶   r²   r   r   ©r   r¶   s     r   rr   zMikotaM.tosparseÕ  s(   € Ý&Ù�d—j‘j“l�^ a S°·
±
À$Ç*Á*ÔMÐMr   c                 óz   — t        j                  | j                  «       «      j                  | j                  «      S r{   )r   Údiagr²   r_   r   r�   s    r   rg   zMikotaM.toarrayÙ  s&   € Ü�w‰w�t—z‘z“|Ó$×+Ñ+¨D¯J©JÓ7Ð7r   c                 ó�   — |j                  | j                  d   d«      }| j                  «       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)r^   r   r²   r   Únewaxisr}   s     r   ry   zMikotaM._matvecÜ  s:   € ð �I‰I�d—j‘j ‘m RÓ(ˆØ�z‰z‹|šAœrŸz™z˜MÑ*¨QÑ.Ð.r   c                 ó$   — | j                  |«      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{   r€   r�   s    r   r‚   zMikotaM._adjointí  rƒ   r   c                 ó   — | S r{   r€   r�   s    r   r…   zMikotaM._transposeð  rƒ   r   )r†   r‡   rˆ   r‰   r   r@   r   r²   r›   rr   rg   ry   r~   r‚   r…   rŠ   r‹   s   @r   r¯   r¯   °  s@   ø„ ñð. %'§J¡Jõ 'ò
Iò
òNò8ò/òòör   r¯   c                   ód   ‡ — 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                  ¬«       | _        y )Nr   r   r   rV   rU   r8   )r   r   r   r   r   r9   Ú_diag0Ú_diag1)r   r   r   r.   r   s       €r   r   zMikotaK.__init__  sn   ø€ ØˆŒ
ØˆŒ
Ü‰Ñ˜ Ô&ð �!‰HˆÜ—i‘i  A¡¨¡	¨1¨b¸¿
¹
ÔCˆŒÜŸ	™	 ! a¡%¨¨B°d·j±jÔAÐAˆ�r   c                 ó‚   — t        j                  t        j                  | j                  dd«      | j                  g«      S )Nrj   Úconstant)r   r—   r§   rÃ   rÂ   r�   s    r   r›   zMikotaK.tobanded  s+   € Ü�x‰xœŸ™ §¡¨V°ZÓ@À$Ç+Á+ÐNÓOÐOr   c                 ó”   — ddl m}  || j                  | j                  | j                  gg d¢| j                  | j
                  ¬«      S )Nr   rµ   rk   rl   )rž   r¶   rÃ   rÂ   r   r   r·   s     r   rr   zMikotaK.tosparse  s6   € Ý&Ù�d—k‘k 4§;¡;°·±Ð<ºjØŸ:™:¨T¯Z©Zô9ð 	9r   c                 ó>   — | j                  «       j                  «       S r{   r¡   r�   s    r   rg   zMikotaK.toarray  r¢   r   c                 ó"  — |j                  | 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   rU   Nr   rV   r   )r^   r   r   r¥   r   r¦   rÃ   rÂ   )r   rQ   r¨   Úkxr™   r˜   s         r   ry   zMikotaK._matvec"  s9  € ð �I‰I�d—j‘j ‘m RÓ(ˆÜ×'Ñ'¨¯©°·±Ó<ˆÜ�]‰]˜1 LÔ1ˆØ�[‰[ˆØ�[‰[ˆØ�a‘5˜1˜Q¢˜T™7‘? R¨¡U¨Q¨q²!¨t©W¡_Ñ4ˆˆ1Šaˆ4‰Ø�r‘F˜Q˜r¢1˜u™XÑ%¨¨2©°°2²q°5±Ñ(9Ñ9ˆˆ2Šqˆ5‰	Ø˜3˜B˜3 ˜9™¨¨$¨B¨$²¨'©
Ñ2Ø˜Q ˜U D˜[™/¨A¨a°¨e²Q¨h©KÑ7ñ8à˜Q™R ˜X™,¨¨1©2ªq¨5©Ñ1ñ2ˆˆ1ˆbˆ5’!ˆ8‰ð ˆ	r   c                 ó$   — | j                  |«      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._matmat4  r«   r   c                 ó   — | S r{   r€   r�   s    r   r‚   zMikotaK._adjoint<  rƒ   r   c                 ó   — | S r{   r€   r�   s    r   r…   zMikotaK._transpose?  rƒ   r   )r†   r‡   rˆ   r‰   r   Úint32r   r›   rr   rg   ry   r~   r‚   r…   rŠ   r‹   s   @r   rÀ   rÀ   ô  s;   ø„ ñð0 %'§H¡Hõ BòPò9ò
)òò$òör   rÀ   c                   ó6   — e Zd ZdZej
                  fd„Zdd„Zy)Ú
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 20 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                  «      | _        y r{   )r.   r   r   r¯   r*   rÀ   rI   )r   r.   r   s      r   r   zMikotaPair.__init__œ  sG   € ØˆŒØˆŒ
Ø˜�VˆŒ
Ü˜Ÿ™ T§Z¡ZÓ0ˆŒÜ˜Ÿ™ T§Z¡ZÓ0ˆ�r   Nc                 óz   — |€| 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.
        r   rU   )r.   r   r9   Úuint64)r   r*   Úarange_plus1s      r   r1   zMikotaPair.eigenvalues£  s7   € ð ˆ9Ø—‘ˆAÜ—y‘y  A¨¡E´·±Ô;ˆØ˜lÑ*Ð*r   r{   )r†   r‡   rˆ   r‰   r   r@   r   r1   r€   r   r   rÏ   rÏ   C  s   „ ñWðp !#§
¡
ó 1ô+r   rÏ   )Únumpyr   Úscipy.sparse.linalgr   rž   r   r   r   Ú__all__r   r�   r¯   rÀ   rÏ   r€   r   r   ú<module>r×      s`   ðÛ Ý .ß -Ñ -àˆ/€ô
y�.ô yôxgˆnô gôTAˆnô AôHLˆnô L÷^q+ò q+r   