B
    |‹dX  ã               @   s2   d dl mZ d dlZddgZdd„ Zd
d	d„ZdS )é    )ÚexpNÚsolve_corrections_sgdÚdetermine_offset_matrixc       	      C   s¨   t | ƒ}t ||f¡tj }x†t| ƒD ]z\}}xpt| ƒD ]d\}}||krJq8| |¡r8|| }t |j¡r8|j|j }t 	|¡|||f< |||f  |||f< q8W q&W |S )ze
    Given a list of ReprojectedArraySubset, determine the offset
    matrix between all arrays.
    )
ÚlenÚnpZonesÚnanÚ	enumerateÚoverlapsÚanyZ	footprintÚarrayZmedian)	ZarraysÚNÚoffset_matrixÚi1Zarray1Úi2Zarray2Ú
differenceÚvalues© r   úl/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/reproject/mosaicking/background.pyr   
   s    
é   éd   ç»½×Ùß|Û=c             C   s&  | j dks| jd | jd kr&tdƒ‚| jd }t |¡}t |¡}d}xØtt|d ƒƒD ]Ä}	tj 	|¡ |t
|	 | ƒ }
xj|D ]b}t || ¡r–q‚t | |dd…f ¡ }|| ||  }||  |
t | ||f | ¡ 7  < q‚W |t |¡8 }|dk	rtj||||drP | ¡ }qZW |S )aî  
    Given a matrix of offsets from each image to each other image, find the
    optimal offsets to use using Stochastic Gradient Descent.

    Given N images, we can construct an NxN matrix Oij giving the typical (e.g.
    mean, median, or other statistic) offset from each image to each other
    image. This can be a reasonably sparse matrix since not all images
    necessarily overlap. From this we then want to find a vector of N
    corrections Ci to apply to each image to minimize the differences.

    We do this by using the Stochastic Gradient Descent algorithm:

    https://en.wikipedia.org/wiki/Stochastic_gradient_descent

    Essentially what we are trying to minimize is the difference between Dij
    and a matrix of the same shape constructed from the Oi values.

    The learning rate is decreased using a decaying exponential:

        $$\eta = \eta_{\rm initial} * \exp{(-i/t_{\eta})}$$

    Parameters
    ----------
    offset_matrix : `~numpy.ndarray`
        The NxN matrix giving the offsets between all images (or NaN if
        an offset could not be determined)
    eta_initial : float
        The initial learning rate to use
    eta_half_life : float
        The number of iterations after which the learning rate should be
        decreased by a factor $e$.
    rtol : float
        The relative tolerance to use to determine if the corrections have
        converged.
    atol : float
        The absolute tolerance to use to determine if the corrections have
        converged.
    é   r   r   z+offset_matrix should be a square NxN matrixNé
   )ÚrtolÚatol)ÚndimÚshapeÚ
ValueErrorr   ZarangeZzerosÚrangeÚintÚrandomÚshuffler   ÚisnanZmeanZnanmeanZallcloseÚcopy)r   Zeta_initialZeta_half_lifer   r   r   ÚindicesZcorrectionsZprevious_correctionsÚ	iterationÚetaÚiZkeepZfitted_offset_matrix_rowr   r   r   r   $   s0    )





)r   r   r   r   )Úmathr   Únumpyr   Ú__all__r   r   r   r   r   r   Ú<module>   s
    