
    _-Ph2                         d Z ddlmZ ddlZddlmZ ddlmZ	 ddl
mZ ddlmZmZmZmZmZmZmZmZ ddlmZ dd	lmZ d
 Z	 	 ddZddZ	 ddZ	 ddZd Z	 ddZ	 	 	 ddZ dS )z3Methods to smooth tentative prolongation operators.    )warnN)sparse   )amg_core)
scale_rowsget_diagonalget_block_diagunamalfilter_operatorcompute_BtBinvfilter_matrix_rowstruncate_rows)approximate_spectral_radius)upcastc                    | j         d         }| j         d         }t          | j        d         |z            }t          j        | |z            }t          j        ||||j        d         t          j        t          j        |                    |t          j        |          | j        | j	        t          j        | j
                  
  
         | S )a  U is the prolongator update.  Project out components of U such that U*B = 0.

    Parameters
    ----------
    U : bsr_matrix
        m x n sparse bsr matrix
        Update to the prolongator
    B : array
        n x k array of the coarse grid near nullspace vectors
    BtBinv : array
        Local inv(B_i.H*B_i) matrices for each supernode, i
        B_i is B restricted to the sparsity pattern of supernode i in U

    Returns
    -------
    Updated U, so that U*B = 0.
    Update is computed by orthogonally (in 2-norm) projecting
    out the components of span(B) in U in a row-wise fashion.

    See Also
    --------
    The principal calling routine,
    pyamg.aggregation.smooth.energy_prolongation_smoother

    r      )	blocksizeintshapenpravelr   satisfy_constraints_helper	conjugateindptrindicesdata)UBBtBinvrows_per_blockcols_per_blocknum_block_rowsUBs          X/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/pyamg/aggregation/smooth.pysatisfy_constraintsr%      s    4 [^N[^NN233N	!A#B '(6
(*RXa[[(A(A(*BHV,<,<()!)(*(8(8: : : H    UUUUUU?r   Fdiagonalc                 :   |dk    r>t          j        |           rd}n't          j        |           r| j        d         dk    rd}|r^t          j        |           r| j        d         }nd}t	          |||          }|                     |          } |                                  |dk    r:t          | d          }	t          | |	d          }
|t          |
          z  |
z  }
n?|dk    rt          | | j        d         d          }	t          j        |	t          j        |	j        d                   t          j        |	j        d         dz             f| j        	          }	|	| z  }
|t          |
          z  |
z  }
n|d
k    rt          j        |           t          j        | j        d         df| j                  z  }t          j        |          }	dt          j        ||dk                       z  |	|dk    <   t          | |	d          }
||
z  }
nt'          d          |rY|}t)          |          D ]F}|
|z                      |j                  }t-          ||          }t/          |||           ||z
  }Gn|}t)          |          D ]
}||
|z  z
  }|S )af	  Jacobi prolongation smoother.

    Parameters
    ----------
    S : csr_matrix, bsr_matrix
        Sparse NxN matrix used for smoothing.  Typically, A.
    T : csr_matrix, bsr_matrix
        Tentative prolongator
    C : csr_matrix, bsr_matrix
        Strength-of-connection matrix
    B : array
        Near nullspace modes for the coarse grid such that T*B
        exactly reproduces the fine grid near nullspace modes
    omega : scalar
        Damping parameter
    filter_entries : boolean
        If true, filter S before smoothing T.  This option can greatly control
        complexity.
    weighting : string
        'block', 'diagonal' or 'local' weighting for constructing the Jacobi D
        'local' Uses a local row-wise weight based on the Gershgorin estimate.
        Avoids any potential under-damping due to inaccurate spectral radius
        estimates.
        'block' uses a block diagonal inverse of A if A is BSR
        'diagonal' uses classic Jacobi with D = diagonal(A)

    Returns
    -------
    P : csr_matrix, bsr_matrix
        Smoothed (final) prolongator defined by P = (I - omega/rho(K) K) * T
        where K = diag(S)^-1 * S and rho(K) is an approximation to the
        spectral radius of K.

    Notes
    -----
    If weighting is not 'local', then results using Jacobi prolongation
    smoother are not precisely reproducible due to a random initial guess used
    for the spectral radius approximation.  For precise reproducibility,
    set numpy.random.seed(..) to the same value before each test.

    Examples
    --------
    >>> from pyamg.aggregation import jacobi_prolongation_smoother
    >>> from pyamg.gallery import poisson
    >>> from scipy.sparse import coo_matrix
    >>> import numpy as np
    >>> data = np.ones((6,))
    >>> row = np.arange(0,6)
    >>> col = np.kron([0,1],np.ones((3,)))
    >>> T = coo_matrix((data,(row,col)),shape=(6,2)).tocsr()
    >>> T.toarray()
    array([[1., 0.],
           [1., 0.],
           [1., 0.],
           [0., 1.],
           [0., 1.],
           [0., 1.]])
    >>> A = poisson((6,),format='csr')
    >>> P = jacobi_prolongation_smoother(A,T,A,np.ones((2,1)))
    >>> P.toarray()
    array([[0.64930164, 0.        ],
           [1.        , 0.        ],
           [0.64930164, 0.35069836],
           [0.35069836, 0.64930164],
           [0.        , 1.        ],
           [0.        , 0.64930164]])

    blockr(   r   r   T)inv)copyr   inv_flagr   localdtype      ?zIncorrect weighting option)r   )r   isspmatrix_csrisspmatrix_bsrr   r
   multiplyeliminate_zerosr   r   r   r	   
