
    _-Ph:                     |    d Z ddlmZ ddlZddlmZmZmZm	Z	m
Z
 ddlmZ ddlmZ dd	ZddZd ZddZ	 	 ddZdS )z$Classical AMG Interpolation methods.    )warnN)
csr_matrix
bsr_matrixisspmatrix_csrisspmatrix_bsrSparseEfficiencyWarning   )amg_core) classical_strength_of_connectionminc                 :   t          |           st          d          t          |          st          d          |t          | ||          }n|                                }|                                 d|j        dd<   |                    |           }t          j        | j	                  }t          j        | j        d         |j	        |j        ||           |d         }t          j        ||j                  }t          j        || j                  }t          j        | j        d         | j	        | j        | j        |j	        |j        |j        ||||           t          j        |          }	| j        d         }
t%          |||f|
|	g	          S )
a  Create prolongator using direct interpolation.

    Parameters
    ----------
    A : csr_matrix
        NxN matrix in CSR format
    C : csr_matrix
        Strength-of-Connection matrix
        Must have zero diagonal
    theta : float in [0, 1), default None
        theta value defining strong connections in a classical AMG
        sense. Provide if a different SOC is used for P than for
        CF-splitting; otherwise, theta = None.
    norm : string, default 'abs'
        Norm used in redefining classical SOC. Options are 'min' and
        'abs' for CSR matrices. See strength.py for more information.
    splitting : array
        C/F splitting stored in an array of length N

    Returns
    -------
    P : csr_matrix
        Prolongator using direct interpolation

    Examples
    --------
    >>> from pyamg.gallery import poisson
    >>> from pyamg.classical.interpolate import direct_interpolation
    >>> import numpy as np
    >>> A = poisson((5,),format='csr')
    >>> splitting = np.array([1,0,1,0,1], dtype='intc')
    >>> P = direct_interpolation(A, A, splitting)
    >>> print(P.toarray())
    [[1.  0.  0. ]
     [0.5 0.5 0. ]
     [0.  1.  0. ]
     [0.  0.5 0.5]
     [0.  0.  1. ]]
    expected csr_matrix for Azexpected csr_matrix for CNthetanorm      ?r   dtypeshape)r   	TypeErrorr   copyeliminate_zerosdatamultiplynp
empty_likeindptrr
   rs_direct_interpolation_pass1r   indicesemptyr   rs_direct_interpolation_pass2sumr   )AC	splittingr   r   P_indptrnnz	P_indicesP_datancns              [/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/pyamg/classical/interpolate.pydirect_interpolationr/      s   P ! 53444! 53444,Qe$GGGFFHH AF111I	

1A}QX&&H*171:qx+4h@ @ @
2,CHN333IXc)))F*171:qxAF+,8QY+4h	6S S S 
			B	
Avy(3Ar7CCCC    Tc                    t          |           st          d          t          |          st          d          t          j        |          }| j        d         }|t          | ||          }n|                                }|r2t          j        | j        d         |j	        |j
        |j        |           |                                 d|j        dd<   |                    |           }t          j        | j	                  }t          j        | j        d         |j	        |j
        ||           |d         }	t          j        |	|j                  }
t          j        |	| j                  }t          j        | j        d         | j	        | j
        | j        |j	        |j
        |j        |||
||           t'          ||
|f||g	          S )
a8  Create prolongator using distance-1 classical interpolation.

    Parameters
    ----------
    A : csr_matrix
        NxN matrix in CSR format
    C : csr_matrix
        Strength-of-Connection matrix
        Must have zero diagonal
    splitting : array
        C/F splitting stored in an array of length N
    theta : float in [0,1), default None
        theta value defining strong connections in a classical AMG
        sense. Provide if a different SOC is used for P than for
        CF-splitting; otherwise, theta = None.
    norm : string, default 'abs'
        Norm used in redefining classical SOC. Options are 'min' and
        'abs' for CSR matrices. See strength.py for more information.
    modified : bool, default True
        Use modified classical interpolation. More robust if RS coarsening with
        second pass is not used for CF splitting. Ignores interpolating from strong
        F-connections without a common C-neighbor.

    Returns
    -------
    P : csr_matrix
        Prolongator using classical interpolation; see Sec. 3 Eq. (8)
        of [0] for modified=False and Eq. (9) for modified=True.

    Examples
    --------
    >>> from pyamg.gallery import poisson
    >>> from pyamg.classical.interpolate import classical_interpolation
    >>> import numpy as np
    >>> A = poisson((5,),format='csr')
    >>> splitting = np.array([1,0,1,0,1], dtype='intc')
    >>> P = classical_interpolation(A, A, splitting, 0.25)
    >>> print(P.todense())
    [[ 1.   0.   0. ]
     [ 0.5  0.5  0. ]
     [ 0.   1.   0. ]
     [ 0.   0.5  0.5]
     [ 0.   0.   1. ]]
    r   z"Expected csr_matrix SOC matrix, C.r   Nr   r   r   r   r   )r   r   r   r$   r   r   r   r
   remove_strong_FF_connectionsr   r!   r   r   r   r    rs_classical_interpolation_pass1r"   r    rs_classical_interpolation_pass2r   )r%   r&   r'   r   r   modifiedr,   r-   r(   r)   r*   r+   s               r.   classical_interpolationr6   V   s   Z ! 53444! ><===				B	
