o
    i^                     @   s   d dl Z d dlZd dlZd dlmZ d dlmZ dd Zdd Zdd Z	d	d
 Z
dd Zdd ZdddZdd ZdddZ			 	dddZdS )    N)linalgc                 C   s(   t j| }t t |rtjj|S )zk
    Wrapper around `cupy.linalg.cholesky` that raises LinAlgError if there are
    NaNs in the output
    )cupyr   choleskyanyisnannumpyLinAlgError)BR r   ^/home/ubuntu/veenaModal/venv/lib/python3.10/site-packages/cupyx/scipy/sparse/linalg/_lobpcg.py	_cholesky   s   r   c                 C   sT  t | }t | d }ddg}t|D ]}|d  | | d jd 7  < qt|D ]}|d  | d | jd 7  < q(tjdd | D  }tdd | D }tdd | D }|r\|s\dnd	}	tjt|||	d
}
d}d}d}d}t|D ]3}|| | d jd  }d}t|D ]}|| | | jd  }| | | |
||||f< |}q|}qt|
S )ze
    Helper function to create a block matrix in cupy from a list
    of smaller 2D dense arrays
    r      c                 S   s   g | ]
}|D ]}|j qqS r   dtype.0	list_iterarrr   r   r   
<listcomp>%   s
    z_bmat.<locals>.<listcomp>c                 s   $    | ]}|D ]}|j d  V  qqdS )F_CONTIGUOUSNflagsr   r   r   r   	<genexpr>(       z_bmat.<locals>.<genexpr>c                 s   r   )C_CONTIGUOUSNr   r   r   r   r   r   *   r   FC)r   order)lenrangeshaper   result_typeallemptytuple)list_objn_rowsn_colsfinal_shapeijr   F_orderC_orderr   resultstart_idx_rowstart_idx_colend_idx_rowend_idx_colr   r   r   _bmat   sD     

r4   c              
   C   s   | | j   }t|d}dt| jj }|tdt	t| d9 }||kr?t
jd| d| j d| d| d	tdd	 d
S d
S )zA
    Report if `M` is not a hermitian matrix given its type.
    r   
   zMatrix z of the type z is not Hermitian: condition: z < z fails.   )
stacklevelN)Tconjr   normr   finfor   epsmaxfloatwarningswarnUserWarning)Mnamemdnmdtolr   r   r   _report_nonhermitian?   s   
rG   c                 C   s0   | j dkr| S tj| dd}| jd df|_|S )zm
    If the input array is 2D return it, if it is 1D, append a dimension,
    making it a column vector.
       F)copyr   r   )ndimr   arrayr"   )arauxr   r   r   _as2dP   s
   
rN   c                 C   s,   | du rdS t | }|j|krtd|S )zTakes a dense numpy array or a sparse matrix or
    a function and makes an operator performing matrix * blockvector
    products.
    Nzoperator has invalid shape)splinalgaslinearoperatorr"   
ValueError)operatorInputexpectedShapeoperatorr   r   r   _makeOperator]   s   