bsr_matrixr   aranger   absonesr2   
zeros_like
ValueErrorrangetobsrr   r%   )STCr   omegadegreefilter_entries	weightingnumPDEsD_invD_inv_SDP_r   r   s                   r$   jacobi_prolongation_smootherrM   =   s   N G ## 	'"II"1%% 	'{1~""&	   ## 	k!nGGG 1gw''JJqMM	JQD)))QD1114W===wF	g		qAKNTJJJ!5")EKN*C*C#%9U[^A-=#>#>#@()1 1 1 '4W===wF	g		 F1IIbgqwqz1oQW====a  bfQqAvY///a1fQD111-5666   v 	 	A!!AK!88A
 $Aq))F  1f--- AAA	  v 	  	 AWQYAAHr&   c                 h    |t          |           z  }|}t          |          D ]}||| |z  z  z
  }|S )a  Richardson prolongation smoother.

    Parameters
    ----------
    S : csr_matrix, bsr_matrix
        Sparse NxN matrix used for smoothing.  Typically, A or the
        "filtered matrix" obtained from A by lumping weak connections
        onto the diagonal of A.
    T : csr_matrix, bsr_matrix
        Tentative prolongator
    omega : scalar
        Damping parameter

    Returns
    -------
    P : csr_matrix, bsr_matrix
        Smoothed (final) prolongator defined by P = (I - omega/rho(S) S) * T
        where rho(S) is an approximation to the spectral radius of S.

    Notes
    -----
    Results using Richardson prolongation smoother are not precisely
    reproducible due to a random initial guess used for the spectral radius
    approximation.  For precise reproducibility, set numpy.random.seed(..) to
    the same value before each test.


    Examples
    --------
    >>> from pyamg.aggregation import richardson_prolongation_smoother
    >>> from pyamg.gallery import poisson
    >>> from scipy.sparse import coo_matrix
    >>> import numpy as np
    >>> data = np.ones((6,))
    >>> row = np.arange(0,6)
    >>> col = np.kron([0,1],np.ones((3,)))
    >>> T = coo_matrix((data,(row,col)),shape=(6,2)).tocsr()
    >>> T.toarray()
    array([[1., 0.],
           [1., 0.],
           [1., 0.],
           [0., 1.],
           [0., 1.],
           [0., 1.]])
    >>> A = poisson((6,),format='csr')
    >>> P = richardson_prolongation_smoother(A,T)
    >>> P.toarray()
    array([[0.64930164, 0.        ],
           [1.        , 0.        ],
           [0.64930164, 0.35069836],
           [0.35069836, 0.64930164],
           [0.        , 1.        ],
           [0.        , 0.64930164]])

    )r   r>   )r@   rA   rC   rD   weightrK   rL   s          r$    richardson_prolongation_smootherrP      sK    p .q111F	A6]]  !Hr&   r0   c	                 0
   t          j        t          j        |j        j        |j                  |j        |j        f|j                  }	|dk    rt          | dd          }
n|dk    ryt          | | j        d         d	          }
t          j        |
t          j        |
j        d                   t          j        |
j        d         d
z             f| j                  }
n|dk    rzt          j        |           t          j        | j        d         d
f| j                  z  }t          j        |          }
dt          j        ||dk                       z  |
|dk    <   nt!          d          t          j        |j        j        |j                  }t          j        ||j        |j        f|j                  }t#          j        | j        | j        t          j        | j                  |j        |j        t          j        |j                  |j        |j        t          j        |j                  t)          |j        d         |j        d         z            t)          |j        d
         |j        d
         z            | j        d         | j        d
         |j        d
                    |xj        dz  c_        t+          |||           |j        dk    rt/          d           |S |j        }d}||k     r||k    r|dv rt1          ||
          }n|