A,Qe$GGGFFHH  A-agaj!(AI./fi	A 	A 	A
 AF111I	

1A}QX&&H-agaj!(./iHN N N
2,CHN333IXc)))F-agaj!(AI./fah	./fi.7K K K
 vy(3Ar7CCCCr0   c                 j   t          |           r| j        d         }| j        d         |z  }n{t          |           r| j        d         }d}n\	 |                                 } t          dt                     | j        d         }d}n"# t          $ r}t          d          |d}~ww xY wt          j
        t          j        dg| j        j                  t          j        || j        j                            }|d         }t          j        d|d| j        j                  }|dk    r1t!          t          j        |f| j                  ||f||g	          }nWt          j        |t          j        || j                  gz  | j                  }	t'          |	||f||g||z  ||z  g
          }|S )a  Create interpolation operator by injection.

    Parameters
    ----------
    A : {csr_matrix}
        NxN matrix in CSR format or BSR format
    splitting : array
        C/F splitting stored in an array of length N

    Returns
    -------
    NxNc interpolation operator, P

    Notes
    -----
    C-points are interpolated by value and F-points are not interpolated.

    Examples
    --------
    >>> from pyamg.gallery import poisson
    >>> from pyamg.classical.interpolate import injection_interpolation
    >>> import numpy as np
    >>> A = poisson((5,),format='csr')
    >>> splitting = np.array([1,0,1,0,1], dtype='intc')
    >>> P = injection_interpolation(A, splitting)
    >>> print(P.todense())
    [[1. 0. 0.]
     [0. 0. 0.]
     [0. 1. 0.]
     [0. 0. 0.]
     [0. 0. 1.]]
    r      Implicit conversion of A to csr(Invalid matrix type, must be CSR or BSR.Nr   r   )startstopstepr   r   	blocksizer   )r   r?   r   r   tocsrr   r   	Exceptionr   r   appendarrayr   r   cumsumaranger   onesidentityr   )
r%   r'   r?   r-   eP_rowptrr,   	P_colindsPr+   s
             r.   injection_interpolationrL      s   B a OKN	GAJ"			 
OGAJ			O		A24KLLL
AII 	O 	O 	OFGGQN	O y1#QX^<<<9AHNCCCE EH	"B	!(.IIIIA~~QW555 (,45r7< < < "bk)17CCCDDAGTTT	84I@V	k2i<8: : : Hs   8B 
B&B!!B&Fc           	         t          |           r+| j        d         }t          | j        d         |z            }n{t	          |           r| j        d         }d}n\	 |                                 } t          dt                     | j        d         }d}n"# t          $ r}t          d          |d}~ww xY wt          j        |          }t          j        |dz   f| j        j                  }t          j        |f| j        j                  }	t          j        |f| j                  }
|dk    r|r@t          j        ||	|
| j        | j        | j        |           t'          |
|	|f||g          }nt          j        ||	|
|j        |j        |j        |           t          j        |f| j                  }
t'          |
|	|f||g          }nt          j        ||	|
|j        |j        |j        |           t          j        |t          j        || j                  gz  | j                  }
t/          |
|	|f||g||z  ||z  g          }|S )	af  Create one-point interpolation operator.

    Parameters
    ----------
    A : {csr_matrix}
        NxN matrix in CSR format
    C : {csr_matrix}
        Strength-of-Connection matrix (does not need zero diagonal)
    splitting : array
        C/F splitting stored in an array of length N
    by_val : bool
        For CSR matrices only right now, use values of -Afc in interp as an
        approximation to P_ideal. If false, F-points are interpolated by value
        with weight 1.

    Returns
    -------
    NxNc interpolation operator, P

    Notes
    -----
    C-points are interpolated by value and F-points are interpolated by value
    from their strongest-connected C-point neighbor.

    Examples
    --------
    >>> from pyamg.gallery import poisson
    >>> from pyamg.classical.interpolate import one_point_interpolation
    >>> import numpy as np
    >>> A = poisson((5,),format='csr')
    >>> splitting = np.array([1,0,1,0,1], dtype='intc')
    >>> P = one_point_interpolation(A, A, splitting)
    >>> print(P.todense())
    [[1. 0. 0.]
     [1. 0. 0.]
     [0. 1. 0.]
     [0. 1. 0.]
     [0. 0. 1.]]
    r   r8   r9   r:   Nr   r   r>   )r   r?   intr   r   r@   r   r   rA   r   r   r$   r"   r   r   r
   one_point_interpolationr!   r   r   rF   rC   rG   r   )r%   r&   r'   by_valr?   r-   rH   r,   rI   rJ   r+   rK   s               r.   rO   rO      s   P a OKN	
