
    _-Ph                     "   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mZmZ ddlm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Zd&dZd!dZd#dZ	 	 d'dZ	 	 d'dZ	 	 d(dZ d#dZ!	 	 d)dZ"	 	 d)dZ#	 	 d*dZ$	 	 d*dZ%dS )+z&Relaxation methods for linear systems.    )warnN)sparse)lapack   )	type_prepget_diagonalget_block_diag)set_tol)norm)amg_corec                    |n|dgk    rmt          j        |           rnt          j        |           r|                                 } nzt	          dt           j                   t          j        |           } nKt          j        |           r
| j        |v rn-t          j        |           	                    |d                   } t          |t          j                  st          d          t          |t          j                  st          d          | j        \  }}||k    rt          d          |j        |f|dffvrt          d	          |j        |f|dffvrt          d
          | j        |j        k    s| j        |j        k    rt!          d          |j        j        st          d          t          j        |          }t          j        |          }| ||fS )aW  Return A,x,b suitable for relaxation or raise an exception.

    Parameters
    ----------
    A : sparse-matrix
        n x n system
    x : array
        n-vector, initial guess
    b : array
        n-vector, right-hand side
    formats: {'csr', 'csc', 'bsr', 'lil', 'dok',...}
        desired sparse matrix format
        default is no change to A's format

    Returns
    -------
    (A,x,b), where A is in the desired sparse-matrix format
    and x and b are "raveled", i.e. (n,) vectors.

    Notes
    -----
    Does some rudimentary error checking on the system,
    such as checking for compatible dimensions and checking
    for compatible type, i.e. float or complex.

    Examples
    --------
    >>> from pyamg.relaxation.relaxation import make_system
    >>> from pyamg.gallery import poisson
    >>> import numpy as np
    >>> A = poisson((10,10), format='csr')
    >>> x = np.zeros((A.shape[0],1))
    >>> b = np.ones((A.shape[0],1))
    >>> (A,x,b) = make_system(A,x,b,formats=['csc'])
    >>> print(x.shape)
    (100,)
    >>> print(b.shape)
    (100,)
    >>> print(A.format)
    csc

    Ncsrzimplicit conversion to CSRr   z#expected numpy array for argument xz#expected numpy array for argument bzexpected square matrix   zx has invalid dimensionszb has invalid dimensionsz.arguments A, x, and b must have the same dtypezx must be contiguous in memory)r   isspmatrix_csrisspmatrix_bsrtocsrr   SparseEfficiencyWarning
csr_matrix
isspmatrixformatasformat
isinstancenpndarray
ValueErrorshapedtype	TypeErrorflagscarrayravel)AxbformatsMNs         [/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/pyamg/relaxation/relaxation.pymake_systemr)      s   V 	UG		 ## 	%"1%% 	%		AA-v/MNNN!!$$AAQ 	:AH$7$7!!$$--gaj99Aa$$ @>???a$$ @>???7DAqAvv1222wtaVn$$3444wtaVn$$3444w!'QW//HIII7> ;9:::
A
Aa7N    r   forwardc                     t          | ||ddg          \  } }}t          j        |          }t          |          D ]/}||dd<   t	          | ||d|           ||z  }|d|z
  z  }||z  }0dS )a  Perform SOR iteration on the linear system Ax=b.

    Parameters
    ----------
    A : csr_matrix, bsr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    omega : scalar
        Damping parameter
    iterations : int
        Number of iterations to perform
    sweep : {'forward','backward','symmetric'}
        Direction of sweep

    Returns
    -------
    Nothing, x will be modified in place.

    Notes
    -----
    When omega=1.0, SOR is equivalent to Gauss-Seidel.

    Examples
    --------
    >>> # Use SOR as stand-along solver
    >>> from pyamg.relaxation.relaxation import sor
    >>> from pyamg.gallery import poisson
    >>> from pyamg.util.linalg import norm
    >>> import numpy as np
    >>> A = poisson((10,10), format='csr')
    >>> x0 = np.zeros((A.shape[0],1))
    >>> b = np.ones((A.shape[0],1))
    >>> sor(A, x0, b, 1.33, iterations=10)
    >>> print(f'{norm(b-A*x0):2.4}')
    3.039
    >>> #
    >>> # Use SOR as the multigrid smoother
    >>> from pyamg import smoothed_aggregation_solver
    >>> sa = smoothed_aggregation_solver(A, B=np.ones((A.shape[0],1)),
    ...         coarse_solver='pinv', max_coarse=50,
    ...         presmoother=('sor', {'sweep':'symmetric', 'omega' : 1.33}),
    ...         postsmoother=('sor', {'sweep':'symmetric', 'omega' : 1.33}))
    >>> x0 = np.zeros((A.shape[0],1))
    >>> residuals=[]
    >>> x = sa.solve(b, x0=x0, tol=1e-8, residuals=residuals)

    r   bsrr%   Nr   
iterationssweep)r)   r   
empty_likerangegauss_seidel)r"   r#   r$   omegar0   r1   x_old_is           r(   sorr8   e   s    f !QE5>:::GAq!M!EJ  aaaQ1%8888	U
!E'	U
 r*   c	                    t          | ||dg          \  } }}|                                  ||t          d          t          | ||||          \  }}}}|dk    rd|j        d         dz
  d}}
}	nt|dk    r|j        d         d	z
  d
d
}}
}	nY|dk    rDt          |          D ]2}t          | ||d||||d	  	         t          | ||d||||d	  	         3dS t          d          t          |          D ]K}t          j        | j	        | j
        | j        |||||||j        d         dz
  | j        d         |	|