|z  }|                                                    |                                          }||k     rn|dk    r|}|}n||z  }|||z  z   }|}d|	j        dd<   t#          j        | j        | j        t          j        | j                  |j        |j        t          j        |j                  |	j        |	j        t          j        |	j                  t)          |j        d         |j        d         z            t)          |j        d
         |j        d
         z            | j        d         | j        d
         |j        d
                    t+          |	||           ||                                                    |	                                          z  }|||z  z   }|d         r |d
         d         |z  |d
         d         z   }|||	z  z
  }|d
z  }|j        }||k     r||k    |S )aT  Use CG to smooth T by solving A T = 0, subject to nullspace and sparsity constraints.

    Parameters
    ----------
    A : csr_matrix, bsr_matrix
        SPD sparse NxN matrix
    T : bsr_matrix
        Tentative prolongator, a NxM sparse matrix (M < N).
        This is initial guess for the equation A T = 0.
        Assumed that T B_c = B_f
    B : array
        Near-nullspace modes for coarse grid, i.e., B_c.
        Has shape (M,k) where k is the number of coarse candidate vectors.
    BtBinv : array
        3 dimensional array such that,
        BtBinv[i] = pinv(B_i.H Bi), and B_i is B restricted
        to the neighborhood (in the matrix graph) of dof of i.
    pattern : csr_matrix, bsr_matrix
        Sparse NxM matrix
        This is the sparsity pattern constraint to enforce on the
        eventual prolongator
    maxiter : int
        maximum number of iterations
    tol : float
        residual tolerance for A T = 0
    weighting : string
        'block', 'diagonal' or 'local' construction of the diagonal
        preconditioning
    Cpt_params : tuple
        Tuple of the form (bool, dict).  If the Cpt_params[0] = False, then
        the standard SA prolongation smoothing is carried out.  If True, then
        dict must be a dictionary of parameters containing, (1) P_I: P_I.T is
        the injection matrix for the Cpts, (2) I_F: an identity matrix
        for only the F-points (i.e. I, but with zero rows and columns for
        C-points) and I_C: the C-point analogue to I_F.

    Returns
    -------
    T : bsr_matrix
        Smoothed prolongator using conjugate gradients to solve A T = 0,
        subject to the constraints, T B_c = B_f, and T has no nonzero
        outside of the sparsity pattern in pattern.

    See Also
    --------
    The principal calling routine,
    pyamg.aggregation.smooth.energy_prolongation_smoother

    r1   r/   r(   FTnorm_eqr+   r*   r   r-   r   r0   r3   weighting value is invalid      _Error in sa_energy_min(..).  Initial R no nonzeros on a level. Returning tentative prolongator
r0   r(           NI_FP_I)r   r8   r   zerosr   r   r2   r   r   r   r	   r   r9   r:   r;   r<   r=   r   incomplete_mat_mult_bsrr   r   r%   nnzprintr   r   r6   sum)ArA   r   r   patternmaxitertolrF   
Cpt_paramsAPDinvrJ   uonesRresidiZnewsumrK   oldsumbetaalphas                         r$   cg_prolongation_smoothingrp     s   h 
	BHW\%7qwGGG#OW^=!(
0 
0 
0B
 JAu$777	g		a1;q>DIII $	$*Q-(@(@"$)DJqM!O"<"<">'(w0 0 0 
g		F1IIbgqwqz1oQW====}QRVAa1fI...Q!V5666 HW\'qw777E5'/">+ '	/ 	/ 	/A $QXqy%'Xaf%5%5%&Xqy%'Xaf%5%5%&Xqy%'Xaf%5%5%(AKN)B%C%C%(AKN)B%C%C%&[^Q[^%&[^	5 	5 	5 FFdNFF 1f%%%uzz 2 	3 	3 	3 EE 	
A
g++%#++---1d##AAQA ++--((++0022C<< 66AFFF?DDF
A 
(19)+!&)9)9)*19)+!&)9)9)+BJ)+"'):):),QWQZA-F)G)G),QWQZA-F)G)G)*QQ)*Q		9 		9 		9 	B6*** ..r2277999 aK a= 	>1e$Q&Au)==A bL	Q s g++%#++z Hr&   c	                    |dk    rt          d| dd           | j                                        }	|	                                 t	          j        |j        j        |j                  }
t          j
        |