Y&''			 
OGAJ			O		A24KLLL
AII 	O 	O 	OFGGQN	O 
			Bx1ahn555H!QX^444IXqd!'***FA~~ 	I,Xy&!(-.Y	K K KFIx8BHHHAA,Xy&!(-.Y	K K KWaT111FFIx8BHHHAA(9fah)*AFI	G 	G 	G!R[!'BBBCC17SSS	84I@V'k9R<8: : : Hs   8B 
B3B..B3皙?absr8   
   c                    t          |           r!t          | |d|          }| j        d         }	nt          |           rd}	t          | |d|          }nb	 |                                 } t          dt                     t          | |d|          }d}	n"# t          $ r}
t          d          |
d}
~
ww xY wt          j
        t          j        |dk              d         | j        j        	          }|j        d         }t          j        |dz   | j        j        	          }t!          j        ||j        |j        |||           |d
         }t          j        || j        j        	          }t          |           rt          j        ||	z  |	z  | j        	          }t!          j        |||| j        | j        | j                                        |j        |j        |j        |||	||||           t/          |                    ||	|	f          ||f|	|	g||	z  | j        d         g          }n|t          j        || j        	          }t!          j        |||| j        | j        | j        |j        |j        |j        ||||||           t5          |||f|| j        d         g          }|                                 |S )a  Compute approx ideal restriction by setting RA = 0, within sparsity pattern of R.

    Parameters
    ----------
    A : {csr_matrix, bsr_matrix}
        NxN matrix in CSR or BSR format
    splitting : array
        C/F splitting stored in an array of length N
    theta : float, default 0.1
        Solve local system for each row of R for all values
            |A_ij| >= 0.1 * max_{i!=k} |A_ik|
    degree : int, default 1
        Expand sparsity pattern for R by considering strongly connected
        neighbors within 'degree' of a given node. Only supports degree 1 and 2.
    use_gmres : bool
        Solve local linear system for each row of R using GMRES.  If False, use
        direct solve.
    maxiter : int
        Maximum number of GMRES iterations
    precondition : bool
        Diagonally precondition GMRES

    Returns
    -------
    Approximate ideal restriction, R, in same sparse format as A.

    Notes
    -----
    Supports BSR (block) matrices, in addition to CSR.

    Sparsity pattern of R for the ith row (i.e. ith C-point) is the set of all
    strongly connected F-points, or the max_row *most* strongly connected
    F-points

    Examples
    --------
    >>> from pyamg.gallery import poisson
    >>> from pyamg.classical.interpolate import local_air
    >>> import numpy as np
    >>> A = poisson((5,),format='csr')
    >>> splitting = np.array([1,0,1,0,1], dtype='intc')
    >>> R = local_air(A, splitting)
    >>> print(R.todense())
    [[1.  0.5 0.  0.  0. ]
     [0.  0.5 1.  0.5 0. ]
     [0.  0.  0.  0.5 1. ]]
    T)r%   r   blockr   r   r8   Fr9   r:   Nr   r   r>   r   )r   r   r?   r   r@   r   r   rA   r   r   rC   wherer   r   r   r"   r
   approx_ideal_restriction_pass1r!   zeros$block_approx_ideal_restriction_pass2r   ravelr   reshapeapprox_ideal_restriction_pass2r   r   )r%   r'   r   r   degree	use_gmresmaxiterpreconditionr&   r?   rH   Cptsr,   R_rowptrr)   	R_colindsR_dataRs                     r.   	local_airrf   =  s   d a O,qTPTUUUKN					 
O	,qUQUVVV	O		A24KLLL01EUYZZZAII 	O 	O 	OFGGQN	O 8BHY!^,,Q/qx~FFFD	ABx1AHN333H+Hah	,0)VE E E 2,CAHN333I a N#i-	1AAA5h	6STS[67iQRQY67iy6?T[6B		D 	D 	D
 Y	'BCCYPXY"+Y!79agVWj?Y[ [ [ #QW---/)VQX01	1618QY01iQZ07	G 	G 	G 	84R<LMMMHs   >B 
B5 B00B5)Nr   )Nr   T)F)rQ   rR   r8   FrS   T)__doc__warningsr   numpyr   scipy.sparser   r   r   r   r    r
   strengthr   r/   r6   rL   rO   rf    r0   r.   <module>rn      s$   * *          , , , , , , , , , , , , , ,       7 7 7 7 7 7FD FD FD FDRTD TD TD TDn= = =@M M M M` ;<8<` ` ` ` ` `r0   