|           LdS )a	  Perform Overlapping multiplicative Schwarz on the linear system Ax=b.

    Parameters
    ----------
    A : csr_matrix, bsr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    iterations : int
        Number of iterations to perform
    subdomain : int array
        Linear array containing each subdomain's elements
    subdomain_ptr : int array
        Pointer in subdomain, such that
        subdomain[subdomain_ptr[i]:subdomain_ptr[i+1]]]
        contains the _sorted_ indices in subdomain i
    inv_subblock : int_array
        Linear array containing each subdomain's
        inverted diagonal block of A
    inv_subblock_ptr : int array
        Pointer in inv_subblock, such that
        inv_subblock[inv_subblock_ptr[i]:inv_subblock_ptr[i+1]]]
        contains the inverted diagonal block of A for the
        i-th subdomain in _row_ major order
    sweep : {'forward','backward','symmetric'}
        Direction of sweep

    Returns
    -------
    Nothing, x will be modified in place.

    Notes
    -----
    If subdomains is None, then a point-wise iteration takes place,
    with the overlapping region defined by each degree-of-freedom's
    neighbors in the matrix graph.

    If subdomains is not None, but subblocks is, then the subblocks
    are formed internally.

    Currently only supports CSR matrices

    Examples
    --------
    >>> # Use Overlapping Schwarz as a Stand-Alone Solver
    >>> from pyamg.relaxation.relaxation import schwarz
    >>> from pyamg.gallery import poisson
    >>> from pyamg.util.linalg import norm
    >>> import numpy as np
    >>> A = poisson((10,10), format='csr')
    >>> x0 = np.zeros((A.shape[0],1))
    >>> b = np.ones((A.shape[0],1))
    >>> schwarz(A, x0, b, iterations=10)
    >>> print(f'{norm(b-A*x0):2.4}')
    0.1263
    >>> #
    >>> # Schwarz as the Multigrid Smoother
    >>> from pyamg import smoothed_aggregation_solver
    >>> sa = smoothed_aggregation_solver(A, B=np.ones((A.shape[0],1)),
    ...         coarse_solver='pinv', max_coarse=50,
    ...         presmoother='schwarz',
    ...         postsmoother='schwarz')
    >>> x0=np.zeros((A.shape[0],1))
    >>> residuals=[]
    >>> x = sa.solve(b, x0=x0, tol=1e-8, residuals=residuals)

    r   r.   Nz.inv_subblock must be None if subdomain is Noner+   r   r   backwardr   	symmetric)r0   	subdomainsubdomain_ptrinv_subblockinv_subblock_ptrr1   z>valid sweep directions: 'forward', 'backward', and 'symmetric')r)   sort_indicesr   schwarz_parametersr   r3   schwarzr   overlapping_schwarz_csrindptrindicesdata)r"   r#   r$   r0   r=   r>   r?   r@   r1   	row_startrow_stoprow_step_iters                r(   rC   rC      s   N !QE7333GAq!NN\5IJJJ
 	1i')9	; 	; ?Y|-= 	()=+>q+A!+CQX8			*		(5(;A(>q(@"bX8			+		:&& 	I 	IEAq!Y"/l%5YH H H H Aq!Y"/l%5ZI I I I I 	YZZZ z"" H H(19af)*A|=M)2M)6)<Q)?)A171:)2Hh		H 	H 	H 	HH Hr*   c                 :   t          | ||ddg          \  } }}t          j        |           rd}n!| j        \  }}||k    rt	          d          |}|dk    r$dt          t          |          |z            d}
}	}n~|dk    r't          t          |          |z            dz
  d	d	}
}	}nQ|d
k    r<t          |          D ]*}t          | ||dd           t          | ||dd           +dS t	          d          t          j        |           r>t          |          D ],}t          j        | j
        | j        | j        ||||	|
           -dS t          |          D ]?}t          j        | j
        | j        t          j        | j                  ||||	|
|	  	         @dS )a  Perform Gauss-Seidel iteration on the linear system Ax=b.

    Parameters
    ----------
    A : csr_matrix, bsr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    iterations : int
        Number of iterations to perform
    sweep : {'forward','backward','symmetric'}
        Direction of sweep

    Returns
    -------
    Nothing, x will be modified in place.

    Examples
    --------
    >>> # Use Gauss-Seidel as a Stand-Alone Solver
    >>> from pyamg.relaxation.relaxation import gauss_seidel
    >>> from pyamg.gallery import poisson
    >>> from pyamg.util.linalg import norm
    >>> import numpy as np
    >>> A = poisson((10,10), format='csr')
    >>> x0 = np.zeros((A.shape[0],1))
    >>> b = np.ones((A.shape[0],1))
    >>> gauss_seidel(A, x0, b, iterations=10)
    >>> print(f'{norm(b-A*x0):2.4}')
    4.007
    >>> #
    >>> # Use Gauss-Seidel as the Multigrid Smoother
    >>> from pyamg import smoothed_aggregation_solver
    >>> sa = smoothed_aggregation_solver(A, B=np.ones((A.shape[0],1)),
    ...         coarse_solver='pinv', max_coarse=50,
    ...         presmoother=('gauss_seidel', {'sweep':'symmetric'}),
    ...         postsmoother=('gauss_seidel', {'sweep':'symmetric'}))
    >>> x0=np.zeros((A.shape[0],1))
    >>> residuals=[]
    >>> x = sa.solve(b, x0=x0, tol=1e-8, residuals=residuals)

    r   r-   r.   r   BSR blocks must be squarer+   r   r:   r;   r<   r/   N>valid sweep directions: "forward", "backward", and "symmetric")r)   r   r   	blocksizer   intlenr3   r4   r   rE   rF   rG   bsr_gauss_seidelr   r!   )r"   r#   r$   r0   r1   rO   RCrH   rI   rJ   rK   s               r(   r4   r4     s	   Z !QE5>:::GAq!Q 		{1668999		()3s1vvi/?+@+@!X8			*		(+CFF9,<(=(=a(?RX8			+		:&& 	B 	BEAqQi@@@@AqQjAAAAAYZZZQ N:&& 	A 	AE!!(AIqvq!"+XxA A A A	A 	A :&& 	N 	NE%ah	28AF;K;K&'Ix1N N N N	N 	Nr*         ?c                    t          | ||ddg          \  } }}t          d          }|                    | j        d                   \  }}}||z
  |z  dk    rdS t	          j        |          }	t          | j        |g          \  }t          j	        |           r@t          |          D ].}
t          j        | j        | j        | j        |||	||||
  
         /dS | j        \  }}||k    rt!          d          t#          ||z            }t#          ||z            }t          |          D ]A}