|j        |j        f|j                  }t          | dd	
          }t	          j        |j        j        |j                  }
t          j
        |
|j        |j        f|j                  }d| z  |z  }d|j        dd<   t          j        |	j        |	j        t	          j        |	j                  |j        |j        t	          j        |j                  |j        |j        t	          j        |j                  t#          |j        d         |j        d         z            t#          |j        d         |j        d         z            |	j        d         |	j        d         |j        d                    t'          |||           |j        dk    rt+          d           |S |j        }d}||k     r||k    rt-          ||          }|                                                    |                                          }||k     rn|dk    r|}|}n||z  }|||z  z   }|}| |z  }d|j        dd<   t          j        |	j        |	j        t	          j        |	j                  |j        |j        t	          j        |j                  |j        |j        t	          j        |j                  t#          |j        d         |j        d         z            t#          |j        d         |j        d         z            |	j        d         |	j        d         |j        d                    ~t'          |||           ||                                                    |                                          z  }|||z  z   }|d         r |d         d         |z  |d         d         z   }|||z  z
  }|dz  }|j        }||k     r||k    |S )a  Smooth T with CGNR by solving A T = 0, subject to nullspace and sparsity constraints.

    Parameters
    ----------
    A : csr_matrix, bsr_matrix
        SPD sparse NxN matrix
        Should be at least nonsymmetric or indefinite
    T : bsr_matrix
        Tentative prolongator, a NxM sparse matrix (M < N).
        This is initial guess for the equation A T = 0.
        Assumed that T B_c = B_f
    B : array
        Near-nullspace modes for coarse grid, i.e., B_c.
        Has shape (M,k) where k is the number of coarse candidate vectors.
    BtBinv : array
        3 dimensional array such that,
        BtBinv[i] = pinv(B_i.H Bi), and B_i is B restricted
        to the neighborhood (in the matrix graph) of dof of i.
    pattern : csr_matrix, bsr_matrix
        Sparse NxM matrix
        This is the sparsity pattern constraint to enforce on the
        eventual prolongator
    maxiter : int
        maximum number of iterations
    tol : float
        residual tolerance for A T = 0
    weighting : string
        'block', 'diagonal' or 'local' construction of the diagonal
        preconditioning
        IGNORED here, only 'diagonal' preconditioning is used.
    Cpt_params : tuple
        Tuple of the form (bool, dict).  If the Cpt_params[0] = False, then
        the standard SA prolongation smoothing is carried out.  If True, then
        dict must be a dictionary of parameters containing, (1) P_I: P_I.T is
        the injection matrix for the Cpts, (2) I_F: an identity matrix
        for only the F-points (i.e. I, but with zero rows and columns for
        C-points) and I_C: the C-point analogue to I_F.

    Returns
    -------
    T : bsr_matrix
        Smoothed prolongator using CGNR to solve A T = 0,
        subject to the constraints, T B_c = B_f, and T has no nonzero
        outside of the sparsity pattern in pattern.

    See Also
    --------
    The principal calling routine,
    pyamg.aggregation.smooth.energy_prolongation_smoother

    r(   zWeighting of z unused.r   )
stacklevelr1   r/   r   TrR   rU   rX   Nr   z^Error in sa_energy_min(..).  Initial R no nonzeros on a level. Returning tentative prolongatorrY   rZ   )r   rA   r   sort_indicesr   r[   r   r   r2   r   r8   r   r   r   r   r\   r   r   r   r%   r]   r^   r   r6   r_   )r`   rA   r   r   ra   rb   rc   rF   rd   Ahrg   re   rf   rh   ATri   rj   rk   rl   rK   rm   rn   AP_tempro   s                           r$   cgnr_prolongation_smoothingrw     s   j J0Y000Q???? 
BOO HW\'qw777E		E7?GNC!(
0 
0 
0B 1$///D HW\'qw777E5'/7>B '	/ 	/ 	/A	aBAF111I$RY
%'Xbg%6%6%'Y
%'Xbg%6%6%&Xqy%'Xaf%5%5%(AKN)B%C%C%(AKN)B%C%C%'\!_bl1o%&[^	5 	5 	5 1f%%%uzz 0 	1 	1 	1 EE 	
A
g++%#++ q$ ++--((++0022C<< 66AFF&=DDF
A A#
(BJ)+"'):):)0)+',)?)?)+BJ)+"'):):),QWQZA-F)G)G),QWQZA-F)G)G)+a)+a!+a.		J 		J 		J  	B6*** ..r2277999 aK a= 	>1e$Q&Au)==A bL	Q { g++%#++J Hr&   c                     t          |          D ]2}| |         }t          j        ||||dz                      |||dz   <   3dS )a  Apply the first k Givens rotations in Q to v.

    Parameters
    ----------
    Q : list
        list of consecutive 2x2 Givens rotations
    v : array
        vector to apply the rotations to
    k : int
        number of rotations to apply.

    Returns
    -------
    v is changed in place

    Notes
    -----
    This routine is specialized for GMRES.  It assumes that the first Givens
    rotation is for dofs 0 and 1, the second Givens rotation is for dofs 1 and
    2, and so on.

    r   N)r>   r   dot)QvkjQlocs        r$   apply_givensr   g  sW    . 1XX * *t6$!AaC%))!AaC%* *r&   c	                 `   t          j        |j        j        |j                  }	t          j        |	|j        |j        f|j                  }
