U
    Ö½|e  ã                
   @   sê   d dl Zd dlZd dlmZ d dlmZ d dlm	Z	 e 
¡ dd„ ƒZej
dddejjejjejjdœd	�d
d„ ƒZdd„ Zdd„ Zd%dd„Zdd„ Zdddejddddfdd„Zdd„ Zdddejddddfdd„Zdd„ Zd&d#d$„ZdS )'é    N)Útau_rand_int)Útqdmc                 C   s    | dkrdS | dk rdS | S dS )züStandard clamping of a value into a fixed range (in this case -4.0 to
    4.0)

    Parameters
    ----------
    val: float
        The value to be clamped.

    Returns
    -------
    The clamped value, now fixed to be in the range -4.0 to 4.0.
    ç      @g      ÀN© )Úvalr   r   úI/var/www/website-v5/atlas_env/lib/python3.8/site-packages/umap/layouts.pyÚclip   s
    r   zf4(f4[::1],f4[::1])T)ÚresultÚdiffÚdim)ÚfastmathÚcacheÚlocalsc                 C   s<   d}| j d }t|ƒD ] }| | ||  }||| 7 }q|S )zÙReduced Euclidean distance.

    Parameters
    ----------
    x: array of shape (embedding_dim,)
    y: array of shape (embedding_dim,)

    Returns
    -------
    The squared euclidean distance between x and y
    ç        r   )ÚshapeÚrange)ÚxÚyr	   r   Úir
   r   r   r   Úrdist   s    
r   c           0      C   s(  t  |jd ¡D �]}|| |kr|| }|| }| | }|| }t||ƒ} |�r\dd|t| |ƒ   }!|| t| |d ƒ d|t| |ƒ   }"|!||  }#|!||  }$|#d|d|!   t || ¡ |"  }%|$d|d|!   t || ¡ |"  }&|| }'|| ||| |  |'  }(|| ||| |  |'  })|| |(|% |)|&   || |  | }*| dk�r˜d| | t| |d ƒ }+|+|t| |ƒ d  }+nd}+t|
ƒD ]t},t|+||, ||,   ƒ}-|�ræ|-td|* ||, ||,   ƒ7 }-||,  |-| 7  < |�r¤||,  |- | 7  < �q¤||  || 7  < t	|||  ||  ƒ}.t|.ƒD ]º}/t
|ƒ| }|| }t||ƒ} | dk�r¦d|	 | }+|+d|  |t| |ƒ d   }+n||k�r¶�qNnd}+t|
ƒD ]B},|+dk�rêt|+||, ||,   ƒ}-nd	}-||,  |-| 7  < �qÂ�qN||  |.||  7  < qd S )
Nr   ç      ð?é   r   ç       Àé   ç       @çü©ñÒMbP?r   )ÚnumbaÚpranger   r   ÚpowÚnpÚexpr   r   Úintr   )0Úhead_embeddingÚtail_embeddingÚheadÚtailÚ
n_verticesÚepochs_per_sampleÚaÚbÚ	rng_stateÚgammar   Ú
move_otherÚalphaÚepochs_per_negative_sampleÚepoch_of_next_negative_sampleÚepoch_of_next_sampleÚnÚdensmap_flagÚdens_phi_sumÚdens_re_sumÚdens_re_covÚdens_re_stdÚdens_re_meanÚdens_lambdaÚdens_RÚdens_muÚdens_mu_totr   ÚjÚkÚcurrentÚotherÚdist_squaredÚphiZ	dphi_termZq_jkZq_kjZdrkZdrjZ	re_std_sqÚweight_kZweight_jZgrad_cor_coeffÚ
grad_coeffÚdÚgrad_dÚn_neg_samplesÚpr   r   r   Ú'_optimize_layout_euclidean_single_epoch=   s’    
&ÿ ÿ ÿÿÿÿÿÿþ
ýüÿ
 ÿ

ÿ


