
    _-PhG                         d Z ddlmZ ddlZddlmZmZmZm	Z	 ddl
mZ ddlmZ ddlmZmZmZmZ ddlmZmZmZmZmZmZmZ d	d
lmZmZmZmZ d	dl m!Z! d	dl"m#Z#m$Z$m%Z% ddl&m'Z' ddddddddifdddifdddifddddfdfddddfdZ(	 ddZ)dS )z"Support for aggregation-based AMG.    )warnN)
csr_matrixisspmatrix_csrisspmatrix_bsrSparseEfficiencyWarning)MultilevelSolver)change_smoothers)eliminate_diag_dom_nodesget_blocksize levelize_strength_or_aggregation%levelize_smooth_or_improve_candidates) classical_strength_of_connection symmetric_strength_of_connection evolution_strength_of_connection#energy_based_strength_of_connectiondistance_strength_of_connectionalgebraic_distanceaffinity_distance   )standard_aggregationnaive_aggregationlloyd_aggregationpairwise_aggregation)fit_candidates)jacobi_prolongation_smoother richardson_prolongation_smootherenergy_prolongation_smoother   )relaxation_as_linear_operator	hermitian	symmetricstandardjacobiomegagUUUUUU?block_gauss_seidelsweep   )r&   
iterations
   Fc           
      T   t          |           sWt          |           sH	 t          |           } t          dt                     n"# t
          $ r}t          d          |d}~ww xY w|                                 } |dvrt          d          || _	        | j
        d         | j
        d         k    rt          d          |t          j        t          j        t          | j
        d         t          |           z            df| j        	          t          j        t          |           | j        	                    }nt          j        || j        	          }t'          |j
                  dk    r|                    d
d          }|j
        d         | j
        d         k    rt          d          |j
        d         t          |           k     rt          d           | j	        dk    r||                                }nt          j        || j        	          }t'          |j
                  dk    r|                    d
d          }|j
        d         |j
        d         k    rt          d          |j
        d         | j
        d         k    rt          d          t-          ||
|          \  }
}}t-          ||
|          \  }
}}t/          |	|
          }	t/          ||
          }g }|                    t3          j                               | |d
         _        ||d
         _        | j	        dk    r||d
         _        t'          |          |
k     rt          |d
         j        j
        d         t          |d
         j                  z            |k    rlt=          |||||	||           t'          |          |