t          | j        |j        |j                  }g }g }t          j        |dz   |dz   f|          }|dk    rt          | dd          }n|dk    ryt          | | j        d	         d
          }t          j        |t          j        |j        d	                   t          j        |j        d	         dz             f| j                  }n|dk    rzt          j        |           t          j        | j        d	         df| j                  z  }t          j        |          }dt          j        ||d	k                       z  ||d	k    <   nt#          d          t          j        |j        j        |j                  }	t          j        |	|j        |j        f|j                  }t%          j        | j        | j        t          j        | j                  |j        |j        t          j        |j                  |j        |j        t          j        |j                  t+          |j        d	         |j        d	         z            t+          |j        d         |j        d         z            | j        d	         | j        d         |j        d                    |xj        dz  c_        |dv rt-          ||          }n||z  }t/          |||           |j        d	k    rt3          d           |S t          j        |j                                        |j        z                                            }t          j        |dz   f|          }||d	<   |dk    r|                    d|z  |z             d}||dz
  k     rG||k    r@|dz   }d|
j        dd<   t%          j        | j        | j        t          j        | j                  ||         j        ||         j        t          j        ||         j                  |
j        |
j        t          j        |
j                  t+          |j        d	         |j        d	         z            t+          |j        d         |j        d         z            | j        d	         | j        d         |j        d                    |dv rt-          |
|          }
n||
z  }
t/          |
||           |                    |
                                           t?          |dz             D ]t}||                                                              ||dz                                                      |||f<   ||dz            |||f         ||         z  z
  ||dz   <   ut          j        ||dz            j                                        ||dz            j        z                                            ||dz   |f<   ||dz   |f         dk    r"d||dz   |f         z  ||dz            z  ||dz   <   |d	k    rtC          ||dd|f         |           ||dz   |f         d	k    ra|||f         }||dz   |f         }t          j        |          }t          j        |          }||k     r/||z  }t          j        |          t          j        |          z  }n||z  }|t          j        |          z  }t          j        |dz  |dz  z             }||z  }||z  |z  }t          j"        |t          j        |          g| |gg|          }|                    |           t          j#        ||||dz                      |||dz   <   t          j#        |d	ddf         |||dz   |f                   |||f<   d||dz   |f<   t          j        ||dz                      }||dz
  k     r||k    @|dk    r[tI          j%        |d	|dz   d	|dz   f         |d	|dz                      } t?          |dz             D ]}|| |         ||         z  z   }|d	         r |d         d         |z  |d         d         z   }|S )a|  Smooth T with GMRES by solving A T = 0 subject to nullspace and sparsity constraints.

    Parameters
    ----------
    A : csr_matrix, bsr_matrix
        SPD sparse NxN matrix
        Should be at least nonsymmetric or indefinite
    T : bsr_matrix
        Tentative prolongator, a NxM sparse matrix (M < N).
        This is initial guess for the equation A T = 0.
        Assumed that T B_c = B_f
    B : array
        Near-nullspace modes for coarse grid, i.e., B_c.
        Has shape (M,k) where k is the number of coarse candidate vectors.
    BtBinv : array
        3 dimensional array such that,
        BtBinv[i] = pinv(B_i.H Bi), and B_i is B restricted
        to the neighborhood (in the matrix graph) of dof of i.
    pattern : csr_matrix, bsr_matrix
        Sparse NxM matrix
        This is the sparsity pattern constraint to enforce on the
        eventual prolongator
    maxiter : int
        maximum number of iterations
    tol : float
        residual tolerance for A T = 0
    weighting : string
        'block', 'diagonal' or 'local' construction of the diagonal
        preconditioning
    Cpt_params : tuple
        Tuple of the form (bool, dict).  If the Cpt_params[0] = False, then
        the standard SA prolongation smoothing is carried out.  If True, then
        dict must be a dictionary of parameters containing, (1) P_I: P_I.T is
        the injection matrix for the Cpts, (2) I_F: an identity matrix
        for only the F-points (i.e. I, but with zero rows and columns for
        C-points) and I_C: the C-point analogue to I_F.

    Returns
    -------
    T : bsr_matrix
        Smoothed prolongator using GMRES to solve A T = 0,
        subject to the constraints, T B_c = B_f, and T has no nonzero
        outside of the sparsity pattern in pattern.

    See Also
    --------
    The principal calling routine,
    pyamg.aggregation.smooth.energy_prolongation_smoother

    r1   r/   r   r(   FTrR   r*   r   r-   r0   r3   rT   rU   rW   rV   rX   Nr   rY   rZ   )&r   r[   r   r   r2   r   r8   r   r   r   r   r	   r   r9   r:   r;   r<   r=   r   r\   r   r   r   r%   r]   r^   sqrtr   r_   appendr,   r>   r6   r   arrayry   lasolve)!r`   rA   r   r   ra   rb   rc   rF   rd   rg   AVxtyperz   VHrf   rJ   rh   normrgrj   r}   h1h2h1_magh2_magmutaudenomcsQblockys!                                    r$   gmres_prolongation_smoothingr     sZ   n HW\'qw777E		E7?GNC!(
0 
0 
0B 17AGQW--E
A
A 	'!)WQY'u555A JAu$777	g		a1;q>DIII $	$*Q-(@(@"$)DJqM!O"<"<">'(w0 0 0 
g		F1IIbgqwqz1oQW====}QRVAa1fI...Q!V5666 HW\'qw777E5'/7>B '	/ 	/ 	/A$QXqy%'Xaf%5%5%&Xqy%'Xaf%5%5%&Xqy%'Xaf%5%5%(AKN)B%C%C%(AKN)B%C%C%&[^Q[^%&[^	5 	5 	5 FFdNFF )))q$F 1f%%%uzz 2 	3 	3 	3 GQV%%''.335566E
'!)U+++AAaD s{{	#e)Q 	A
 gai--ECKKaC 
(19)+!&)9)9)*1adl)+!A$))<)<)+BJ)+"'):):),QWQZA-F)G)G),QWQZA-F)G)G)*QQ)*Q		9 		9 		9 ---B%%BBbB 	B6***	 qs 	+ 	+At~~''001Q388==??AadGqsVa1gadl*AacFF GQqsV[2244QqsV[@EEGGHH!A#q&	 QqS!V9Aac1fIo1Q3/AacF q55AaaadGQ''' QqS!V9>>1a4B1Q36BVBZZFVBZZFUl2&&rvbzz1UmGFAI	122EuAs
5 AX2<??3qb!W=UKKKFHHV vfa!A#h//Aa!eH fVAqqqD\1QqsUAX;77AadGAac1fIq1vQ gai--ECKKZ 	BwwHQq1ua!e|_a!A#h//qs 	 	AAaD1IAA !} :qM% "Z]5%99Hr&   cg   :0yE>c                    |dk     rt          d          |dk    rt          d          t          j        |           r|                     dd          } n$t          j        |           rnt          d          t          j        |          r|                    dd          }n$t          j        |          rnt          d	          |j        d         | j        d         k    rt          d
          |j        d         |j        d         k    rt          d          t          |j	        | j	                  dk    r|S t          j        |          st          d          |i }|i }d|v r"|d         dk    r|
                    dd           d|v r"|d         dk    r|
                    dd           |t          j        t          j        t          | j                            | j                                        | j                                        f| j        d         | j        d         z  | j        d         | j        d         z  f          }t          |j	        | j	                  dk    r|S |	dk    r|                                 t'          |j        d         |j        d         z            t'          |j        d         |j        d         z            f}t          j        t          j        |j        j                  |j        |j        f|          }|                                }t)          |	          D ]}||z  }d|v r6d|v r2t+          ||d                   }t-          ||d                   }||z  }nXd|v rt-          ||d                   }n=d|v rt+          ||d                   }n"t          |          dk    rt          d          t/          ||j        d         |j        d                   }|                                 n|                                }d|v r6d|v r2t+          ||d                   }t-          ||d                   }||z  }nXd|v rt-          ||d                   }n=d|v rt+          ||d                   }n"t          |          dk    rt          d          d|j        dd<   |                                 |d         r"|d         d         |z  }|d         d         |z   }t3          ||          }|d         r|j        d         | j        d         k    sd|v r;t5          |||||          }|d         r |d         d         |z  |d         d         z   }|dk    rt7          | |||||||
|	  	        }n;|dk    rt9          | |||||||
|	  	        }n|dk    rt;          | |||||||
|	  	        }|                                 t          |          dk    sd|v s
|d         du r|S d|v rod|v rkt+          ||d                   }t-          ||d                   }d|j        dd<   d|j        dd<   ||z   }d|j        dd<   |                    |          }nEd|v rt-          ||d                   }n*d|v rt+          ||d                   }nt          d          tA          | ||||||ddd|
i ddi          }|S )a-  Minimize the energy of the coarse basis functions (columns of T).

    Both root-node and non-root-node style prolongation smoothing is available,
    see Cpt_params description below.

    Parameters
    ----------
    A : csr_matrix, bsr_matrix
        Sparse NxN matrix
    T : bsr_matrix
        Tentative prolongator, a NxM sparse matrix (M < N)
    Atilde : csr_matrix
        Strength of connection matrix
    B : array
        Near-nullspace modes for coarse grid.  Has shape (M,k) where
        k is the number of coarse candidate vectors.
    Bf : array
        Near-nullspace modes for fine grid.  Has shape (N,k) where
        k is the number of coarse candidate vectors.
    Cpt_params : tuple
        Tuple of the form (bool, dict).  If the Cpt_params[0] = False, then the
        standard SA prolongation smoothing is carried out.  If True, then
        root-node style prolongation smoothing is carried out.  The dict must
        be a dictionary of parameters containing, (1) for P_I, P_I.T is the
        injection matrix for the Cpts, (2) I_F is an identity matrix for only the
        F-points (i.e. I, but with zero rows and columns for C-points) and I_C is
        the C-point analogue to I_F.  See Notes below for more information.
    krylov : string
        'cg' for SPD systems.  Solve A T = 0 in a constraint space with CG
        'cgnr' for nonsymmetric and/or indefinite systems.
        Solve A T = 0 in a constraint space with CGNR
        'gmres' for nonsymmetric and/or indefinite systems.
        Solve A T = 0 in a constraint space with GMRES
    maxiter : integer
        Number of energy minimization steps to apply to the prolongator
    tol : scalar
        Minimization tolerance
    degree : int
        Generate sparsity pattern for P based on (Atilde^degree T)
    weighting : string
        'block', 'diagonal' or 'local' construction of the diagonal preconditioning
        'local' Uses a local row-wise weight based on the Gershgorin estimate.
        Avoids any potential under-damping due to inaccurate spectral
        radius estimates.
        'block' Uses a block diagonal inverse of A if A is BSR.
        'diagonal' Uses the inverse of the diagonal of A
    prefilter : dictionary
        Filter elements by row in sparsity pattern for P to reduce operator and
        setup complexity. If None or an empty dictionary, then no dropping in P
        is done.  If postfilter has key 'k', then the largest 'k' entries  are
        kept in each row.  If postfilter has key 'theta', all entries such that
        :math:`P[i,j] < kwargs['theta']*max(abs(P[i,:]))`
        are dropped.  If postfilter['k'] and postfiler['theta'] are present,
        then they are used with the union of their patterns.
    postfilter : dictionary
        Filters elements by row in smoothed P to reduce operator complexity.
        Only supported if using the rootnode_solver. If None or an empty
        dictionary, no dropping in P is done. If postfilter has key 'k',
        then the largest 'k' entries  are kept in each row.  If postfilter
        has key 'theta', all entries such that
        :math::`P[i,j] < kwargs['theta']*max(abs(P[i,:]))`
        are dropped.  If postfilter['k'] and postfiler['theta'] are present,
        then they are used with the union of their patterns.

    Returns
    -------
    T : bsr_matrix
        Smoothed prolongator

    Notes
    -----
    Only 'diagonal' weighting is supported for the CGNR method, because
    we are working with A^* A and not A.

    When Cpt_params[0] == True, root-node style prolongation smoothing is used
    to minimize the energy of columns of T.  Essentially, an identity block is
    maintained in T, corresponding to injection from the coarse-grid to the
    fine-grid root-nodes.  See [2011OlScTu]_ for more details, and see
    util.utils.get_Cpt_params for the helper function to generate Cpt_params.

    If Cpt_params[0] == False, the energy of columns of T are still
    minimized, but without maintaining the identity block.

    See [1999cMaBrVa]_ for more details on smoothed aggregation.

    Examples
    --------
    >>> from pyamg.aggregation import energy_prolongation_smoother
    >>> from pyamg.gallery import poisson
    >>> from scipy.sparse import coo_matrix
    >>> import numpy as np
    >>> data = np.ones((6,))
    >>> row = np.arange(0,6)
    >>> col = np.kron([0,1],np.ones((3,)))
    >>> T = coo_matrix((data,(row,col)),shape=(6,2)).tocsr()
    >>> print(T.toarray())
    [[1. 0.]
     [1. 0.]
     [1. 0.]
     [0. 1.]
     [0. 1.]
     [0. 1.]]
    >>> A = poisson((6,),format='csr')
    >>> B = np.ones((2,1),dtype=float)
    >>> P = energy_prolongation_smoother(A,T,A,B, None, (False,{}))
    >>> print(P.toarray())
    [[1.         0.        ]
     [1.         0.        ]
     [0.66666667 0.33333333]
     [0.33333333 0.66666667]
     [0.         1.        ]
     [0.         1.        ]]

    References
    ----------
    .. [1999cMaBrVa] Jan Mandel, Marian Brezina, and Petr Vanek
       "Energy Optimization of Algebraic Multigrid Bases"
       Computing 62, 205-228, 1999
       http://dx.doi.org/10.1007/s006070050022

    .. [2011OlScTu] Olson, L. and Schroder, J. and Tuminaro, R.,
       "A general interpolation strategy for algebraic
       multigrid using energy minimization", SIAM Journal
       on Scientific Computing (SISC), vol. 33, pp.
       966--991, 2011.

    r   zmaxiter must be > 0r   ztol must be <= 1)r   r   F)r   r,   z"A must be csr_matrix or bsr_matrixz"T must be csr_matrix or bsr_matrixz1T row-blocksize should be the same as A blocksizezDB is the candidates for the coarse grid.   num_rows(b) = num_cols(T)zAtilde must be csr_matrixNthetar/   r|   zUnrecognized prefilter optionr3   rY   rZ   
secondpassr   cgnrgmreszUnrecognized postfilter optionr   T)krylovrb   rc   rD   rF   	prefilter
postfilter)!r=   r   r4   r?   r5   	TypeErrorr   r   minr]   pop
csr_matrixr   r;   lenr   r,   r   rs   r   r>   r   r   r
   r   r   r   rp   rw   r   r7   r6   energy_prolongation_smoother)r`   rA   Atilder   Bfrd   r   rb   rc   rD   rF   r   r   r   ra   