t          j        | j        | j        t	          j        | j                  |||	|||||           BdS )ab  Perform Jacobi iteration on the linear system Ax=b.

    Parameters
    ----------
    A : csr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    iterations : int
        Number of iterations to perform
    omega : scalar
        Damping parameter

    Returns
    -------
    Nothing, x will be modified in place.

    Examples
    --------
    >>> # Use Jacobi as a Stand-Alone Solver
    >>> from pyamg.relaxation.relaxation import jacobi
    >>> from pyamg.gallery import poisson
    >>> from pyamg.util.linalg import norm
    >>> import numpy as np
    >>> A = poisson((10,10), format='csr')
    >>> x0 = np.zeros((A.shape[0],1))
    >>> b = np.ones((A.shape[0],1))
    >>> jacobi(A, x0, b, iterations=10, omega=1.0)
    >>> print(f'{norm(b-A*x0):2.4}')
    5.835
    >>> #
    >>> # Use Jacobi as the Multigrid Smoother
    >>> from pyamg import smoothed_aggregation_solver
    >>> sa = smoothed_aggregation_solver(A, B=np.ones((A.shape[0],1)),
    ...         coarse_solver='pinv', max_coarse=50,
    ...         presmoother=('jacobi', {'omega': 4.0/3.0, 'iterations' : 2}),
    ...         postsmoother=('jacobi', {'omega': 4.0/3.0, 'iterations' : 2}))
    >>> x0=np.zeros((A.shape[0],1))
    >>> residuals=[]
    >>> x = sa.solve(b, x0=x0, tol=1e-8, residuals=residuals)

    r   r-   r.   Nr   rM   )r)   slicerF   r   r   r2   r   r   r   r   r3   r   jacobirE   rG   rO   r   rP   
bsr_jacobir!   )r"   r#   r$   r0   r5   r1   rH   rI   rJ   temprK   rS   rT   s                r(   rX   rX   _  s   Z !QE5>:::GAq!$KKE&+mmAGAJ&?&?#Y(9(A--=D %))GUQ 4:&& 	B 	BEOAHaiAt%x5B B B B	B 	B {1668999	A&&	x!|$$:&& 	4 	4E!)RXaf5E5E !1dIx (!U4 4 4 4	4 	4r*   c                 ,   t          | ||ddg          \  } }}|                     ||f          } |t          | |d          }nl|j        d         t	          | j        d         |z            k    rt          d	          |j        d
         |k    s|j        d         |k    rt          d          t          d          }|                    t	          | j        d         |z                      \  }}	}
|	|z
  |
z  dk    rdS t          j	        |          }t          | j        |g          \  }t          |          D ]T}t          j        | j        | j        t          j        | j                  ||t          j        |          |||	|
||           UdS )aV  Perform block Jacobi iteration on the linear system Ax=b.

    Parameters
    ----------
    A : csr_matrix or bsr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    Dinv : array
        Array holding block diagonal inverses of A
        size (N/blocksize, blocksize, blocksize)
    blocksize : int
        Desired dimension of blocks
    iterations : int
        Number of iterations to perform
    omega : scalar
        Damping parameter

    Returns
    -------
    Nothing, x will be modified in place.

    Examples
    --------
    >>> # Use block Jacobi as a Stand-Alone Solver
    >>> from pyamg.relaxation.relaxation import block_jacobi
    >>> from pyamg.gallery import poisson
    >>> from pyamg.util.linalg import norm
    >>> import numpy as np
    >>> A = poisson((10,10), format='csr')
    >>> x0 = np.zeros((A.shape[0],1))
    >>> b = np.ones((A.shape[0],1))
    >>> block_jacobi(A, x0, b, blocksize=4, iterations=10, omega=1.0)
    >>> print(f'{norm(b-A*x0):2.4}')
    4.665
    >>> #
    >>> # Use block Jacobi as the Multigrid Smoother
    >>> from pyamg import smoothed_aggregation_solver
    >>> opts = {'omega': 4.0/3.0, 'iterations' : 2, 'blocksize' : 4}
    >>> sa = smoothed_aggregation_solver(A, B=np.ones((A.shape[0],1)),
    ...        coarse_solver='pinv', max_coarse=50,
    ...        presmoother=('block_jacobi', opts),
    ...        postsmoother=('block_jacobi', opts))
    >>> x0=np.zeros((A.shape[0],1))
    >>> residuals=[]
    >>> x = sa.solve(b, x0=x0, tol=1e-8, residuals=residuals)

    r   r-   r.   rO   NTrO   inv_flagr   'Dinv and A have incompatible dimensionsr   r   #Dinv and blocksize are incompatible)r)   tobsrr	   r   rP   r   rW   rF   r   r2   r   r   r3   r   block_jacobirE   r!   rG   )r"   r#   r$   DinvrO   r0   r5   r1   rH   rI   rJ   rZ   rK   s                r(   rb   rb     s   f !QE5>:::GAq!	9i011A|a9tDDD	A#agaj233	3	3BCCC
*Q-9
$
$$*Q-9*D*D>???$KKE&+mmC
98L4M4M&N&N#Y(9(A--=D %))GUz"" 0 0ah	28AF3C3CBHTNND'8#Y	0 	0 	0 	00 0r*   c                    t          | ||ddg          \  } }}|                     ||f          } |t          | |d          }nl|j        d         t	          | j        d         |z            k    rt          d	          |j        d
         |k    s|j        d         |k    rt          d          |dk    r$dt	          t          |          |z            d
}	}}n|dk    r't	          t          |          |z            d
z
  dd}	}}nU|dk    r@t          |          D ].}