k     rDt          |d
         j        j
        d         t          |d
         j                  z            |k    lt3          |fi |}t?          |||           |S )a  Create a multilevel solver using classical-style Smoothed Aggregation (SA).

    Parameters
    ----------
    A : csr_matrix, bsr_matrix
        Sparse NxN matrix in CSR or BSR format

    B : None, array_like
        Right near-nullspace candidates stored in the columns of an NxK array.
        The default value B=None is equivalent to B=ones((N,1))

    BH : None, array_like
        Left near-nullspace candidates stored in the columns of an NxK array.
        BH is only used if symmetry='nonsymmetric'.
        The default value B=None is equivalent to BH=B.copy()

    symmetry : string
        'symmetric' refers to both real and complex symmetric
        'hermitian' refers to both complex Hermitian and real Hermitian
        'nonsymmetric' i.e. nonsymmetric in a hermitian sense
        Note, in the strictly real case, symmetric and hermitian are the same.
        Note, this flag does not denote definiteness of the operator.

    strength : string or list
        Method used to determine the strength of connection between unknowns of
        the linear system.  Method-specific parameters may be passed in using a
        tuple, e.g. strength=('symmetric',{'theta' : 0.25 }). If strength=None,
        all nonzero entries of the matrix are considered strong.
        Choose from 'symmetric', 'classical', 'evolution', 'algebraic_distance',
        'affinity', ('predefined', {'C' : csr_matrix}), None

    aggregate : string or list
        Method used to aggregate nodes.
        Choose from 'standard', 'lloyd', 'naive', 'pairwise',
        ('predefined', {'AggOp' : csr_matrix})

    smooth : list
        Method used to smooth the tentative prolongator.  Method-specific
        parameters may be passed in using a tuple, e.g.  smooth=
        ('jacobi',{'filter' : True }).
        Choose from 'jacobi', 'richardson', 'energy', None

    presmoother : tuple, string, list
        Defines the presmoother for the multilevel cycling.  The default block
        Gauss-Seidel option defaults to point-wise Gauss-Seidel, if the matrix
        is CSR or is a BSR matrix with blocksize of 1.

    postsmoother : tuple, string, list
        Same as presmoother, except defines the postsmoother.

    improve_candidates : tuple, string, list
        The ith entry defines the method used to improve the candidates B on
        level i.  If the list is shorter than max_levels, then the last entry
        will define the method for all levels lower.  If tuple or string, then
        this single relaxation descriptor defines improve_candidates on all
        levels.
        The list elements are relaxation descriptors of the form used for
        presmoother and postsmoother.  A value of None implies no action on B.

    max_levels : integer
        Maximum number of levels to be used in the multilevel solver.

    max_coarse : integer
        Maximum number of variables permitted on the coarse grid.

    diagonal_dominance : bool, tuple
        If True (or the first tuple entry is True), then avoid coarsening
        diagonally dominant rows.  The second tuple entry requires a
        dictionary, where the key value 'theta' is used to tune the diagonal
        dominance threshold.

    keep : bool
        Flag to indicate keeping extra operators in the hierarchy for
        diagnostics.  For example, if True, then strength of connection (C),
        tentative prolongation (T), and aggregation (AggOp) are kept.

    Other Parameters
    ----------------
    cycle_type : ['V','W','F']
        Structrure of multigrid cycle

    coarse_solver : ['splu', 'lu', 'cholesky, 'pinv', 'gauss_seidel', ... ]
        Solver used at the coarsest level of the MG hierarchy.
        Optionally, may be a tuple (fn, args), where fn is a string such as
        ['splu', 'lu', ...] or a callable function, and args is a dictionary of
        arguments to be passed to fn.

    Returns
    -------
    ml : MultilevelSolver
        Multigrid hierarchy of matrices and prolongation operators

    See Also
    --------
    MultilevelSolver, classical.ruge_stuben_solver,
    aggregation.smoothed_aggregation_solver

    Notes
    -----
        - This method implements classical-style SA, not root-node style SA
          (see aggregation.rootnode_solver).

        - The additional parameters are passed through as arguments to
          MultilevelSolver.  Refer to pyamg.MultilevelSolver for additional
          documentation.

        - At each level, four steps are executed in order to define the coarser
          level operator.

          1. Matrix A is given and used to derive a strength matrix, C.

          2. Based on the strength matrix, indices are grouped or aggregated.

          3. The aggregates define coarse nodes and a tentative prolongation
             operator T is defined by injection

          4. The tentative prolongation operator is smoothed by a relaxation
             scheme to improve the quality and extent of interpolation from the
             aggregates to fine nodes.

        - The parameters smooth, strength, aggregate, presmoother, postsmoother
          can be varied on a per level basis.  For different methods on
          different levels, use a list as input so that the i-th entry defines
          the method at the i-th level.  If there are more levels in the
          hierarchy than list entries, the last entry will define the method
          for all levels lower.

          Examples are:
          smooth=[('jacobi', {'omega':1.0}), None, 'jacobi']
          presmoother=[('block_gauss_seidel', {'sweep':symmetric}), 'sor']
          aggregate=['standard', 'naive']
          strength=[('symmetric', {'theta':0.25}), ('symmetric', {'theta':0.08})]

        - Predefined strength of connection and aggregation schemes can be
          specified.  These options are best used together, but aggregation can
          be predefined while strength of connection is not.

          For predefined strength of connection, use a list consisting of
          tuples of the form ('predefined', {'C' : C0}), where C0 is a
          csr_matrix and each degree-of-freedom in C0 represents a supernode.
          For instance to predefine a three-level hierarchy, use
          [('predefined', {'C' : C0}), ('predefined', {'C' : C1}) ].

          Similarly for predefined aggregation, use a list of tuples.  For
          instance to predefine a three-level hierarchy, use [('predefined',
          {'AggOp' : Agg0}), ('predefined', {'AggOp' : Agg1}) ], where the
          dimensions of A, Agg0 and Agg1 are compatible, i.e.  Agg0.shape[1] ==
          A.shape[0] and Agg1.shape[1] == Agg0.shape[0].  Each AggOp is a
          csr_matrix.

    Examples
    --------
    >>> from pyamg import smoothed_aggregation_solver
    >>> from pyamg.gallery import poisson
    >>> from scipy.sparse.linalg import cg
    >>> import numpy as np
    >>> A = poisson((100,100), format='csr')           # matrix
    >>> b = np.ones((A.shape[0]))                      # RHS
    >>> ml = smoothed_aggregation_solver(A)            # AMG solver
    >>> M = ml.aspreconditioner(cycle='V')             # preconditioner
    >>> x,info = cg(A, b, tol=1e-8, maxiter=30, M=M)   # solve with CG

    References
    ----------
    .. [1996VaMaBr] Vanek, P. and Mandel, J. and Brezina, M.,
       "Algebraic Multigrid by Smoothed Aggregation for
       Second and Fourth Order Elliptic Problems",
       Computing, vol. 56, no. 3, pp. 179--196, 1996.
       http://citeseer.ist.psu.edu/vanek96algebraic.html

    zImplicit conversion of A to CSRzSArgument A must have type csr_matrix or bsr_matrix, or be convertible to csr_matrixN)r!   r    nonsymmetriczOExpected "symmetric", "nonsymmetric" or "hermitian" for the symmetry parameter r   r   zexpected square matrixdtypez1The shape of near null-space modes B is incorrectz\Having less target vectors, B.shape[1], than blocksize of A can degrade convergence factors.r+   zIThe number of left and right near null-space modes B and BH must be equal) r   r   r   r   r   	Exception	TypeErrorasfptype
