U
    ÅmœdK&  ã                   @   sÂ  d dl mZ d dlmZmZ d dlZd dlmZ d dlm	Z	 d dl
Z
d dlZd dlZd dlmZ edddddddœeeeejejf  ee ee ee ee eeejef d	œd
d„ƒZe
jddd�dd„ ƒZe
jddd�dd„ ƒZe
jdd�dd„ ƒZe
jdd�dd„ ƒZe
jddd�dd„ ƒZe
jddd�dd„ ƒZedd„ ƒZe ej¡e ej ¡dd„ ƒƒZ!e ej¡dd„ ƒZ!e ej"¡e ej#¡d d„ ƒƒZ!d!d"„ Z$e ej ¡ejd#œd$d%„ƒZ%dS )&é    )Úsingledispatch)ÚOptionalÚUnionN)ÚAnnData)Ú_get_obs_rep)ÚsparseF)ÚvalsÚ	use_graphÚlayerÚobsmÚobspÚuse_raw)Úadatar   r	   r
   r   r   r   Úreturnc                C   sx   |dkrLt | dƒr(d| jkr(| jd }qRd| jkrB| jd d }qRtdƒ‚ntƒ ‚|dkrnt| ||||d�j}t||ƒS )a=  
    Calculate `Geary's C <https://en.wikipedia.org/wiki/Geary's_C>`_, as used
    by `VISION <https://doi.org/10.1038/s41467-019-12235-0>`_.

    Geary's C is a measure of autocorrelation for some measure on a graph. This
    can be to whether measures are correlated between neighboring cells. Lower
    values indicate greater correlation.

    .. math::

        C =
        \frac{
            (N - 1)\sum_{i,j} w_{i,j} (x_i - x_j)^2
        }{
            2W \sum_i (x_i - \bar{x})^2
        }

    Params
    ------
    adata
    vals
        Values to calculate Geary's C for. If this is two dimensional, should
        be of shape `(n_features, n_cells)`. Otherwise should be of shape
        `(n_cells,)`. This matrix can be selected from elements of the anndata
        object by using key word arguments: `layer`, `obsm`, `obsp`, or
        `use_raw`.
    use_graph
        Key to use for graph in anndata object. If not provided, default
        neighbors connectivities will be used instead.
    layer
        Key for `adata.layers` to choose `vals`.
    obsm
        Key for `adata.obsm` to choose `vals`.
    obsp
        Key for `adata.obsp` to choose `vals`.
    use_raw
        Whether to use `adata.raw.X` for `vals`.


    This function can also be called on the graph and values directly. In this case
    the signature looks like:

    Params
    ------
    g
        The graph
    vals
        The values


    See the examples for more info.

    Returns
    -------
    If vals is two dimensional, returns a 1 dimensional ndarray array. Returns
    a scalar if `vals` is 1d.


    Examples
    --------

    Calculate Gearys C for each components of a dimensionality reduction:

    .. code:: python

        import scanpy as sc, numpy as np

        pbmc = sc.datasets.pbmc68k_processed()
        pc_c = sc.metrics.gearys_c(pbmc, obsm="X_pca")


    It's equivalent to call the function directly on the underlying arrays:

    .. code:: python

        alt = sc.metrics.gearys_c(pbmc.obsp["connectivities"], pbmc.obsm["X_pca"].T)
        np.testing.assert_array_equal(pc_c, alt)
    Nr   ZconnectivitiesZ	neighborszMust run neighbors first.)r   r
   r   r   )Úhasattrr   ZunsÚ
ValueErrorÚNotImplementedErrorr   ÚTÚgearys_c)r   r   r	   r
   r   r   r   Úg© r   úQ/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/scanpy/metrics/_gearys_c.pyr      s    Y

r   T)ÚcacheÚparallelc                 C   s   |   ¡ }t| ||||ƒS ©N)ÚsumÚ_gearys_c_vec_W)ÚdataÚindicesÚindptrÚxÚWr   r   r   Ú_gearys_c_vec…   s    r"   c                 C   s¬   t |ƒd }| tj¡}| ¡ }d}t |¡D ]L}t|| ||d  ƒ}	||	 }
| |	 }|t ||| ||
  d  ¡7 }q.|d | }d| || d  ¡  }|| }|S )Né   ç        é   )	ÚlenÚastypeÚnpÚfloat_ÚmeanÚnumbaÚprangeÚslicer   )r   r   r   r    r!   ÚNÚx_barÚtotalÚiÚsÚ	i_indicesÚi_dataÚnumerÚdenomÚCr   r   r   r   ‹   s    $r   )r   c                 C   sœ   |  ¡ }d}t|ƒ}t |¡D ]L}t|| ||d  ƒ}	||	 }