t          | ||d
d||           t          | ||d
d||           /dS t          d          t          |          D ]R}
t          j        | j
        | j        t          j        | j                  ||t          j        |          |||	|
  
         SdS )a  Perform block Gauss-Seidel iteration on the linear system Ax=b.

    Parameters
    ----------
    A : csr_matrix, bsr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    iterations : int
        Number of iterations to perform
    sweep : {'forward','backward','symmetric'}
        Direction of sweep
    Dinv : array
        Array holding block diagonal inverses of A
        size (N/blocksize, blocksize, blocksize)
    blocksize : int
        Desired dimension of blocks


    Returns
    -------
    Nothing, x will be modified in place.

    Examples
    --------
    >>> # Use Gauss-Seidel as a Stand-Alone Solver
    >>> from pyamg.relaxation.relaxation import block_gauss_seidel
    >>> from pyamg.gallery import poisson
    >>> from pyamg.util.linalg import norm
    >>> import numpy as np
    >>> A = poisson((10,10), format='csr')
    >>> x0 = np.zeros((A.shape[0],1))
    >>> b = np.ones((A.shape[0],1))
    >>> block_gauss_seidel(A, x0, b, iterations=10, blocksize=4, sweep='symmetric')
    >>> print(f'{norm(b-A*x0):2.4}')
    0.9583
    >>> #
    >>> # Use Gauss-Seidel as the Multigrid Smoother
    >>> from pyamg import smoothed_aggregation_solver
    >>> opts = {'sweep':'symmetric', 'blocksize' : 4}
    >>> sa = smoothed_aggregation_solver(A, B=np.ones((A.shape[0],1)),
    ...        coarse_solver='pinv', max_coarse=50,
    ...        presmoother=('block_gauss_seidel', opts),
    ...        postsmoother=('block_gauss_seidel', opts))
    >>> x0=np.zeros((A.shape[0],1))
    >>> residuals=[]
    >>> x = sa.solve(b, x0=x0, tol=1e-8, residuals=residuals)

    r   r-   r.   r\   NTr]   r   r_   r   r   r`   r+   r:   r;   r<   )r0   r1   rO   rc   rN   )r)   ra   r	   r   rP   r   rQ   r3   block_gauss_seidelr   rE   rF   r   r!   rG   )r"   r#   r$   r0   r1   rO   rc   rH   rI   rJ   rK   s              r(   re   re     s   j !QE5>:::GAq!	9i011A|a9tDDD	A#agaj233	3	3BCCC
*Q-9
$
$$*Q-9*D*D>???	()3s1vvi/?+@+@!X8			*		(+CFF9,<(=(=a(?RX8			+		:&& 	? 	?Eq!Q1I)2? ? ? ?q!Q1J)2? ? ? ? ?YZZZz"" N N#AHai!&9I9I$%q"(4..$-x9	N 	N 	N 	NN Nr*   c                     t          | ||d          \  } }}t          |          D ]H}t          |          dk    r|}n|| |z  z
  }|d         |z  }|dd         D ]}||z  | |z  z   }||z  }IdS )a  Apply a polynomial smoother to the system Ax=b.

    Parameters
    ----------
    A : sparse matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    coefficients : array_like
        Coefficients of the polynomial.  See Notes section for details.
    iterations : int
        Number of iterations to perform

    Returns
    -------
    Nothing, x will be modified in place.

    Notes
    -----
    The smoother has the form  x[:] = x + p(A) (b - A*x) where p(A) is a
    polynomial in A whose scalar coefficients are specified (in descending
    order) by argument 'coefficients'.

    - Richardson iteration p(A) = c_0:
        polynomial_smoother(A, x, b, [c_0])

    - Linear smoother p(A) = c_1*A + c_0:
        polynomial_smoother(A, x, b, [c_1, c_0])

    - Quadratic smoother p(A) = c_2*A^2 + c_1*A + c_0:
        polynomial_smoother(A, x, b, [c_2, c_1, c_0])

    Here, Horner's Rule is applied to avoid computing A^k directly.

    For efficience, the method detects the case x = 0 one matrix-vector
    product is avoided (since (b - A*x) is b).

    Examples
    --------
    >>> # The polynomial smoother is not currently used directly
    >>> # in PyAMG.  It is only used by the chebyshev smoothing option,
    >>> # which automatically calculates the correct coefficients.
    >>> from pyamg.gallery import poisson
    >>> from pyamg.util.linalg import norm
    >>> import numpy as np
    >>> from pyamg.aggregation import smoothed_aggregation_solver
    >>> A = poisson((10,10), format='csr')
    >>> b = np.ones((A.shape[0],1))
    >>> sa = smoothed_aggregation_solver(A, B=np.ones((A.shape[0],1)),
    ...         coarse_solver='pinv', max_coarse=50,
    ...         presmoother=('chebyshev', {'degree':3, 'iterations':1}),
    ...         postsmoother=('chebyshev', {'degree':3, 'iterations':1}))
    >>> x0=np.zeros((A.shape[0],1))
    >>> residuals=[]
    >>> x = sa.solve(b, x0=x0, tol=1e-8, residuals=residuals)

    Nr.   r   r   )r)   r3   r   )	r"   r#   r$   coefficientsr0   r7   residualhcs	            r(   
polynomialrk   K  s    x !Q4000GAq!J  77a<<HH1Q3wHOH$abb! 	! 	!A(
QqS AA	Q r*   c                    t          | ||dg          \  } }}t          j        |d          }|dk    rdt          |          d}}}np|dk    rt          |          dz
  d	d	}}}nS|d
k    r>t	          |          D ],}	t          | |||dd           t          | |||dd           -dS t          d          t	          |          D ]-}	t          j        | j        | j	        | j
        ||||||	  	         .dS )a  Perform indexed Gauss-Seidel iteration on the linear system Ax=b.

    In indexed Gauss-Seidel, the sequence in which unknowns are relaxed is
    specified explicitly.  In contrast, the standard Gauss-Seidel method
    always performs complete sweeps of all variables in increasing or
    decreasing order.  The indexed method may be used to implement
    specialized smoothers, like F-smoothing in Classical AMG.

    Parameters
    ----------
    A : csr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    indices : ndarray
        Row indices to relax.
    iterations : int
        Number of iterations to perform
    sweep : {'forward','backward','symmetric'}
        Direction of sweep

    Returns
    -------
    Nothing, x will be modified in place.

    Examples
    --------
    >>> from pyamg.gallery import poisson
    >>> from pyamg.relaxation.relaxation import gauss_seidel_indexed
    >>> import numpy as np
    >>> A = poisson((4,), format='csr')
    >>> x = np.array([0.0, 0.0, 0.0, 0.0])
    >>> b = np.array([0.0, 1.0, 2.0, 3.0])
    >>> gauss_seidel_indexed(A, x, b, [0,1,2,3])  # relax all rows in order
    >>> gauss_seidel_indexed(A, x, b, [0,1])      # relax first two rows
    >>> gauss_seidel_indexed(A, x, b, [2,0])      # relax row 2, then row 0
    >>> gauss_seidel_indexed(A, x, b, [2,3], sweep='backward')  # 3, then 2
    >>> gauss_seidel_indexed(A, x, b, [2,0,2])    # relax row 2, 0, 2

    r   r.   intcr   r+   r   r   r:   r;   r<   r/   NrN   )r)   r   asarrayrQ   r3   gauss_seidel_indexedr   r   rE   rF   rG   )
r"   r#   r$   rF   r0   r1   rH   rI   rJ   rK   s
             r(   rp   rp     s]   V !QE7333GAq!j///G 	()3w<<X8			*		(+GQBX8			+		:&& 	3 	3E Aq'a'02 2 2 2 Aq'a'13 3 3 3 3YZZZz"" E E%ah	16&'G&/8	E 	E 	E 	EE Er*   c                 $   t          | ||dg          \  } }}t          d          }|                    | j        d                   \  }}}t	          j        |          }	t          | dd          }
t          | j        |g          \  }t          |          D ]v}t	          j
        || |z  z
            t	          j
        |
          z                      | j                  }t          j        | j        | j        | j        ||||	||||           wdS )a  Perform Jacobi iterations on the linear system A A.H x = A.H b.

    Also known as Cimmino relaxation

    Parameters
    ----------
    A : csr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    iterations : int
        Number of iterations to perform
    omega : scalar
        Damping parameter

    Returns
    -------
    Nothing, x will be modified in place.

    References
    ----------
    .. [1] Brandt, Ta'asan.
       "Multigrid Method For Nearly Singular And Slightly Indefinite Problems."
       1985.  NASA Technical Report Numbers: ICASE-85-57; NAS 1.26:178026;
       NASA-CR-178026;

    .. [2] Kaczmarz.  Angenaeherte Aufloesung von Systemen Linearer
       Gleichungen.  Bull. Acad.  Polon. Sci. Lett. A 35, 355-57.  1937

    .. [3] Cimmino. La ricerca scientifica ser. II 1.
       Pubbliz. dell'Inst. pre le Appl. del Calculo 34, 326-333, 1938.

    Examples
    --------
    >>> # Use NE Jacobi as a Stand-Alone Solver
    >>> from pyamg.relaxation.relaxation import jacobi_ne
    >>> from pyamg.gallery import poisson
    >>> from pyamg.util.linalg import norm
    >>> import numpy as np
    >>> A = poisson((50,50), format='csr')
    >>> x0 = np.zeros((A.shape[0],1))
    >>> b = np.ones((A.shape[0],1))
    >>> jacobi_ne(A, x0, b, iterations=10, omega=2.0/3.0)
    >>> print(f'{norm(b-A*x0):2.4}')
    49.39
    >>> #
    >>> # Use NE Jacobi as the Multigrid Smoother
    >>> from pyamg import smoothed_aggregation_solver
    >>> opts = {'iterations' : 2, 'omega' : 4.0/3.0}
    >>> sa = smoothed_aggregation_solver(A, B=np.ones((A.shape[0],1)),
    ...         coarse_solver='pinv', max_coarse=50,
    ...         presmoother=('jacobi_ne', opts),
    ...         postsmoother=('jacobi_ne', opts))
    >>> x0=np.zeros((A.shape[0],1))
    >>> residuals=[]
    >>> x = sa.solve(b, x0=x0, tol=1e-8, residuals=residuals)

    r   r.   Nr   r   Tnorm_eqinv)r)   rW   rF   r   r   
zeros_liker   r   r   r3   r!   astyper   	jacobi_nerE   rG   )r"   r#   r$   r0   r5   r1   rH   rI   rJ   rZ   rc   r7   deltas                r(   rw   rw     s   z !QE7333GAq!$KKE&+mmAGAJ&?&?#Y(=D 1$///D %))GUJ 6 6!ac'""28D>>199!'BB18QYai#Xu	6 	6 	6 	66 6r*   c                    t          | ||dg          \  } }}|$t          j        t          | dd                    }|dk    rdt	          |          d	}	}}nr|d
k    rt	          |          d	z
  dd}	}}nU|dk    r@t          |          D ].}
t          | ||d	d||           t          | ||d	d
||           /dS t          d          t          |          D ].}t          j        | j	        | j
        | j        |||||	||
  
         /dS )a!  Perform Gauss-Seidel iterations on the linear system A A.H y = b, where x = A.H y.

    Also known as Kaczmarz relaxation

    Parameters
    ----------
    A : csr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    iterations : int
        Number of iterations to perform
    sweep : {'forward','backward','symmetric'}
        Direction of sweep
    omega : float
        Relaxation parameter typically in (0, 2)
        if omega != 1.0, then algorithm becomes SOR on A A.H
    Dinv : ndarray
        Inverse of diag(A A.H),  (length N)

    Returns
    -------
    Nothing, x will be modified in place.

    References
    ----------
    .. [1] Brandt, Ta'asan.
       "Multigrid Method For Nearly Singular And Slightly Indefinite Problems."
       1985.  NASA Technical Report Numbers: ICASE-85-57; NAS 1.26:178026;
       NASA-CR-178026;

    .. [2] Kaczmarz.  Angenaeherte Aufloesung von Systemen Linearer
       Gleichungen. Bull. Acad.  Polon. Sci. Lett. A 35, 355-57.  1937

    Examples
    --------
    >>> # Use NE Gauss-Seidel as a Stand-Alone Solver
    >>> from pyamg.relaxation.relaxation import gauss_seidel_ne
    >>> from pyamg.gallery import poisson
    >>> from pyamg.util.linalg import norm
    >>> import numpy as np
    >>> A = poisson((10,10), format='csr')
    >>> x0 = np.zeros((A.shape[0],1))
    >>> b = np.ones((A.shape[0],1))
    >>> gauss_seidel_ne(A, x0, b, iterations=10, sweep='symmetric')
    >>> print(f'{norm(b-A*x0):2.4}')
    8.476
    >>> #
    >>> # Use NE Gauss-Seidel as the Multigrid Smoother
    >>> from pyamg import smoothed_aggregation_solver
    >>> sa = smoothed_aggregation_solver(A, B=np.ones((A.shape[0],1)),
    ...         coarse_solver='pinv', max_coarse=50,
    ...         presmoother=('gauss_seidel_ne', {'sweep' : 'symmetric'}),
    ...         postsmoother=('gauss_seidel_ne', {'sweep' : 'symmetric'}))
    >>> x0=np.zeros((A.shape[0],1))
    >>> residuals=[]
    >>> x = sa.solve(b, x0=x0, tol=1e-8, residuals=residuals)

    r   r.   Nr   Trr   r+   r   r   r:   r;   r<   r0   r1   r5   rc   rN   )r)   r   r!   r   rQ   r3   gauss_seidel_ner   r   rE   rF   rG   )r"   r#   r$   r0   r1   r5   rc   rH   rI   rJ   rK   r7   s               r(   r{   r{   1  sr   ~ !QE7333GAq! |xQt<<<==	()3q661X8			*		(+Aq"bX8			+		:&& 	4 	4EAq!"'d4 4 4 4Aq!"'d4 4 4 4 4YZZZJ B B 19af!"Ay!)8T5	B 	B 	B 	BB Br*   c                 &   t          | ||dg          \  } }}|$t          j        t          | dd                    }|dk    rdt	          |          d}	}}nr|d	k    rt	          |          dz
  d
d
}	}}nU|dk    r@t          |          D ].}
t          | ||dd||           t          | ||dd	||           /dS t          d          || |z  z
  }t          |          D ].}t          j        | j	        | j
        | j        |||||	||
  
         /dS )a2  Perform Gauss-Seidel iterations on the linear system A.H A x = A.H b.

    Parameters
    ----------
    A : csr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    iterations : int
        Number of iterations to perform
    sweep : {'forward','backward','symmetric'}
        Direction of sweep
    omega : float
        Relaxation parameter typically in (0, 2)
        if omega != 1.0, then algorithm becomes SOR on A.H A
    Dinv : ndarray
        Inverse of diag(A.H A),  (length N)

    Returns
    -------
    Nothing, x will be modified in place.

    References
    ----------
    .. [1] Yousef Saad, "Iterative Methods for Sparse Linear Systems,
       Second Edition", SIAM, pp. 247-9, 2003
       http://www-users.cs.umn.edu/~saad/books.html


    Examples
    --------
    >>> # Use NR Gauss-Seidel as a Stand-Alone Solver
    >>> from pyamg.relaxation.relaxation import gauss_seidel_nr
    >>> from pyamg.gallery import poisson
    >>> from pyamg.util.linalg import norm
    >>> import numpy as np
    >>> A = poisson((10,10), format='csr')
    >>> x0 = np.zeros((A.shape[0],1))
    >>> b = np.ones((A.shape[0],1))
    >>> gauss_seidel_nr(A, x0, b, iterations=10, sweep='symmetric')
    >>> print(f'{norm(b-A*x0):2.4}')
    8.45
    >>> #
    >>> # Use NR Gauss-Seidel as the Multigrid Smoother
    >>> from pyamg import smoothed_aggregation_solver
    >>> sa = smoothed_aggregation_solver(A, B=np.ones((A.shape[0],1)),
    ...      coarse_solver='pinv', max_coarse=50,
    ...      presmoother=('gauss_seidel_nr', {'sweep' : 'symmetric'}),
    ...      postsmoother=('gauss_seidel_nr', {'sweep' : 'symmetric'}))
    >>> x0=np.zeros((A.shape[0],1))
    >>> residuals=[]
    >>> x = sa.solve(b, x0=x0, tol=1e-8, residuals=residuals)

    cscr.   Nr   Trr   r+   r   r:   r;   r<   rz   rN   )r)   r   r!   r   rQ   r3   gauss_seidel_nrr   r   rE   rF   rG   )r"   r#   r$   r0   r1   r5   rc   	col_startcol_stopcol_steprK   rr7   s                r(   r~   r~     s   t !QE7333GAq! |xQt<<<==	()3q661X8			*		(+Aq"bX8			+		:&& 	4 	4EAq!"'d4 4 4 4Aq!"'d4 4 4 4 4YZZZ 	
AaCAJ B B 19af!"Ay!)8T5	B 	B 	B 	BB Br*   c                    t          | d          r}|t|rt          j        | j        d         |k                                              r<t          j        | j        d         |k                                              r| j        S n| j        S ||2| j                                        }| j                                        }||t          j        |j	        | j        j
                  }|dd         |dd         z
  }t          j        ||z            |dd<   t          j        |d         f| j
                  }t          j        | j        | j        | j        ||||t          |j	        d         dz
            | j	        d         	  	         t!          | j
                  }t#          j        dgt          j        d| j
                            \  }t)          |j	        d         dz
            D ]}||         }	t          j        |	|	| j
                  }
||         }||dz            } ||||                             |	|	          |
|d	d	
          }t          j        |d                   |||<   ||||f| _        | j        S )a  Set Schwarz parameters.

    Helper function for setting up Schwarz relaxation.  This function avoids
    recomputing the subdomains and block inverses manytimes, e.g., it avoids a
    costly double computation when setting up pre and post smoothing with
    Schwarz.

    Parameters
    ----------
    A {csr_matrix}

    Returns
    -------
    A.schwarz_parameters[0] is subdomain
    A.schwarz_parameters[1] is subdomain_ptr
    A.schwarz_parameters[2] is inv_subblock
    A.schwarz_parameters[3] is inv_subblock_ptr

    rB   Nr   r   rn   r;   gelssr   T)condoverwrite_aoverwrite_b)hasattrr   arrayrB   allrE   copyrF   zerosr   r   cumsumr   extract_subblocksrG   rP   r
   laget_lapack_funcsonesr3   eyereshaper!   )r"   r=   r>   r?   r@   rO   r   my_pinvimrhsj0j1gelssoutputs                 r(   rB   rB     s   , q&'' ( ]%> x,Q/9<==AACC ,x,Q/=@AAEEGG,++'' M1INN$$	 /78M$7*+)/; ; ;!!""%crc(::	!y9)<== x!1"!5 7qwGGG"18QY#3Y#&}':1'=a'?#@#@!'!*	N 	N 	N qw &y(*AG(D(D(DG G}*1-a/00 	; 	;A!A&AQW---C!!$B!!A#&B!',r"u"5"="=a"C"C"%Dd.24 4 4K #%(;q>":":LB%}l,.Ar*   c                    t          | ||ddg          \  } }}t          j        |d          }t          | j        |g          \  }t          j        |           r=t          |          D ]+}t          j	        | j
        | j        | j        ||||           ,d
S | j        \  }}||k    rt          d          |                                | j        d         |z  dz
  k    rt          d	          t          |          D ]>}t          j        | j
        | j        | j                                        |||||           ?d
S )ap  Perform indexed Jacobi iteration on the linear system Ax=b.

    The indexed method may be used to implement
    specialized smoothers, like F-smoothing in classical AMG.

    Parameters
    ----------
    A : csr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    indices : ndarray
        Row indices to relax.
    iterations : int
        Number of iterations to perform
    omega : scalar
        Damping parameter

    Returns
    -------
    Nothing, x will be modified in place.

    Examples
    --------
    >>> from pyamg.gallery import poisson
    >>> from pyamg.relaxation.relaxation import jacobi_indexed
    >>> import numpy as np
    >>> A = poisson((4,), format='csr')
    >>> x = np.array([0.0, 0.0, 0.0, 0.0])
    >>> b = np.array([0.0, 1.0, 2.0, 3.0])
    >>> jacobi_indexed(A, x, b, [0,1,2,3])  # relax all rows in order
    >>> jacobi_indexed(A, x, b, [0,1])      # relax first two rows
    >>> jacobi_indexed(A, x, b, [2,0])      # relax row 2, then row 0
    >>> jacobi_indexed(A, x, b, [2,3])      # relax 2 and 3

    r   r-   r.   rm   rn   rM   r   r   z6Indices must range from 0, ..., numrows/blocksize - 1)N)r)   r   ro   r   r   r   r   r3   r   jacobi_indexedrE   rF   rG   rO   r   maxr   bsr_jacobi_indexedr!   )	r"   r#   r$   rF   r0   r5   rK   rS   rT   s	            r(   r   r   2  s`   N !QE5>:::GAq!j///G %))GUQ ;:&& 	W 	WE#AHaiAwPUVVVV	W 	W {1668999;;==171:a<!+++UVVV:&& 	; 	;E'!)QV\\^^QPQ(/E; ; ; ;	; 	;r*   c	                    t          | ||ddg          \  } }}|                    | j        j                  }|                    | j        j                  }t	          | j        |g          \  }t          j        |           rt          |          D ]x}	t          |          D ]+}