ÿrH   c                 C   sä   |  d¡ |  d¡ t |j¡D ]Œ}|| }	|| }
| |	 }||
 }t||ƒ}dd|t||ƒ   }||	  || 7  < ||
  || 7  < ||	  |7  < ||
  |7  < q d}t|jƒD ]"}t ||| ||   ¡||< q¼d S )Nr   r   g:Œ0âŽyE>)	Úfillr   r   Úsizer   r   r   r   Úlog)r"   r#   r$   r%   r(   r)   Zre_sumZphi_sumr   r<   r=   r>   r?   r@   rA   Úepsilonr   r   r   Ú-_optimize_layout_euclidean_densmap_epoch_init»   s     



rM   r   ç      @Fc           &      C   s  | j d }|}|| }| ¡ }| ¡ }tjtd|d�}|dkrBi }|dkrNi }|r¶tjtd|d�}t |d ¡d }|d }|d }|d	 }tj|tj	d
�}tj|tj	d
�}|d } nHd}d}tjdtj	d
�}tjdtj	d
�}tjdtj	d
�}tjdtj	d
�}d|k�r| |d< t
t|ƒf|ŽD ]æ}!|�oT|d dk�oT|!d t|ƒ d|d  k}"|"�r¦|| |||||||ƒ t t |¡|  ¡}#t |¡}$t ||¡|d  }%nd}#d}$d}%|| ||||||||	|
|||||||!|"|||%|#|$||||ƒ |dt|!ƒt|ƒ   }�q"| S )a2  Improve an embedding using stochastic gradient descent to minimize the
    fuzzy set cross entropy between the 1-skeletons of the high dimensional
    and low dimensional fuzzy simplicial sets. In practice this is done by
    sampling edges based on their membership strength (with the (1-p) terms
    coming from negative sampling similar to word2vec).
    Parameters
    ----------
    head_embedding: array of shape (n_samples, n_components)
        The initial embedding to be improved by SGD.
    tail_embedding: array of shape (source_samples, n_components)
        The reference embedding of embedded points. If not embedding new
        previously unseen points with respect to an existing embedding this
        is simply the head_embedding (again); otherwise it provides the
        existing embedding to embed with respect to.
    head: array of shape (n_1_simplices)
        The indices of the heads of 1-simplices with non-zero membership.
    tail: array of shape (n_1_simplices)
        The indices of the tails of 1-simplices with non-zero membership.
    n_epochs: int
        The number of training epochs to use in optimization.
    n_vertices: int
        The number of vertices (0-simplices) in the dataset.
    epochs_per_sample: array of shape (n_1_simplices)
        A float value of the number of epochs per 1-simplex. 1-simplices with
        weaker membership strength will have more epochs between being sampled.
    a: float
        Parameter of differentiable approximation of right adjoint functor
    b: float
        Parameter of differentiable approximation of right adjoint functor
    rng_state: array of int64, shape (3,)
        The internal state of the rng
    gamma: float (optional, default 1.0)
        Weight to apply to negative samples.
    initial_alpha: float (optional, default 1.0)
        Initial learning rate for the SGD.
    negative_sample_rate: int (optional, default 5)
        Number of negative samples to use per positive sample.
    parallel: bool (optional, default False)
        Whether to run the computation using numba parallel.
        Running in parallel is non-deterministic, and is not used
        if a random seed has been set, to ensure reproducibility.
    verbose: bool (optional, default False)
        Whether to report information on the current progress of the algorithm.
    densmap: bool (optional, default False)
        Whether to use the density-augmented densMAP objective
    densmap_kwds: dict (optional, default None)
        Auxiliary data for densMAP
    tqdm_kwds: dict (optional, default None)
        Keyword arguments for tqdm progress bar.
    move_other: bool (optional, default False)
        Whether to adjust tail_embedding alongside head_embedding
    Returns
    -------
    embedding: array of shape (n_samples, n_components)
        The optimized embedding.
    r   T©r   ÚparallelNÚmu_sumr   ÚlambdaÚRÚmu)ÚdtypeÚ	var_shiftr   ÚdisableÚfracr   )r   Úcopyr   ÚnjitrH   rM   r   ÚsumÚzerosÚfloat32r   r   ÚfloatÚsqrtÚvarÚmeanÚdot)&r"   r#   r$   r%   Ún_epochsr&   r'   r(   r)   r*   r+   Úinitial_alphaÚnegative_sample_raterP   ÚverboseÚdensmapÚdensmap_kwdsÚ	tqdm_kwdsr,   r   r-   r.   r/   r0   Úoptimize_fnZdens_init_fnr;   r8   r9   r:   r3   r4   Údens_var_shiftr1   r2   r6   r7   r5   r   r   r   Úoptimize_layout_euclideanÜ   s²    N
  ÿý