AtildeCopyrL   pattern_thetar   T_thetaT_kT_filters                         r$   r   r   f  s   H {{.///
Qww+,,,Q >GGf5G11		q	!	! ><===Q >GGf5G11		q	!	! ><==={1~Q''LMMMwqzQWQZ 7 8 8 	8 15!%A (( 53444	
99W#5#:#:gt$$$:Jw$71$<$<w%%% ~"BGC	NN$;$;$%INN$4$4ahmmoo$G*+'!*Q[^*C*+'!*Q[^*C*EF F F 15!%A zz 	
QWQZA.//QWQZA.//1#RWQY_%=%=qy!($S*/1 1 1 [[]]
v 	+ 	+A 7*GG iC9$4$4.w	'8JKKM#GYs^<<G}$GGI#GYs^<<GG	!!()G2DEEGG^^a<=== !+a.!+a.AA &&((iC9$4$4.w	'8JKKM#GYs^<<G}$GGI#GYs^<<GG	!!()G2DEEGG^^a<===QQQ !} 1Q-&0Q-&0
 Aw''F
 
A >AGAJQ77:%%Aw2v66a= 	>1e$Q&Au)==A
 ~~%aAvw&-sIzK K	6		'1a(/iM M	7		(Aq&')0#y*N N  
ZA		:%%a=E!!*
!2!2$Q
7(;<<Az#// QQQS=aaa::h''	
		 JsO44	J		%aG)<==9:::
 	%Q%+QJ,2A)-a/8/11=t0D	F 	F 	FA Hr&   )r'   r   Fr(   )r'   r   )r0   N)r(   N)r   r   r   r   r0   NN)!__doc__warningsr   numpyr   scipyr   scipy.linalglinalgr    r   
util.utilsr   r   r	   r
   r   r   r   r   util.linalgr   utilr   r%   rM   rP   rp   rw   r   r   r    r&   r$   <module>r      s   9 9                                                6 5 5 5 5 5      ) ) )X DEAKM M M M`> > > >D =Ag g g gV GKl l l l^* * *: EI` ` ` `H >B5<<@s s s s s sr&   