rU   c                 C   s2   t |j | }t||}| t ||8 } dS )zChanges blockVectorV in place.N)r   dotr8   r9   r   solve)blockVectorVYBYblockVectorBYblockVectorYYBVtmpr   r   r   _applyConstraintsm   s   r^   Fc                 C   s   |j ddt|jj }|| }|du r!| dur| |}n|}n|| }t|j |}zt|}t	
|j}t||}| durJt||}nd}W n tj	jy^   d}d}d}Y nw |rg||||fS ||fS )z7B-orthonormalize the given block vector using Cholesky.r   )axisN)r=   r   r;   r   r<   matmulr8   r9   r   r   invr   r   )r	   rX   blockVectorBVretInvRnormalizationVBVr   r   r   _b_orthonormalizev   s8   
rf   c                 C   s6   t | }|r|d| d d }|S |d| }|S )z?Get `num` indices into `_lambda` depending on `largest` option.Nr   )r   argsort)_lambdanumlargestiir   r   r   	_get_indx   s   
rm   c           	      C   sr   |du rt | \}}||fS t|}t |}t |j}t|t| |}t |\}}t||}||fS )z
    Helper function for converting a generalized eigenvalue problem
    A(X) = lambda(B(X)) to standard eigen value problem using cholesky
    transformation
    N)r   eighr   ra   r8   r   r`   )	Ar	   valsvecsr
   RTiRir   eigVecr   r   r   _eigh   s   
ru   Tc           K         s  |}|}|}|du rd}|dur|j d }nd}t|j dkr#td|j \}} rsd}|du r5|d7 }n|d	7 }|d
7 }|du rE|d7 }|d7 }|d| 7 }|d| 7 }|du r^|d7 }n|dkri|d| 7 }n|d| 7 }t| t| ||f} t|||f}t|||f}|| d| k rt||}|durtd| tj|| j	d}|du rdn	|tj||j	d}t
||\}}|r|ddd }|dddddf }|d| }|ddd|f }||fS |du s|dkrtd| }|dur|dur||}n|}t|j |}t|||| t||\}}| |}t|j |}t
|\}}t|||}|| }t|dd|f }t||}t||}|dur\t||}tj|ftd}|g}g } |}!tj|| j	d}"tj|| j	d}#d}$d}%d}&d}'d}(d})|'|k rx|'d7 }'|dur||tjddf  }n||tjddf  }|| }*t|* |* d}t|}+| |+ t|+|kdd}||@ }t| },|,|!kr|,}!tj|,| j	d}"|,dkrn dkrtd|'  td|,  td|  td|+   dkrt| t|*dd|f }-|'dkrHt|$dd|f }.t|%dd|f }/|durHt|&dd|f }0|durQ||-}-|dur]t|-||| |durr|-t|t|j |- }-n|-t|t|j |- }-t||-}|\}-}1| |-}2|'dkr|durt||.|0dd}|\}.}0}3}4nt||.dd}|\}.}5}3}4|.dur|/|4 }/t|/|3}/d}(nd}(|2j	d krd}6n|-j	d krd!}6nd"}6|+ |6kr|)sd})nd})|du r|}|-}1|(s|.}0t|j |2}7t|-j |2}8|)rE|8|8j  d }8t|j |}||j  d }t|j |}9t|-j |1}:t|j |1};nt|}|#}9|"}:tjt|t|,f| j	d}; fd#d$}<|(st|j |/}=t|-j |/}>t|.j |/}?t|j |0}@t|-j |0}A|)r|?|?j  d }?t|.j |0}Bn|"}Bt||7|=g|7j |8|>g|=j |>j |?gg}Ct|9|;|@g|;j |:|Ag|@j |Aj |Bgg}D|<|C|D z	t
|C|D\}}W n t j!j"y   d}(Y nw |(r3t||7g|7j |8gg}Ct|9|;g|;j |:gg}D|<|C|D z	t
|C|D\}}W n t j!j"y2   td%w t|||} dkrFt| t| || }|dd|f }||  dkratd&|  dkrjt| |dur|(s|d| }E||||,  }F|||, d }Gt|-|F}H|Ht|.|G7 }Ht|2|F}I|It|/|G7 }It|1|F}J|Jt|0|G7 }Jn|d| }E||d }Ft|-|F}Ht|2|F}It|1|F}J dkrt|H t|I t|J t||E|H }t||E|I }t||E|J }|H|I|J}$}%}&np|(s9|d| }E||||,  }F|||, d }Gt|-|F}H|Ht|.|G7 }Ht|2|F}I|It|/|G7 }In|d| }E||d }Ft|-|F}Ht|2|F}I dkr^t|H t|I t||E|H }t||E|I }|H|I}$}%|'|k s|dur||tjddf  }n||tjddf  }|| }*t|* |* d}t|}+ dkrtd'|  td(|+   dkrtd)|  td*|+  |	r|
r|||| fS |||fS |
r||| fS ||fS )+a  Locally Optimal Block Preconditioned Conjugate Gradient Method (LOBPCG)

    LOBPCG is a preconditioned eigensolver for large symmetric positive
    definite (SPD) generalized eigenproblems.

    Args:
        A (array-like): The symmetric linear operator of the problem,
            usually a sparse matrix. Can be of the following types
            - cupy.ndarray
            - cupyx.scipy.sparse.csr_matrix
            - cupy.scipy.sparse.linalg.LinearOperator
        X (cupy.ndarray): Initial approximation to the ``k``
            eigenvectors (non-sparse). If `A` has ``shape=(n,n)``
            then `X` should have shape ``shape=(n,k)``.
        B (array-like): The right hand side operator in a generalized
            eigenproblem. By default, ``B = Identity``.
            Can be of following types:
            - cupy.ndarray
            - cupyx.scipy.sparse.csr_matrix
            - cupy.scipy.sparse.linalg.LinearOperator
        M (array-like): Preconditioner to `A`; by default ``M = Identity``.
            `M` should approximate the inverse of `A`.
            Can be of the following types:
            - cupy.ndarray
            - cupyx.scipy.sparse.csr_matrix
            - cupy.scipy.sparse.linalg.LinearOperator
        Y (cupy.ndarray):
            `n-by-sizeY` matrix of constraints (non-sparse), `sizeY < n`
            The iterations will be performed in the B-orthogonal complement
            of the column-space of Y. Y must be full rank.
        tol (float):
            Solver tolerance (stopping criterion).
            The default is ``tol=n*sqrt(eps)``.
        maxiter (int):
            Maximum number of iterations.  The default is ``maxiter = 20``.
        largest (bool):
            When True, solve for the largest eigenvalues,
            otherwise the smallest.
        verbosityLevel (int):
            Controls solver output.  The default is ``verbosityLevel=0``.
        retLambdaHistory (bool):
            Whether to return eigenvalue history.  Default is False.
        retResidualNormsHistory (bool):
            Whether to return history of residual norms.  Default is False.

    Returns:
        tuple:
            - `w` (cupy.ndarray): Array of ``k`` eigenvalues
            - `v` (cupy.ndarray) An array of ``k`` eigenvectors.
              `v` has the same shape as `X`.
            - `lambdas` (list of cupy.ndarray): The eigenvalue history,
              if `retLambdaHistory` is True.
            - `rnorms` (list of cupy.ndarray): The history of residual norms,
              if `retResidualNormsHistory` is True.

    .. seealso:: :func:`scipy.sparse.linalg.lobpcg`

    .. note::
        If both ``retLambdaHistory`` and ``retResidualNormsHistory`` are `True`
        the return tuple has the following format
        ``(lambda, V, lambda history, residual norms history)``.
    N   r   r   rH   z$expected rank-2 array for argument XzSolving standardgeneralizedz eigenvalue problem withoutz preconditioning

zmatrix size %d
zblock size %d

zNo constraints

z%d constraints

z%d constraint

   z3The dense eigensolver does not support constraints.r   rg   g        gV瞯<TFziteration %dzcurrent block size: zeigenvalue(s):
zresidual norm(s):
r5   )rc   float32g-C6?g:0yE>c                    sP    dkrt | d t |d  dkr&tdt|  tdt| d S d S )Nr   gramAgramBr5   z	gramA.txtz	gramB.txt)rG   r   savetxtr   asnumpy)r|   r}   verbosityLevelr   r   _handle_gramA_gramB_verbosity  s   

z-lobpcg.<locals>._handle_gramA_gramB_verbosityz$eigh has failed in lobpcg iterationszlambda:zFinal iterative eigenvalue(s):
z"Final iterative residual norm(s):
z$Final postprocessing eigenvalue(s):
zFinal residual norm(s):
)#r"   r    rQ   printrU   minNotImplementedErrorr   eyer   ru   sqrtrV   r8   r9   r^   rf   rm   asarrayonesboolnewaxissumappendwhereintrN   r`   r=   diagzerosr4   r   r   r   )Kro   Xr	   rB   YrF   maxiterrk   r   retLambdaHistoryretResidualNormsHistoryblockVectorXr[   residualTolerancesizeYnsizeXrM   A_denseB_denserp   rq   rZ   gramYBYblockVectorBXblockVectorAXgramXAXri   eigBlockVectorrl   
activeMasklambdaHistoryresidualNormsHistorypreviousBlockSizeidentident0blockVectorPblockVectorAPblockVectorBPiterationNumberrestartexplicitGramFlagblockVectorRresidualNormscurrentBlockSizeactiveBlockVectorRactiveBlockVectorPactiveBlockVectorAPactiveBlockVectorBPactiveBlockVectorBRactiveBlockVectorARinvRnormal_myepsgramXARgramRARgramXBXgramRBRgramXBRr   gramXAPgramRAPgramPAPgramXBPgramRBPgramPBPr|   r}   eigBlockVectorXeigBlockVectorReigBlockVectorPppappbppr   r   r   lobpcg   sX  C



 


	




















	












  
  






r   )NF)N)	NNNNNTr   FF)r?   r   r   cupy.linalgr   cupyx.scipy.sparserO   r   r4   rG   rN   rU   r^   rf   rm   ru   r   r   r   r   r   <module>   s&    (
	#
