o
    :Î®c~  ã                   @   s$   d dl Z							ddd„ZdS )	é    Nç        çH¯¼šò×z>é'  Fc	                    s¸  ˆ du r	dd„ }	nt ˆ ƒrˆ }	n‡ fdd„}	|du rt |¡n| ¡ }
tj |¡}t | ƒr4|| |
ƒ }n||  |
¡ }tj |¡}||k sK||| k rM|
S |	|ƒ}| ¡ }t ||¡}t|ƒD ]v}| ¡ }t | ƒrn| |ƒ}n|  |¡}|t ||¡ }|
|| 7 }
||| 8 }tj |¡}|durš|| |
||||ƒ ||k s¤||| k r¨|
  S |	|ƒ}|r¿t || |¡| }t ||¡}nd| }t ||¡}||9 }||9 }||7 }q_t	d| ƒ‚)a£  Solves a system of linear equations :math:`Ax=b` using conjugate gradient descent :cite:`hestenes1952methods`

    Parameters
    ----------
    A: scipy.sparse.csr_matrix
       Square matrix
    b: numpy.ndarray
       Vector describing the right-hand side of the system
    x0: numpy.ndarray
       Initialization, if `None` then :code:`x=np.zeros_like(b)`
    atol: float
       Absolute tolerance. The loop terminates if the :math:`||r||` is smaller than `atol`, where :math:`r` denotes the residual of the current iterate.
    rtol: float
       Relative tolerance. The loop terminates if :math:`{||r||}/{||b||}` is smaller than `rtol`, where :math:`r` denotes the residual of the current iterate.
    callback: function
       Function :code:`callback(A, x, b, norm_b, r, norm_r)` called after each iteration, defaults to `None`
    M: function or scipy.sparse.csr_matrix
       Function that applies the preconditioner to a vector. Alternatively, `M` can be a matrix describing the precondioner.
    reorthogonalize: boolean
        Wether to apply reorthogonalization of the residuals after each update, defaults to `False`


    Returns
    -------
    x: numpy.ndarray
        Solution of the system

    Example
    -------
    >>> from pymatting import *
    >>> import numpy as np
    >>> A = np.array([[3.0, 1.0], [1.0, 2.0]])
    >>> M = jacobi(A)
    >>> b = np.array([4.0, 3.0])
    >>> cg(A, b, M=M)
    array([1., 1.])
    Nc                 S   s   | S ©N© ©Úxr   r   ú:/tmp/pip-target-vg8gfxp4/lib/python/pymatting/solver/cg.pyÚprecondition6   s   zcg.<locals>.preconditionc                    s
   ˆ   | ¡S r   )Údotr   ©ÚMr   r	   r
   =   s   
g      ð?z@Conjugate gradient descent did not converge within %d iterations)
ÚcallableÚnpÚ
zeros_likeÚcopyÚlinalgÚnormr   ÚinnerÚrangeÚ
ValueError)ÚAÚbÚx0ÚatolÚrtolÚmaxiterÚcallbackr   Úreorthogonalizer
   r   Únorm_bÚrÚnorm_rÚzÚpÚrzÚ	iterationÚr_oldÚApÚalphaÚbetar   r   r	   Úcg   sR   0



ÿr*   )Nr   r   r   NNF)Únumpyr   r*   r   r   r   r	   Ú<module>   s    ÷