ValueErrorsymmetryshapenpkrononesintr   r-   eyeasarraylenreshapecopyr   r   appendr   LevelABBH_extend_hierarchyr	   )r@   rA   rB   r3   strength	aggregatesmoothpresmootherpostsmootherimprove_candidates
max_levels
max_coarsediagonal_dominancekeepkwargselevelsmls                     ]/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/pyamg/aggregation/aggregation.pysmoothed_aggregation_solverrS      s+   t 1 F!2!2 F	F1A24KLLLL 	F 	F 	F > ? ?DEF	F 	


AAAA 7 8 8 	8AJwqzQWQZ1222 	yGBGSM!,<,<!<==qAQQQF=++17;;;= = Jq(((qw<<1		"a  A71:##PQQQ71:a(((( 4 5 5 5 	z^##:BBBag...B28}}!!ZZA&&x{agaj((  "@ A A Ax{agaj(( !TUUU
 	):zJJ %J
H 	)J
KK &J
I 	..@*MM 26:FFF F
MM"(**+++F2JL F2JLz^##r

f++

"
"r
"1%mF2JL&A&AABBZOO&(Iv,.@$	H 	H 	H f++

"
"r
"1%mF2JL&A&AABBZOO 
&	+	+F	+	+BRl333Is   $A 
A$AA$Tc           	      j   d }| d         j         }| d         j        }	d}
d}d}|j        dk    r>|j                                                            |j                  }
| d         j        } ||t          |           dz
                     \  }}|dk    rt          |fi |}n|dk    rt          |fi |}n|dk    rt          |fi |}n|d	v r!d
|v rt          |fi |}nt          ||	fi |}n|dk    rt          |fi |}n|dk    r|d                                         }n^|dk    rt          |fi |}nJ|dk    rt!          |fi |}n6||                                }nt#          dt%          |                      ||          \  }}|rt'          ||fi |} ||t          |           dz
                     \  }}|dk    rt)          |fi |d         }n|dk    rt+          |fi |d         }nt|dk    rt-          |fi |d         }nZ|dk    rt/          |fi |d         }n@|dk    r|d                                         }nt#          dt%          |                      ||t          |           dz
                     \  }}|yt1          j        |j        d         df|j                  }t9          ||f||          |	z  }	|	| d         _        |j        dk    r#t9          ||f|