t          j	        | j        | j
        | j        ||||           ,t          |          D ]+}t          j	        | j        | j
        | j        ||||           ,ydS | j        \  }}||k    rt          d          t          |          D ]}	t          |          D ]>}
t          j        | j        | j
        t          j        | j                  |||||           ?t          |          D ]>}t          j        | j        | j
        t          j        | j                  |||||           ?dS )a  Perform CF Jacobi iteration on the linear system Ax=b.

    CF Jacobi executes

        xc = (1-omega)xc + omega*Dff^{-1}(bc - Acf*xf - Acc*xc)
        xf = (1-omega)xf + omega*Dff^{-1}(bf - Aff*xf - Afc*xc)

    where xf is x restricted to F-points, and likewise for c subscripts.

    Parameters
    ----------
    A : csr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    Cpts : array ints
        List of C-points
    Fpts : array ints
        List of F-points
    iterations : int
        Number of iterations to perform of total CF-cycle
    f_iterations : int
        Number of sweeps of F-relaxation to perform
    c_iterations : int
        Number of sweeps of C-relaxation to perform
    omega : scalar
        Damping parameter

    Returns
    -------
    Nothing, x will be modified in place.
    r   r-   r.   rM   Nr)   rv   rE   r   r   r   r   r3   r   r   rF   rG   rO   r   r   r   r!   )r"   r#   r$   CptsFptsr0   f_iterationsc_iterationsr5   rK   _citer_fiterrS   rT   s                 r(   	cf_jacobir   n  %   H !QE5>:::GAq!;;qx~&&D;;qx~&&D %))GUQ B:&& 	X 	XE-- X X'!)QVQ4QVWWWW-- X X'!)QVQ4QVWWWWX	X 	X {1668999:&& 	B 	BE-- B B+AHai!&AQAQ,-q$5B B B B-- B B+AHai!&AQAQ,-q$5B B B BB		B 	Br*   c	                    t          | ||ddg          \  } }}|                    | j        j                  }|                    | j        j                  }t	          | j        |g          \  }t          j        |           rt          |          D ]x}	t          |          D ]+}
