o
    :Î®c  ã                   @   sH   d dl Zd dlZd dlZdd„ Zdd„ Zdd„ Z					
	ddd„ZdS )é    Nc                 C   s  | \}}|| }|d }|d }|| }t  g d¢¡d }t  t  t  |¡|¡d¡}t  t  t  |¡|¡d¡}	|d t  g d¢|¡ }
|	d t  g d¢|¡ }d|
k|
|k @ d|k@ ||k@ }||	|  | }|
||  | }t  ||¡| }tj |||ff||f¡}|j}||fS )Né   )	é   r   r   r   é   r   r   r   r   é   é	   )	éÿÿÿÿr   r   r   r   r   r   r   r   )	r   r   r   r   r   r   r   r   r   r   )	ÚnpÚfloat64ÚrepeatÚtileÚarangeÚscipyÚsparseÚ
csr_matrixÚT)ÚshapeÚhÚwÚnÚh2Úw2Ún2ÚweightsÚx2Úy2ÚxÚyÚmaskÚi_indsÚj_indsÚvaluesÚ
downsampleÚupsample© r#   úF/tmp/pip-target-vg8gfxp4/lib/python/pymatting/preconditioner/vcycle.pyÚmake_P   s"    r%   c                 C   s\   |d u r|dkr|| | }|d8 }nt  |¡}t|ƒD ]}||||  |¡  |  }q|S )Nr   r   )r   Ú
zeros_likeÚrangeÚdot)ÚAÚA_diagÚbr   Únum_iterÚomegaÚ_r#   r#   r$   Újacobi_step    s   

r/   c              	   C   sæ   |\}}	||	 }
|
|krt jj | |¡S ||vr3t|ƒ\}}| | ¡ |¡}|  ¡ }||||f||< n|| \}}}}t| ||d ||ƒ}||  |¡ }| |¡}t|||d |	d f|||||ƒ}|| |¡7 }t| |||||ƒ}|S )Nr   )	r   r   ÚlinalgÚspsolver%   r(   Údiagonalr/   Ú_vcycle_step)r)   r+   r   ÚcacheÚnum_pre_iterÚnum_post_iterr-   Údirect_solve_sizer   r   r   r"   r!   Úcoarse_Ar*   r   ÚresidualÚcoarse_residualÚcoarse_xr#   r#   r$   r3   .   s4   

ør3   r   çš™™™™™é?é@   c                    s(   ˆdu ri ‰‡ ‡‡‡‡‡‡fdd„}|S )aæ  
    Implements the V-Cycle preconditioner.
    The V-Cycle solver was recommended by :cite:`lee2014scalable` to solve the alpha matting problem.

    Parameters
    ----------
    A: numpy.ndarray
        Input matrix
    shape: tuple of ints
        Describing the height and width of the image
    num_pre_iter: int
        Number of Jacobi iterations before each V-Cycle, defaults to 1
    num_post_iter: int
        Number of Jacobi iterations after each V-Cycle, defaults to 1
    omega: float
        Weight parameter for the Jacobi method. If method fails to converge, try different values.

    Returns
    -------
    precondition: function
        Function which applies the V-Cycle preconditioner to a vector

    Example
    -------
    >>> from pymatting import *
    >>> import numpy as np
    >>> from scipy.sparse import csc_matrix
    >>> A = np.array([[2, 3], [3, 5]])
    >>> preconditioner = vcycle(A, (2, 2))
    >>> preconditioner(np.array([1, 2]))
    array([-1.,  1.])
    Nc              	      s   t ˆ | ˆˆˆˆˆˆƒS )N)r3   )Úr©r)   r4   r7   r6   r5   r-   r   r#   r$   Úprecondition”   s   ÿzvcycle.<locals>.preconditionr#   )r)   r   r5   r6   r-   r7   r4   r@   r#   r?   r$   Úvcycleg   s   *rA   )r   r   r<   r=   N)	Únumpyr   Úscipy.sparser   Úscipy.sparse.linalgr%   r/   r3   rA   r#   r#   r#   r$   Ú<module>   s    <ù