ÿýø
årl   c           "   	   C   s  t | jd ƒD �]ø}|| |kr|| }|| }|| }|| }|||f|žŽ \}}|||f|žŽ \}}|dkrŽtd|t|d| ƒ  dƒ}nd}d| |d  |d  }t |ƒD ]P}t|||  ƒ}||  ||	 7  < |
r²t|||  ƒ}||  ||	 7  < q²||  | | 7  < t|||  ||  ƒ} t | ƒD ]¶}!t|ƒ| }|| }|||f|žŽ \}}|dk�rŒtd|t|d| ƒ  dƒ}n||k�rœ�q8nd}|d | | |d  }t |ƒD ]*}t|||  ƒ}||  ||	 7  < �qÀ�q8||  | ||  7  < q||fS )Nr   r   r   r   éÿÿÿÿr   ç�íµ ÷Æ°>)r   r   r   r   r!   r   )"r'   r0   r$   r%   r"   r#   Úoutput_metricÚoutput_metric_kwdsr   r-   r,   r1   r/   r.   r*   r&   r(   r)   r+   r   r<   r=   r>   r?   Údist_outputÚgrad_dist_outputÚ_Zrev_grad_dist_outputÚw_lrC   rD   rE   rF   rG   r   r   r   Ú%_optimize_layout_generic_single_epoch”  sb     ÿÿ
ÿ ÿÿ



ÿru   r   c                 C   s°   | j d }|}|| }| ¡ }| ¡ }tjtdd�}|dkr@i }d|krR| |d< tt|ƒf|ŽD ]H}|||||| ||||||||||	||||
ƒ |dt|ƒt|ƒ   }qb| S )a—	  Improve an embedding using stochastic gradient descent to minimize the
    fuzzy set cross entropy between the 1-skeletons of the high dimensional
    and low dimensional fuzzy simplicial sets. In practice this is done by
    sampling edges based on their membership strength (with the (1-p) terms
    coming from negative sampling similar to word2vec).

    Parameters
    ----------
    head_embedding: array of shape (n_samples, n_components)
        The initial embedding to be improved by SGD.

    tail_embedding: array of shape (source_samples, n_components)
        The reference embedding of embedded points. If not embedding new
        previously unseen points with respect to an existing embedding this
        is simply the head_embedding (again); otherwise it provides the
        existing embedding to embed with respect to.

    head: array of shape (n_1_simplices)
        The indices of the heads of 1-simplices with non-zero membership.

    tail: array of shape (n_1_simplices)
        The indices of the tails of 1-simplices with non-zero membership.

    n_epochs: int
        The number of training epochs to use in optimization.

    n_vertices: int
        The number of vertices (0-simplices) in the dataset.

    epochs_per_sample: array of shape (n_1_simplices)
        A float value of the number of epochs per 1-simplex. 1-simplices with
        weaker membership strength will have more epochs between being sampled.

    a: float
        Parameter of differentiable approximation of right adjoint functor

    b: float
        Parameter of differentiable approximation of right adjoint functor

    rng_state: array of int64, shape (3,)
        The internal state of the rng

    gamma: float (optional, default 1.0)
        Weight to apply to negative samples.

    initial_alpha: float (optional, default 1.0)
        Initial learning rate for the SGD.

    negative_sample_rate: int (optional, default 5)
        Number of negative samples to use per positive sample.

    verbose: bool (optional, default False)
        Whether to report information on the current progress of the algorithm.

    tqdm_kwds: dict (optional, default None)
        Keyword arguments for tqdm progress bar.

    move_other: bool (optional, default False)
        Whether to adjust tail_embedding alongside head_embedding

    Returns
    -------
    embedding: array of shape (n_samples, n_components)
        The optimized embedding.
    r   T©r   NrW   r   )r   rY   r   rZ   ru   r   r   r^   )r"   r#   r$   r%   rc   r&   r'   r(   r)   r*   r+   rd   re   ro   rp   rf   ri   r,   r   r-   r.   r/   r0   rj   r1   r   r   r   Úoptimize_layout_genericæ  sJ    V