t          j	        | j        | j
        | j        ||||           ,t          |          D ]+}t          j	        | j        | j
        | j        ||||           ,ydS | j        \  }}||k    rt          d          t          |          D ]}	t          |          D ]>}
t          j        | j        | j
        t          j        | j                  |||||           ?t          |          D ]>}t          j        | j        | j
        t          j        | j                  |||||           ?dS )a  Perform FC Jacobi iteration on the linear system Ax=b.

    FC Jacobi executes

        xf = (1-omega)xf + omega*Dff^{-1}(bf - Aff*xf - Afc*xc)
        xc = (1-omega)xc + omega*Dff^{-1}(bc - Acf*xf - Acc*xc)

    where xf is x restricted to F-points, and likewise for c subscripts.

    Parameters
    ----------
    A : csr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    Cpts : array ints
        List of C-points
    Fpts : array ints
        List of F-points
    iterations : int
        Number of iterations to perform of total FC-cycle
    f_iterations : int
        Number of sweeps of F-relaxation to perform
    c_iterations : int
        Number of sweeps of C-relaxation to perform
    omega : scalar
        Damping parameter

    Returns
    -------
    Nothing, x will be modified in place.
    r   r-   r.   rM   Nr   )r"   r#   r$   r   r   r0   r   r   r5   rK   r   r   rS   rT   s                 r(   	fc_jacobir     r   r*   c                    t          | ||ddg          \  } }}|                     ||f          } |                    | j        j                  }|                    | j        j                  }|t          | |d          }nl|j        d         t          | j        d         |z            k    rt          d	          |j        d
         |k    s|j        d         |k    rt          d          t          | j        |