| |	 }|t ||| ||
  d  ¡7 }q|d | }d| || d  ¡  }|| }|S )Nr$   r#   r%   )r*   r&   r+   r,   r-   r(   r   )Úg_dataÚ	g_indicesÚg_indptrr    r!   r/   r0   r.   r1   r2   r3   r4   r5   r6   r7   r   r   r   Ú!_gearys_c_inner_sparse_x_densevecª   s    $r;   c                 C   sÖ   t j|t jd�}|||< t  |¡| }d}	t|ƒ}t |¡D ]L}
t||
 ||
d  ƒ}|| }| | }|	t  |||
 ||  d  ¡7 }	q<|d |	 }d| t  |d ¡t  || d ¡ |d |   }|| }|S )N©Zdtyper$   r#   r%   )r(   Úzerosr)   r   r&   r+   r,   r-   )r8   r9   r:   Úx_dataÚ	x_indicesr.   r!   r    r/   r0   r1   r2   r3   r4   r5   r6   r7   r   r   r   Ú"_gearys_c_inner_sparse_x_sparsevecº   s*    $ÿ
þþÿ	r@   c           
      C   sv   |j \}}|t|ƒd kst‚|  ¡ }tj|tjd�}t |¡D ]0}||d d …f  	tj¡}	t
| |||	|ƒ||< q@|S )Nr#   r<   )Úshaper&   ÚAssertionErrorr   r(   r=   r)   r+   r,   r'   r;   )
r8   r9   r:   ÚXÚMr.   r!   ÚoutÚkr    r   r   r   Ú_gearys_c_mtxÙ   s    
rG   c              	   C   s|   |\}}|   ¡ }	tj|tjd�}
t ||dd… ¡}t ||dd… ¡}t |¡D ]$}t| |||| || ||	ƒ|
|< qR|
S )Nr<   r#   éÿÿÿÿ)r   r(   r=   r)   Úsplitr+   r,   r@   )r8   r9   r:   r>   r?   Zx_indptrZx_shaperD   r.   r!   rE   Zx_data_listZx_indices_listrF   r   r   r   Ú_gearys_c_mtx_csrå   s     ù
	rJ   c                 C   s
   t  | ¡S r   )r(   Zasarray©Úvalr   r   r   Ú_resolve_valsþ   s    rM   c                 C   s   | S r   r   rK   r   r   r   Ú_  s    rN   c                 C   s
   t  | ¡S r   )r   Ú
csr_matrixrK   r   r   r   rN   	  s    c                 C   s   |   ¡ S r   )Zto_numpyrK   r   r   r   rN     s    c                 C   s|   ddl m} tj| jd tjd�}| tj¡ || dd� }| ¡ rNt	dƒ}n t
 tt|ƒ| ¡  › d�ƒ¡ | | ||fS )zé    Checks that values wont cause issues in computation.

    Returns new set of vals, and indexer to put values back into result.

    For details on why this is neccesary, see:
    https://github.com/scverse/scanpy/issues/1806
    r   )Úis_constantr<   r#   )ZaxisNz4 variables were constant, will return nan for these.)Zscanpy._utilsrP   r(   ÚemptyrA   Zfloat64ÚfillÚnanÚallr-   ÚwarningsÚwarnÚUserWarningr&   r   )r   rP   Úfull_resultÚidxerr   r   r   Ú_check_vals  s    	
ÿÿrZ   )r   c                 C   sJ  | j d | j d kstdƒ‚t|ƒ}| jjtjdd�}t|tj	ƒr | j d |j d ksZt‚t
|ƒ\}}}t|| j| j|jjtjdd�|j|j|j ƒ}|||< |S t|tjƒrà|jdkrà| j d |j d ksÎt‚t|| j| j|ƒS t|tjƒ�r@|jdk�r@| j d |j d k�st‚t
|ƒ\}}}t|| j| j|ƒ}|||< |S tƒ ‚d S )Nr   r#   z'`g` should be a square adjacency matrixF)Úcopyr%   )rA   rB   rM   r   r'   r(   r)   Ú
isinstancer   rO   rZ   rJ   r   r   ÚndarrayÚndimr"   rG   r   )r   r   r8   Únew_valsrY   rX   Úresultr   r   r   Ú	_gearys_c-  s6    ù	ra   )&Ú	functoolsr   Útypingr   r   rU   Zanndatar   Z
scanpy.getr   r+   Únumpyr(   ZpandasÚpdZscipyr   r]   ZspmatrixÚstrÚboolÚfloatr   Znjitr"   r   r;   r@   rG   rJ   rM   ÚregisterrO   rN   Z	DataFrameZSeriesrZ   ra   r   r   r   r   Ú<module>   sd   ø÷v