þ
írw   c           "      C   sº  t | jd ƒD �]¤}|| |kr|| }|| }|| }|| }|||f|žŽ \}}|| }d||	|  d   }t |
ƒD ]B}t|||  ƒ}||  || 7  < |rz||  | | 7  < qz||  | | 7  < t|||  ||  ƒ}t |ƒD ]¨} t|ƒ| }|| }|||f|žŽ \}}t t|||  dƒ |	| d  ¡}!| d|! d|! |	|  d   }t |
ƒD ]*}t|||  ƒ}||  || 7  < �qnqò||  |||  7  < qd S )Nr   r   rn   )r   r   r   r!   r   r   r    Úmax)"r'   r0   r$   r%   r"   r#   ro   rp   ÚweightÚsigmasr   r-   r,   r1   r/   r.   r*   r&   Úrhosr+   r   r<   r=   r>   r?   rq   rr   rt   rC   rD   rE   rF   rG   Zw_hr   r   r   Ú%_optimize_layout_inverse_single_epochi  sP     ÿÿ
ÿ ÿÿ
&"
ÿr|   c                 C   s²   | j d }|}|	| }| ¡ }|	 ¡ }tjtdd�}|dkr@i }d|krR| |d< tt|ƒf|ŽD ]J}||	|||| |||||||||||||||ƒ |dt|ƒt|ƒ   }qb| S )a
  Improve an embedding using stochastic gradient descent to minimize the
    fuzzy set cross entropy between the 1-skeletons of the high dimensional
    and low dimensional fuzzy simplicial sets. In practice this is done by
    sampling edges based on their membership strength (with the (1-p) terms
    coming from negative sampling similar to word2vec).

    Parameters
    ----------
    head_embedding: array of shape (n_samples, n_components)
        The initial embedding to be improved by SGD.

    tail_embedding: array of shape (source_samples, n_components)
        The reference embedding of embedded points. If not embedding new
        previously unseen points with respect to an existing embedding this
        is simply the head_embedding (again); otherwise it provides the
        existing embedding to embed with respect to.

    head: array of shape (n_1_simplices)
        The indices of the heads of 1-simplices with non-zero membership.

    tail: array of shape (n_1_simplices)
        The indices of the tails of 1-simplices with non-zero membership.

    weight: array of shape (n_1_simplices)
        The membership weights of the 1-simplices.

    sigmas:

    rhos:

    n_epochs: int
        The number of training epochs to use in optimization.

    n_vertices: int
        The number of vertices (0-simplices) in the dataset.

    epochs_per_sample: array of shape (n_1_simplices)
        A float value of the number of epochs per 1-simplex. 1-simplices with
        weaker membership strength will have more epochs between being sampled.

    a: float
        Parameter of differentiable approximation of right adjoint functor

    b: float
        Parameter of differentiable approximation of right adjoint functor

    rng_state: array of int64, shape (3,)
        The internal state of the rng

    gamma: float (optional, default 1.0)
        Weight to apply to negative samples.

    initial_alpha: float (optional, default 1.0)
        Initial learning rate for the SGD.

    negative_sample_rate: int (optional, default 5)
        Number of negative samples to use per positive sample.

    verbose: bool (optional, default False)
        Whether to report information on the current progress of the algorithm.

    tqdm_kwds: dict (optional, default None)
        Keyword arguments for tqdm progress bar.

    move_other: bool (optional, default False)
        Whether to adjust tail_embedding alongside head_embedding

    Returns
    -------
    embedding: array of shape (n_samples, n_components)
        The optimized embedding.
    r   Trv   NrW   r   )r   rY   r   rZ   r|   r   r   r^   )r"   r#   r$   r%   ry   rz   r{   rc   r&   r'   r(   r)   r*   r+   rd   re   ro   rp   rf   ri   r,   r   r-   r.   r/   r0   rj   r1   r   r   r   Úoptimize_layout_inverse±  sL    `