g          \  }
t          |          D ]}t          |	          D ]Q}t          j        | j        | j        t          j        | j                  ||t          j        |          ||
|	  	         Rt          |          D ]Q}t          j        | j        | j        t          j        | j                  ||t          j        |          ||
|	  	         RdS )a  Perform CF block Jacobi iteration on the linear system Ax=b.

    CF block Jacobi executes

        xc = (1-omega)xc + omega*Dff^{-1}(bc - Acf*xf - Acc*xc)
        xf = (1-omega)xf + omega*Dff^{-1}(bf - Aff*xf - Afc*xc)

    where xf is x restricted to F-blocks, and Dff^{-1} the block inverse
    of the block diagonal Dff, and likewise for c subscripts.

    Parameters
    ----------
    A : csr_matrix or bsr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    Cpts : array ints
        List of C-blocks in A
    Fpts : array ints
        List of F-blocks in A
    Dinv : array
        Array holding block diagonal inverses of A
        size (N/blocksize, blocksize, blocksize)
    blocksize : int
        Desired dimension of blocks
    iterations : int
        Number of iterations to perform of total CF-cycle
    f_iterations : int
        Number of sweeps of F-relaxation to perform
    c_iterations : int
        Number of sweeps of C-relaxation to perform
    omega : scalar
        Damping parameter

    Returns
    -------
    Nothing, x will be modified in place.

    r   r-   r.   r\   NTr]   r   r_   r   r   r`   r)   ra   rv   rE   r   r	   r   rP   r   r   r3   r   block_jacobi_indexedrF   r   r!   rG   )r"   r#   r$   r   r   rc   rO   r0   r   r   r5   rK   r   r   s                 r(   cf_block_jacobir        V !QE5>:::GAq!	9i011A;;qx~&&D;;qx~&&D|a9tDDD	A#agaj233	3	3BCCC
*Q-9
$
$$*Q-9*D*D>??? %))GU z"" 5 5L)) 	5 	5F)!(AIrx?O?O*+Qe*35 5 5 5 L)) 	5 	5F)!(AIrx?O?O*+Qe*35 5 5 5	55 5r*   c                    t          | ||ddg          \  } }}|                     ||f          } |                    | j        j                  }|                    | j        j                  }|t          | |d          }nl|j        d         t          | j        d         |z            k    rt          d	          |j        d
         |k    s|j        d         |k    rt          d          t          | j        |
g          \  }
t          |          D ]}t          |          D ]Q}t          j        | j        | j        t          j        | j                  ||t          j        |          ||
|	  	         Rt          |	          D ]Q}t          j        | j        | j        t          j        | j                  ||t          j        |          ||
|	  	         RdS )a  Perform FC block Jacobi iteration on the linear system Ax=b.

    FC block Jacobi executes

        xf = (1-omega)xf + omega*Dff^{-1}(bf - Aff*xf - Afc*xc)
        xc = (1-omega)xc + omega*Dff^{-1}(bc - Acf*xf - Acc*xc)

    where xf is x restricted to F-blocks, and Dff^{-1} the block inverse
    of the block diagonal Dff, and likewise for c subscripts.

    Parameters
    ----------
    A : csr_matrix or bsr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    Cpts : array ints
        List of C-blocks in A
    Fpts : array ints
        List of F-blocks in A
    Dinv : array
        Array holding block diagonal inverses of A
        size (N/blocksize, blocksize, blocksize)
    blocksize : int
        Desired dimension of blocks
    iterations : int
        Number of iterations to perform of total FC-cycle
    f_iterations : int
        Number of sweeps of F-relaxation to perform
    c_iterations : int
        Number of sweeps of C-relaxation to perform
    omega : scalar
        Damping parameter

    Returns
    -------
    Nothing, x will be modified in place.

    r   r-   r.   r\   NTr]   r   r_   r   r   r`   r   )r"   r#   r$   r   r   rc   rO   r0   r   r   r5   rK   r   r   s                 r(   fc_block_jacobir   5  r   r*   )N)r   r+   )r   NNNNr+   )r   rU   )Nr   r   rU   )r   r+   r   Nr   )r   r+   rU   N)NNNN)r   r   r   rU   )Nr   r   r   r   rU   )&__doc__warningsr   numpyr   scipyr   scipy.linalgr   r   
util.utilsr   r   r	   util.paramsr
   util.linalgr    r   r)   r8   rC   r4   rX   rb   re   rk   rp   rw   r{   r~   rB   r   r   r   r   r    r*   r(   <module>r      s   , ,                 % % % % % % @ @ @ @ @ @ @ @ @ @ ! ! ! ! ! !            S S S Sl> > > >B BF<EiH iH iH iHXJN JN JN JNZG4 G4 G4 G4TL0 L0 L0 L0^ JK PN PN PN PNfJ J J JZEE EE EE EEPN6 N6 N6 N6b CFVB VB VB VBr CFTB TB TB TBD 9=;?C  C  C  C L9; 9; 9; 9;x ?@$'=B =B =B =B@ ?@$'=B =B =B =B@ MN:=D5 D5 D5 D5N MN:=D5 D5 D5 D5 D5 D5r*   