|          |z  }|| d         _        t;          ||	          \  }}	|j        dk    rt;          ||          \  }} ||t          |           dz
                     \  }}|dk    rt=          ||||	fi |}nT|dk    rt?          ||fi |}n?|dk    rtA          ||||	ddi ffi |}n$||}nt#          dt%          |                     |j        }|dk    r|j                                        }n|dk    r	|j        }n|dk    r ||t          |           dz
                     \  }}|dk    r(t=          |
|||fi |j                                        }n|dk    r&t?          |
|fi |j                                        }n~|dk    r.tA          |
|||ddi ffi |}|j                                        }nJ||j                                        }n.t#          dt%          |                     t#          d          |r'|| d         _!        || d         _"        || d         _        || d         _#        || d         _$        | %                    tM          j'                               ||z  |z  }||_        || d         _         |	| d         _        |j        dk    r|| d         _        dS dS ) zExtend the multigrid hierarchy.

    Service routine to implement the strength of connection, aggregation,
    tentative prolongation construction, and prolongation smoothing.  Called by
    smoothed_aggregation_solver.

    c                 T    t          | t                    r| d         | d         fS | i fS )Nr   r   )
isinstancetuple)vs    rR   
unpack_argz%_extend_hierarchy.<locals>.unpack_arg)  s/    a 	Q41:"u    r.   Nr+   r   r!   	classicaldistance)ode	evolutionrA   energy_based
predefinedCr   affinityz,Unrecognized strength of connection method: r"   r   naivelloydpairwiseAggOpz Unrecognized aggregation method r,   r#   
richardsonenergyFz*Unrecognized prolongation smoother method r    zUnrecognized symmetry.)(r@   rA   r3   T	conjugateasformatformatrB   r;   r   r   r   r   r   tocsrr   r   r2   strr
   r   r   r   r   r5   zerosr4   r-   r   r   r   r   r   ra   rf   PRr>   r   r?   )rP   rD   rE   rF   rI   rL   rM   rY   r@   rA   AHrB   THfnrN   ra   flagrf   bri   rp   r3   rq   s                          rR   rC   rC      s     
 	r
Ar
A	B	B	Bz^##S]]__%%ah//BZ] HS[[]344JB	[,Q99&99	{		,Q99&99	z		+A8888	#	#	#&==0==f==AA0A@@@@AA	~		/<<V<<	|		3K	#	#	#q++F++	z		a**6**	GGIIQBQQRRR :011LD& 5$Q44V44
 Ic&kk!m455JB	Z$Q11&11!4	w!!..v..q1	w!!..v..q1	z		$Q11&11!4	|		w%%''ECGGEEFFF .s6{{1}=>>JB	~Hagaj!_AG444)2v,1==Ar
:''.F|RCCbHBF2JM
 %##DAqz^##r**B F3v;;q=122JB	X~~(Aq!>>v>>	|		,Q<<V<<	x(Aq!TE2; 3 3+13 3	Oc"ggOOPPP
 zH;CMMOO	[	 	 C	^	#	#Zs6{{1} 566
F>>,RQEEfEEGQQSSAA<0RBB6BBDNNPPAA8^^,RQD5"+ 7 7/57 7AAAZAAS#b''SSTTT1222 r
 r
r
F2JLF2JL
MM"(**+++	A	AAJF2JLF2JLz^##r
 $#rZ   )FT)*__doc__warningsr   numpyr5   scipy.sparser   r   r   r   pyamg.multilevelr   pyamg.relaxation.smoothingr	   pyamg.util.utilsr
   r   r   r   pyamg.strengthr   r   r   r   r   r   r   rE   r   r   r   r   	tentativer   rF   r   r   r   relaxation.utilsr   rS   rC    rZ   rR   <module>r      s   ( (                      . - - - - - 7 7 7 7 7 7L L L L L L L L L L L L* * * * * * * * * * * * * * * * * *, , , , , , , , , , , , % % % % % %C C C C C C C C C C = < < < < < &*d)4{*4(07G2D'E-A.5{-C-E.B/6.D.F5I?JDE6G 6G5H 594: ,."38%*C C C CN 6:P P P P P PrZ   