þ
ìr}   c           (      C   sö  t |ƒ}|jd d d }d}|D ]}|jd |kr"|jd }q"t |¡ tj¡}tj t|	d ƒ¡ tj 	|¡ t
|ƒD �]t}|D �]h}||| jd k r„|| | |kr„|| | }|| | }| | | }|| | }t||ƒ}|dk�r"d| | t||d ƒ }||t||ƒ d  }nd}t
|ƒD �]Ä} t|||  ||    ƒ}!t
| |ƒD ]ž}"||" }#||#  k�rˆd  k�rˆ|"k�rXn nh|||"| |f }$|$dk�rX|!t|t t |"¡d  ¡ |||"| |f  ||  | |# |$| f   ƒ8 }!�qX||   t|!ƒ| 7  < |�r.t|||  ||    ƒ}%t
| |ƒD ]ž}"||" }#||#  k�rjd  k�rj|"k�r:n nh|||"| |f }$|$dk�r:|!t|t t |"¡d  ¡ |||"| |f  ||  | |# |$| f   ƒ8 }!�q:||   t|%ƒ| 7  < �q.|| |  || | 7  < || | dk�rFt||| |  || |  ƒ}&nd}&t
|&ƒD �]x}'t|	ƒ|| jd  }|| | }t||ƒ}|dk�rºd|
 | }|d| |t||ƒ d   }n||k�rÊ�qRnd}t
|ƒD ]ò} |dk�rþt|||  ||    ƒ}!nd	}!t
| |ƒD ]ž}"||" }#||#  k�r>d  k�r>|"k�rn nh|||"| |f }$|$dk�r|!t|t t |"¡d  ¡ |||"| |f  ||  | |# |$| f   ƒ8 }!�q||   t|!ƒ| 7  < �qÖ�qR|| |  |&|| |  7  < q„qzd S )
Nr   r   r   r   r   r   r   r   r   )Úlenr   r   ÚarangeÚastypeÚint32ÚrandomÚseedÚabsÚshuffler   r   r   r   r    r!   r   )(Úhead_embeddingsÚtail_embeddingsÚheadsÚtailsr'   r(   r)   Úregularisation_weightsÚ	relationsr*   r+   Úlambda_r   r,   r-   r.   r/   r0   r1   Zn_embeddingsZwindow_sizeZmax_n_edgesZe_p_sZembedding_orderr   Úmr<   r=   r>   r?   r@   rC   rD   rE   ÚoffsetZ
neighbor_mZidentified_indexZother_grad_drF   rG   r   r   r   Ú/_optimize_layout_aligned_euclidean_single_epoch?  sÖ    
"

(
ÿÿÿýÿ
(
ÿÿÿÿûÿ

ÿÿ

ÿ

(
ÿÿÿÿûÿ
 ÿr�   ç‘Pá);ù?çÏìîµV¤ì?ç{®Gázt?c                 C   sJ  | d j d }|}tjj tjjd d d… ¡}tjj tjjd d d… ¡}tjj tjjd d d… ¡}tt|ƒƒD ]J}| 	||  
tj¡| ¡ | 	||  
tj¡¡ | 	||  
tj¡¡ qrtjtd|d�}|d krÚi }d|krì| |d< tt|ƒf|ŽD ]H}|| |||||	|
||||||||||||ƒ |dt|ƒt|ƒ   }qü| S )Nr   r   TrO   rW   r   )r   r   ÚtypedÚListÚ
empty_listÚtypesr]   r   r~   Úappendr€   r   rZ   r�   r   r^   )r†   r‡   rˆ   r‰   rc   r'   rŠ   r‹   r*   r(   r)   r+   rŒ   rd   re   rP   rf   ri   r,   r   r-   r.   r/   r0   r�   rj   r1   r   r   r   Ú!optimize_layout_aligned_euclideanÖ  s`    ÿÿÿý
ír˜   )	r   r   rN   FFFNNF)
r�   r‘   r   r’   r   rN   TFNF)Únumpyr   r   Úumap.distancesÚ	distancesÚdistÚ
umap.utilsr   Z	tqdm.autor   rZ   r   r–   r]   Úintpr   rH   rM   rl   ru   Ú	euclideanrw   r|   r}   r�   r˜   r   r   r   r   Ú<module>   s€   
ýü

~,         í
 9]î
 Vë
  "          í