§
    ÏÁ³gP  ã                   ó  — d dl Zd dlT d dlZd dlZd„ Zd„ Zed fd„Z	d d„Z
d!d„ZeZd d	„Zd
„ ZeZd"d„Zd„ Zd„ ZeZd#d„ZeZd#d„Z G d„ d¦  «        Zd$d„Z G d„ d¦  «        Zedfd„Zd%d„Z G d„ d¦  «        Zd„ ZeZd„ Ze Z!d&d„Z dS )'é    N)Ú*c                 óÒ  — t          j        | d¬¦  «        } | j        \  }}t          j        ||fd¬¦  «        }t          j        ||fd¬¦  «        }t	          j        ¦   «         }t          |¦  «        |_        t          |¦  «        |_        ||_	        ||_
        |                     ¦   «          |                     |t          | ¦  «        ¦  «         |                     ¦   «          ||fS )zPreturn k smallest values (and their indices) of the lines of a
    float32 arrayÚfloat32©ÚdtypeÚint64)ÚnpÚascontiguousarrayÚshapeÚzerosÚfaissÚfloat_maxheap_array_tÚswig_ptrÚidsÚvalÚnhÚkÚheapifyÚaddnÚreorder©Úarrayr   ÚmÚnÚIÚDÚhas          úR/var/www/html/mpstechhub/venv/lib/python3.11/site-packages/faiss/extra_wrappers.pyÚkminr      óÇ   € õ Ô  ¨iÐ8Ñ8Ô8€EØŒ;�D€A€qÝ
Œ�!�Q�˜wÐ'Ñ'Ô'€AÝ
Œ�!�Q�˜yÐ)Ñ)Ô)€AÝ	Ô	$Ñ	&Ô	&€BÝ�a‰[Œ[€B„FÝ�a‰[Œ[€B„FØ€B„EØ€B„DØ‡J‚J�L„L€LØ‡G‚GˆA�x˜‰ŒÑÔÐØ‡J‚J�L„L€LØˆaˆ4€Kó    c                 óÒ  — t          j        | d¬¦  «        } | j        \  }}t          j        ||fd¬¦  «        }t          j        ||fd¬¦  «        }t	          j        ¦   «         }t          |¦  «        |_        t          |¦  «        |_        ||_	        ||_
        |                     ¦   «          |                     |t          | ¦  «        ¦  «         |                     ¦   «          ||fS )zOreturn k largest values (and their indices) of the lines of a
    float32 arrayr   r   r   )r	   r
   r   r   r   Úfloat_minheap_array_tr   r   r   r   r   r   r   r   r   s          r   Úkmaxr$   +   r    r!   c                 ó  — t          j        | d¬¦  «        } t          j        |d¬¦  «        }| j        \  }}|j        \  }}||k    sJ ‚t          j        ||fd¬¦  «        }|t          k    r<t          ||t          | ¦  «        |t          |¦  «        t          |¦  «        ¦  «         nX|t          k    r| |j        z  |dd…<   n=t          ||t          | ¦  «        |t          |¦  «        ||t          |¦  «        ¦  «         |S )zJcompute the whole pairwise distance matrix between two sets of
    vectorsr   r   N)
r	   r
   r   ÚemptyÚ	METRIC_L2Úpairwise_L2sqrr   ÚMETRIC_INNER_PRODUCTÚTÚpairwise_extra_distances)	ÚxqÚxbÚmetricÚ
metric_argÚnqÚdÚnbÚd2Údiss	            r   Úpairwise_distancesr5   =   s  € õ 
Ô	˜b¨	Ð	2Ñ	2Ô	2€BÝ	Ô	˜b¨	Ð	2Ñ	2Ô	2€BØŒH�E€BˆØŒX�F€BˆØ�Š7ˆ7ˆ7ˆ7Ý
Œ(�B˜�8 9Ð
-Ñ
-Ô
-€CØ•ÒÐÝØˆr•8˜B‘<”<Ø•˜‘”Ý�S‰MŒMñ	ô 	ð 	ð 	ð 
Õ'Ò	'Ð	'Ø�b”d‘ˆˆAˆAˆA‰ˆå Øˆr•8˜B‘<”<Ø•˜‘”Ø�JÝ�S‰MŒMñ		ô 	ð 	ð
 €Jr!   é90  c                 óx   — t          j        | d¬¦  «        }t          t          |¦  «        |j        |¦  «         |S ©Nr   r   )r	   r&   Ú
float_randr   Úsize©r   ÚseedÚress      r   Úrandr>   V   s5   € Ý
Œ(�1˜IÐ
&Ñ
&Ô
&€CÝ�x˜‰}Œ}˜cœh¨Ñ-Ô-Ð-Ø€Jr!   c                 óÆ   — t          j        | d¬¦  «        }|€$t          t          |¦  «        |j        |¦  «         n$t          t          |¦  «        |j        ||¦  «         |S ©Nr   r   )r	   r&   Ú
int64_randr   r:   Úint64_rand_max)r   r<   Úvmaxr=   s       r   ÚrandintrD   \   sY   € Ý
Œ(�1˜GÐ
$Ñ
$Ô
$€CØ€|Ý•8˜C‘=”= #¤(¨DÑ1Ô1Ð1Ð1å•x ‘}”} c¤h°°dÑ;Ô;Ð;Ø€Jr!   c                 óx   — t          j        | d¬¦  «        }t          t          |¦  «        |j        |¦  «         |S r8   )r	   r&   Úfloat_randnr   r:   r;   s      r   ÚrandnrG   h   s5   € Ý
Œ(�1˜IÐ
&Ñ
&Ô
&€CÝ•˜‘”˜sœx¨Ñ.Ô.Ð.Ø€Jr!   c                 ó"  — |                       d¦  «        } | j        dk    r"t          | j        t	          | ¦  «        ¦  «        S | j        \  }}t          j        |d¬¦  «        }t          ||t	          | ¦  «        t	          |¦  «        ¦  «         |S )z> compute a checksum for quick-and-dirty comparisons of arrays Úuint8é   Úuint64r   )	ÚviewÚndimÚbvec_checksumr:   r   r   r	   r   Úbvecs_checksum)Úar   r1   Úcss       r   ÚchecksumrR   n   sx   € à	�Šˆw‰Œ€AØ„v�‚{€{Ý˜QœV¥X¨a¡[¤[Ñ1Ô1Ð1ØŒ7�D€A€qÝ	Œ�!˜8Ð	$Ñ	$Ô	$€BÝ�1�a� !™œ¥h¨r¡l¤lÑ3Ô3Ð3Ø€Ir!   éÒ  c                 ót   — t          j        | |fd¬¦  «        }t          | |t          |¦  «        |¦  «         |S r8   )r	   r&   Úrand_smooth_vectors_cr   )r   r1   r<   r=   s       r   Úrand_smooth_vectorsrV   z   s9   € Ý
Œ(�A�q�6 Ð
+Ñ
+Ô
+€CÝ˜!˜Q¥¨¡¤¨tÑ4Ô4Ð4Ø€Jr!   c                 óp  — t          j        | d¬¦  «        } t          j        |d¬¦  «        }| j        d         }|j        d         |k    sJ ‚| j        d         |j        d         }}d}t          |¦  «        D ]=}|t	          |t          | |         ¦  «        |t          ||         ¦  «        ¦  «        z  }Œ>|S )z< size of intersection between each line of two result tablesr   r   r   rJ   )r	   r
   r   ÚrangeÚranklist_intersection_sizer   )ÚI1ÚI2r   Úk1Úk2ÚninterÚis          r   Úeval_intersectionr`   €   s¸   € å	Ô	˜b¨Ð	0Ñ	0Ô	0€BÝ	Ô	˜b¨Ð	0Ñ	0Ô	0€BØ
Œ�Œ€AØŒ8�AŒ;˜!ÒÐÐÐØŒX�aŒ[˜"œ( 1œ+ˆ€BØ€FÝ�1‰XŒXð 6ð 6ˆØÕ,Ø•˜˜Aœ‘” ¥X¨b°¬e¡_¤_ñ6ô 6ñ 	6ˆˆà€Mr!   c                 ón   — t          | j        d         | j        d         t          | ¦  «        ¦  «         d S )NrJ   r   )Úfvec_renorm_L2r   r   ©Úxs    r   Únormalize_L2re   Ž   s,   € Ý�1”7˜1”:˜qœw qœz­8°A©;¬;Ñ7Ô7Ð7Ð7Ð7r!   c           	      ó®  — t          j        | d¬¦  «        } |€$t          |                      ¦   «         dz   ¦  «        }t          j        |dz   d¬¦  «        }t          j        | j        d¬¦  «        }t          | j        t          j        |  	                    d¦  «        ¦  «        |t          j        |¦  «        t          j        |¦  «        |¦  «         ||fS )aù  Perform a bucket sort on a table of integers.

    Parameters
    ----------
    tab : array_like
        elements to sort, max value nbucket - 1
    nbucket : integer
        number of buckets, None if unknown
    nt : integer
        number of threads to use (0 = use unthreaded codepath)

    Returns
    -------
    lims : array_like
        cumulative sum of bucket sizes (size vmax + 1)
    perm : array_like
        perm[lims[i] : lims[i + 1]] contains the indices of bucket #i (size tab.size)
    r   r   NrJ   rK   )
r	   r
   ÚintÚmaxr&   r:   Úbucket_sort_cr   r   rL   )ÚtabÚnbucketÚntÚlimsÚperms        r   Úbucket_sortro   “   s¾   € õ& Ô
˜s¨'Ð
2Ñ
2Ô
2€CØ€Ý�c—g’g‘i”i !‘mÑ$Ô$ˆÝŒ8�G˜a‘K wÐ/Ñ/Ô/€DÝŒ8�C”H GÐ,Ñ,Ô,€DÝØŒ•%”. §¢¨(Ñ!3Ô!3Ñ4Ô4Ø•” Ñ%Ô%¥u¤~°dÑ';Ô';Ø
ñô ð ð
 �ˆ:Ðr!   c           	      ó8  — | j         dk    s| j         dk    sJ ‚| j        \  }}|€$t          |                      ¦   «         dz   ¦  «        }t	          j        |dz   d¬¦  «        }t          ||t          j        | ¦  «        |t          j        |¦  «        |¦  «         |S )a®  Perform a bucket sort on a matrix, recording the original
    row of each element.

    Parameters
    ----------
    tab : array_like
        array of size (N, ncol) that contains the bucket ids, maximum
        value nbucket - 1.
        On output, it the elements are shuffled such that the flat array
        tab.ravel()[lims[i] : lims[i + 1]] contains the row numbers
        of each bucket entry.
    nbucket : integer
        number of buckets (the maximum value in tab should be nbucket - 1)
    nt : integer
        number of threads to use (0 = use unthreaded codepath)

    Returns
    -------
    lims : array_like
        cumulative sum of bucket sizes (size vmax + 1)
    Úint32r   NrJ   r   )	r   r   rg   rh   r	   r&   Úmatrix_bucket_sort_inplace_cr   r   )rj   rk   rl   ÚnrowÚncolrm   s         r   Úmatrix_bucket_sort_inplaceru   ´   s    € ð, Œ9˜ÒÐ 3¤9°Ò#7Ð#7Ð#7Ð#7Ø”�J€Dˆ$Ø€Ý�c—g’g‘i”i !‘mÑ$Ô$ˆÝŒ8�G˜a‘K wÐ/Ñ/Ô/€DÝ Øˆd•E”N 3Ñ'Ô'Ø•” Ñ%Ô%Ø
ñô ð ð
 €Kr!   c                   ó,   — e Zd ZdZdd„Zd„ Zd„ Zd„ ZdS )	Ú
ResultHeapz_Accumulate query results from a sliced dataset. The final result will
    be in self.D, self.I.Fc                 óŒ  — t          j        ||fd¬¦  «        | _        t          j        ||fd¬¦  «        | _        ||c| _        | _        |rt          ¦   «         }nt          ¦   «         }||_        ||_        t          | j        ¦  «        |_
        t          | j        ¦  «        |_        |                     ¦   «          || _        dS )z›
        nq: number of query vectors,
        k: number of results per query
        keep_max: keep the top-k maximum values instead of the minima
        r   r   r   N)r	   r   r   r   r0   r   r#   r   r   r   r   r   r   Úheaps)Úselfr0   r   Úkeep_maxry   s        r   Ú__init__zResultHeap.__init__ß   s¯   € õ ”˜2˜q˜'¨Ð1Ñ1Ô1ˆŒÝ”˜2˜q˜'¨Ð3Ñ3Ô3ˆŒØ˜aˆˆŒ�”Øð 	,Ý)Ñ+Ô+ˆEˆEå)Ñ+Ô+ˆEØˆŒØˆŒÝ˜TœVÑ$Ô$ˆŒ	Ý˜TœVÑ$Ô$ˆŒ	Ø�Š‰ŒˆØˆŒ
ˆ
ˆ
r!   c                 ó  — |j         \  }}t          j        |d¬¦  «        }t          j        |d¬¦  «        }|j         ||fk    sJ ‚|| j        k    sJ ‚| j                             |t          |¦  «        t          |¦  «        |¦  «         dS )z›
        Add results for all heaps
        D, I should be of size (nh, nres)
        D, I do not need to be in a particular order (heap or sorted)
        r   r   r   N)r   r	   r
   r0   ry   Úaddn_with_idsr   )rz   r   r   r0   Úkds        r   Ú
add_resultzResultHeap.add_resultó   s™   € ð ”‰ˆˆBÝÔ  ¨)Ð4Ñ4Ô4ˆÝÔ  ¨'Ð2Ñ2Ô2ˆØŒw˜2˜r˜(Ò"Ð"Ð"Ð"Ø�T”WŠ}ˆ}ˆ}ˆ}ØŒ
× Ò Ø•˜‘”Ý�Q‰KŒK˜ñ	ô 	ð 	ð 	ð 	r!   c           	      óÚ  — |j         \  }}|t          |¦  «        k    sJ ‚|j        dk    r|j         |j         k    s|j        dk    r|j         |fk    sJ ‚t          j        |d¬¦  «        }t          j        |d¬¦  «        }t          j        |d¬¦  «        }|j        dk    rdn|}| j                             |t          |¦  «        |t          |¦  «        t          |¦  «        |¦  «         dS )z·
        Add results for a subset of heaps.
        D, I should hold resutls for all the subset
        as a special case, if I is 1D, then all ids are assumed to be the same
        é   rJ   r   r   r   r   N)r   ÚlenrM   r	   r
   ry   Úaddn_query_subset_with_idsr   )rz   Úsubsetr   r   Únsubsetr   Ú	id_strides          r   Úadd_result_subsetzResultHeap.add_result_subset  sö   € ð ”g‰ˆ�Ø�#˜f™+œ+Ò%Ð%Ð%Ð%àŒF�aŠKˆK˜AœG q¤wÒ.Ð.ØŒF�aŠKˆK˜AœG¨ vÒ-Ð-Ð-Ð-åÔ  ¨)Ð4Ñ4Ô4ˆÝÔ  ¨'Ð2Ñ2Ô2ˆÝÔ% f°GÐ<Ñ<Ô<ˆØœ 1š˜�A�A¨"ˆ	ØŒ
×-Ò-Ø•X˜fÑ%Ô%Ø•˜‘”�X a™[œ[¨)ñ	
ô 	
ð 	
ð 	
ð 	
r!   c                 ó8   — | j                              ¦   «          d S ©N)ry   r   )rz   s    r   ÚfinalizezResultHeap.finalize  s   € ØŒ
×ÒÑÔÐÐÐr!   N©F)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r|   r€   rˆ   r‹   © r!   r   rw   rw   Û   s_   € € € € € ðð ðð ð ð ð(ð ð ð
ð 
ð 
ð*ð ð ð ð r!   rw   Fc                 ób  — |j         | j         k    sJ ‚| j         \  }}}t          j        ||f| j        ¬¦  «        }t          j        ||f|j        ¬¦  «        }|rt          nt
          } ||||t          | ¦  «        t          |¦  «        t          |¦  «        t          |¦  «        ¦  «         ||fS )zÝ
    Merge a set of sorted knn-results obtained from different shards in a dataset
    Dall and Iall are of size (nshard, nq, k) each D[i, j] should be sorted
    returns D, I of size (nq, k) as the merged result set
    r   )r   r	   r&   r   Úmerge_knn_results_CMaxÚmerge_knn_results_CMinr   )	ÚDallÚIallr{   Únshardr   r   ÚDnewÚInewÚfuncs	            r   Úmerge_knn_resultsr›     s´   € ð Œ:˜œÒ#Ð#Ð#Ð#Ø”:�L€FˆAˆqÝŒ8�Q˜�F $¤*Ð-Ñ-Ô-€DÝŒ8�Q˜�F $¤*Ð-Ñ-Ô-€DØ%-ÐIÕ!Ð!Õ3I€DØ€DØ	ˆ1ˆfÝ�‰Œ� ™œÝ�‰Œ� ™œñô ð ð
 �ˆ:Ðr!   c                   ó    — e Zd Zd„ Zd„ Zd„ ZdS )ÚMapInt64ToInt64c                 ó"  — t          t          j        |¦  «        ¦  «        | _        |d| j        z  k    s
J d¦   «         ‚|| _        t          j        |dfd¬¦  «        | _        t          j        | j        t          | j        ¦  «        ¦  «         d S )Nr‚   zneed power of 2 capacityr   r   )
rg   r	   Úlog2Úlog2_capacityÚcapacityr&   rj   r   Úhashtable_int64_to_int64_initr   )rz   r¡   s     r   r|   zMapInt64ToInt64.__init__3  s…   € Ý ¥¤¨Ñ!2Ô!2Ñ3Ô3ˆÔØ˜1 Ô 2Ñ2Ò2Ð2Ð2Ð4NÑ2Ô2Ð2Ø ˆŒÝ”8˜X q˜M°Ð9Ñ9Ô9ˆŒÝÔ+¨DÔ,>ÅÈÌÑ@RÔ@RÑSÔSÐSÐSÐSr!   c           	      óÆ   — |j         \  }|j         |fk    sJ ‚t          j        | j        t	          | j        ¦  «        |t	          |¦  «        t	          |¦  «        ¦  «         d S rŠ   )r   r   Úhashtable_int64_to_int64_addr    r   rj   )rz   ÚkeysÚvalsr   s       r   ÚaddzMapInt64ToInt64.add:  sd   € ØŒZ‰ˆØŒz˜a˜TÒ!Ð!Ð!Ð!ÝÔ*ØÔ¥¨¬Ñ 2Ô 2Ø�x˜‰~Œ~�x¨™~œ~ñ	/ô 	/ð 	/ð 	/ð 	/r!   c           	      óØ   — |j         \  }t          j        |fd¬¦  «        }t          j        | j        t          | j        ¦  «        |t          |¦  «        t          |¦  «        ¦  «         |S r@   )r   r	   r&   r   Úhashtable_int64_to_int64_lookupr    r   rj   )rz   r¥   r   r¦   s       r   ÚlookupzMapInt64ToInt64.lookupA  sb   € ØŒZ‰ˆÝŒx˜˜ GÐ,Ñ,Ô,ˆÝÔ-ØÔ¥¨¬Ñ 2Ô 2Ø�x˜‰~Œ~�x¨™~œ~ñ	/ô 	/ð 	/ð ˆr!   N)r�   rŽ   r�   r|   r§   rª   r‘   r!   r   r�   r�   1  sD   € € € € € ðTð Tð Tð/ð /ð /ðð ð ð ð r!   r�   ç        c                 óê  — t          j        | d¬¦  «        } t          j        |d¬¦  «        }| j        \  }}|j        \  }}||k    sJ ‚t          j        ||fd¬¦  «        }	t          j        ||fd¬¦  «        }
|t          k    rKt          t          | ¦  «        t          |¦  «        ||||t          |
¦  «        t          |	¦  «        ¦  «         n¢|t          k    rKt          t          | ¦  «        t          |¦  «        ||||t          |
¦  «        t          |	¦  «        ¦  «         nLt          t          | ¦  «        t          |¦  «        ||||||t          |
¦  «        t          |	¦  «        ¦
  «
         |
|	fS )aÅ  
    Compute the k nearest neighbors of a vector without constructing an index


    Parameters
    ----------
    xq : array_like
        Query vectors, shape (nq, d) where the dimension d is that same as xb
        `dtype` must be float32.
    xb : array_like
        Database vectors, shape (nb, d) where dimension d is the same as xq
        `dtype` must be float32.
    k : int
        Number of nearest neighbors.
    metric : MetricType, optional
        distance measure to use (either METRIC_L2 or METRIC_INNER_PRODUCT)

    Returns
    -------
    D : array_like
        Distances of the nearest neighbors, shape (nq, k)
    I : array_like
        Labels of the nearest neighbors, shape (nq, k)
    r   r   r   )
r	   r
   r   r&   r'   Ú	knn_L2sqrr   r)   Úknn_inner_productÚknn_extra_metrics)r,   r-   r   r.   r/   r0   r1   r2   r3   r   r   s              r   Úknnr°   M  sj  € õ2 
Ô	˜b¨	Ð	2Ñ	2Ô	2€BÝ	Ô	˜b¨	Ð	2Ñ	2Ô	2€BØŒH�E€BˆØŒX�F€BˆØ�Š7ˆ7ˆ7ˆ7å
Œ�"�a� Ð(Ñ(Ô(€AÝ
Œ�"�a� 	Ð*Ñ*Ô*€Aà•ÒÐÝÝ�R‰LŒL�( 2™,œ,Øˆr�2�q�( 1™+œ+¥x°¡{¤{ñ	
ô 	
ð 	
ð 	
ð 
Õ'Ò	'Ð	'ÝÝ�R‰LŒL�( 2™,œ,Øˆr�2�q�( 1™+œ+¥x°¡{¤{ñ	
ô 	
ð 	
ð 	
õ
 	Ý�R‰LŒL�( 2™,œ,Øˆr�2�v˜z¨1Ý�Q‰KŒK� !™œñ	
ô 	
ð 	
ð ˆaˆ4€Kr!   Úhcc                 ó²  — | j         \  }}|j         \  }}||k    sJ ‚t          j        ||fd¬¦  «        }t          j        ||fd¬¦  «        }	|dk    r‘t          j        ¦   «         }
||
_        ||
_        t          j        |	¦  «        |
_        t          j        |¦  «        |
_	        t          j
        |
t          j        | ¦  «        t          j        |¦  «        ||d¦  «         nq|dk    rdt          j        t          j        | ¦  «        t          j        |¦  «        ||||t          j        |¦  «        t          j        |	¦  «        ¦  «         nt          ‚||	fS )a®  
    Compute the k nearest neighbors of a set of vectors without constructing an index.

    Parameters
    ----------
    xq : array_like
        Query vectors, shape (nq, d) where d is the number of bits / 8
        `dtype` must be uint8.
    xb : array_like
        Database vectors, shape (nb, d) where d is the number of bits / 8
        `dtype` must be uint8.
    k : int
        Number of nearest neighbors.
    variant : string
        Function variant to use, either "mc" (counter) or "hc" (heap)

    Returns
    -------
    D : array_like
        Distances of the nearest neighbors, shape (nq, k)
    I : array_like
        Labels of the nearest neighbors, shape (nq, k)
    rq   r   r   r±   rJ   Úmc)r   r	   r&   r   Úint_maxheap_array_tr   r   r   r   r   Úhammings_knn_hcÚhammings_knn_mcÚNotImplementedError)r,   r-   r   Úvariantr0   r1   r2   r3   r   r   Úheaps              r   Úknn_hammingrº   ƒ  sJ  € ð2 ŒH�E€BˆØŒX�F€BˆØ�Š7ˆ7ˆ7ˆ7Ý
Œ�"�a� Ð(Ñ(Ô(€AÝ
Œ�"�a� Ð(Ñ(Ô(€Aà�$‚€ÝÔ(Ñ*Ô*ˆØˆŒØˆŒÝ”> !Ñ$Ô$ˆŒÝ”> !Ñ$Ô$ˆŒÝÔØ•%”. Ñ$Ô$¥e¤n°RÑ&8Ô&8¸"Øˆqñ	
ô 	
ð 	
ð 	
ð 
�DŠˆÝÔÝŒN˜2ÑÔ¥¤¨rÑ 2Ô 2°B¸¸A¸qÝŒN˜1ÑÔ�uœ~¨aÑ0Ô0ñ	
ô 	
ð 	
ð 	
õ
 "Ð!Øˆaˆ4€Kr!   c                   ó4   — e Zd ZdZd„ Zd„ Zdd„Zd	d„Zd„ ZdS )
ÚKmeansaÇ  Object that performs k-means clustering and manages the centroids.
    The `Kmeans` class is essentially a wrapper around the C++ `Clustering` object.

    Parameters
    ----------
    d : int
       dimension of the vectors to cluster
    k : int
       number of clusters
    gpu: bool or int, optional
       False: don't use GPU
       True: use all GPUs
       number: use this many GPUs
    progressive_dim_steps:
        use a progressive dimension clustering (with that number of steps)

    Subsequent parameters are fields of the Clustring object. The most important are:

    niter: int, optional
       clustering iterations
    nredo: int, optional
       redo clustering this many times and keep best
    verbose: bool, optional
    spherical: bool, optional
       do we want normalized centroids?
    int_centroids: bool, optional
       round centroids coordinates to integer
    seed: int, optional
       seed for the random number generator

    c                 ó¤  — || _         |                      |¦  «         d| _        d|v rt          ¦   «         | _        nt          ¦   «         | _        |                     ¦   «         D ]X\  }}|dk    r"|dk    s|dk    rt          ¦   «         }|| _        Œ-t          | j        |¦  «         t          | j        ||¦  «         ŒY|  
                    ¦   «          dS )z¼d: input dimension, k: nb of centroids. Additional
         parameters are passed on the ClusteringParameters object,
         including niter=25, verbose=False, spherical = False
        FÚprogressive_dim_stepsÚgpuTéÿÿÿÿN)r1   Úresetr¿   Ú"ProgressiveDimClusteringParametersÚcpÚClusteringParametersÚitemsÚget_num_gpusÚgetattrÚsetattrÚ	set_index)rz   r1   r   ÚkwargsÚvs        r   r|   zKmeans.__init__Ü  sÐ   € ð
 ˆŒØ�
Š
�1‰ŒˆØˆŒØ" fÐ,Ð,Ý8Ñ:Ô:ˆDŒGˆGå*Ñ,Ô,ˆDŒGØ—L’L‘N”Nð 	'ð 	'‰DˆAˆqØ�EŠzˆzØ˜’9�9  R¢ Ý$™œ�AØ�”�õ ˜œ Ñ#Ô#Ð#Ý˜œ  AÑ&Ô&Ð&Ð&Ø�ŠÑÔÐÐÐr!   c                 ól  — | j         }| j        j        t          k    re| j        j        rt          |¦  «        | _        nt          |¦  «        | _        | j        r't          j
        | j        | j        ¬¦  «        | _        d S d S | j        rt          | j        ¬¦  «        }nt          ¦   «         }|| _        d S )N)Úngpu)r1   rÃ   Ú	__class__rÄ   Ú	sphericalÚIndexFlatIPÚindexÚIndexFlatL2r¿   r   Úindex_cpu_to_all_gpusÚGpuProgressiveDimIndexFactoryÚProgressiveDimIndexFactoryÚfac)rz   r1   rÖ   s      r   rÉ   zKmeans.set_indexó  s¯   € ØŒFˆØŒ7ÔÕ 4Ò4Ð4ØŒwÔ ð ,Ý(¨™^œ^�”
�
å(¨™^œ^�”
ØŒxð TÝ"Ô8¸¼È$Ì(ÐSÑSÔS�”
�
�
ðTð Tð Œxð 3Ý3¸¼ÐBÑBÔB��å0Ñ2Ô2�ØˆDŒHˆHˆHr!   Nc                 ó\   — |�t          |¦  «        | _        d| _        d| _        d| _        dS )zg prepare k-means object to perform a new clustering, possibly
        with another number of centroids N)rg   r   Ú	centroidsÚobjÚiteration_stats)rz   r   s     r   rÁ   zKmeans.reset  s2   € ð ˆ=Ý˜‘V”VˆDŒFØˆŒØˆŒØ#ˆÔÐÐr!   c                 óÚ  ‡
‡— t          j        |d¬¦  «        }|j        \  }}|| j        k    sJ ‚| j        j        t          k    rxt          || j        | j        ¦  «        }|�>|j        \  }}||k    sJ ‚t          j
        |                     ¦   «         |j        ¦  «         |                     || j        |¦  «         nZ|�J ‚|�J ‚| j        j        rJ ‚t!          || j        | j        ¦  «        }|                     |t#          |¦  «        | j        ¦  «         t          j        |j        ¦  «        }	|	                     | j        |¦  «        | _        |j        Šˆfd„t-          ‰                     ¦   «         ¦  «        D ¦   «         Št          j        d„ ‰D ¦   «         ¦  «        | _        d                     ¦   «         Š
ˆ
fd„‰D ¦   «         | _        | j        j        dk    r| j        d	         nd
S )a   Perform k-means clustering.
        On output of the function call:

        - the centroids are in the centroids field of size (`k`, `d`).

        - the objective value at each iteration is in the array obj (size `niter`)

        - detailed optimization statistics are in the array iteration_stats.

        Parameters
        ----------
        x : array_like
            Training vectors, shape (n, d), `dtype` must be float32 and n should
            be larger than the number of clusters `k`.
        weights : array_like
            weight associated to each vector, shape `n`
        init_centroids : array_like
            initial set of centroids, shape (n, d)

        Returns
        -------
        final_obj: float
            final optimization objective

        r   r   Nc                 ó:   •— g | ]}‰                      |¦  «        ‘ŒS r‘   )Úat)Ú.0r_   Ústatss     €r   ú
<listcomp>z Kmeans.train.<locals>.<listcomp>>  s#   ø€ Ð:Ð:Ð: �—’˜!‘”Ð:Ð:Ð:r!   c                 ó   — g | ]	}|j         ‘Œ
S r‘   )rÙ   )rÞ   Ústs     r   rà   z Kmeans.train.<locals>.<listcomp>?  s   € Ð4Ð4Ð4¨˜RœVÐ4Ð4Ð4r!   z,obj time time_search imbalance_factor nsplitc                 ó.   •‡— g | ]Šˆfd „‰D ¦   «         ‘ŒS )c                 ó2   •— i | ]}|t          ‰|¦  «        “ŒS r‘   )rÇ   )rÞ   Úfieldrâ   s     €r   ú
<dictcomp>z+Kmeans.train.<locals>.<listcomp>.<dictcomp>C  s%   ø€ Ð@Ð@Ð@¨5ˆU•G˜B Ñ&Ô&Ð@Ð@Ð@r!   r‘   )rÞ   râ   Ústat_fieldss    @€r   rà   z Kmeans.train.<locals>.<listcomp>B  s?   øø€ ð  
ð  
ð  
àð AÐ@Ð@Ð@°KÐ@Ñ@Ô@ð 
ð  
ð  
r!   r   rÀ   r«   )r	   r
   r   r1   rÃ   rÎ   rÄ   Ú
Clusteringr   r   Úcopy_array_to_vectorÚravelrØ   ÚtrainrÑ   rÏ   ÚProgressiveDimClusteringr   rÖ   Úvector_float_to_arrayÚreshaperÚ   rX   r:   r   rÙ   Úsplit)rz   rd   ÚweightsÚinit_centroidsr   r1   ÚclusÚncr3   rØ   rç   rß   s             @@r   rë   zKmeans.train  sé  øø€ õ4 Ô  ¨)Ð4Ñ4Ô4ˆØŒw‰ˆˆ1Ø�D”FŠ{ˆ{ˆ{ˆ{àŒ7ÔÕ 4Ò4Ð4å˜a ¤¨¬Ñ1Ô1ˆDØÐ)Ø'Ô-‘��BØ˜Q’w�w�w�wÝÔ*¨>×+?Ò+?Ñ+AÔ+AÀ4Ä>ÑRÔRÐRØ�JŠJ�q˜$œ* gÑ.Ô.Ð.Ð.ð �?�?�?Ø!Ð)Ð)Ð)Ø”wÔ(Ð(Ð(Ð(Ý+¨A¨t¬v°t´wÑ?Ô?ˆDØ�JŠJ�q�( 1™+œ+ t¤xÑ0Ô0Ð0åÔ/°´Ñ?Ô?ˆ	à"×*Ò*¨4¬6°1Ñ5Ô5ˆŒØÔ$ˆØ:Ð:Ð:Ð:¥e¨E¯JªJ©L¬LÑ&9Ô&9Ð:Ñ:Ô:ˆÝ”8Ð4Ð4¨eÐ4Ñ4Ô4Ñ5Ô5ˆŒàD×JÒJÑLÔLˆð 
ð  
ð  
ð  
àð 
ñ  
ô  
ˆÔð  $œxœ}¨qÒ0Ð0ˆtŒx˜Œ|ˆ|°cÐ9r!   c                 óL  — t          j        |d¬¦  «        }| j        €
J d¦   «         ‚| j                             ¦   «          | j                             | j        ¦  «         | j                             |d¦  «        \  }}|                     ¦   «         |                     ¦   «         fS )Nr   r   zshould train before assigningrJ   )r	   r
   rØ   rÑ   rÁ   r§   Úsearchrê   )rz   rd   r   r   s       r   ÚassignzKmeans.assignH  sŽ   € ÝÔ  ¨)Ð4Ñ4Ô4ˆØŒ~Ð)Ð)Ð+JÑ)Ô)Ð)ØŒ
×ÒÑÔÐØŒ
�Š�t”~Ñ&Ô&Ð&ØŒz× Ò   AÑ&Ô&‰ˆˆ1Ø�wŠw‰yŒy˜!Ÿ'š'™)œ)Ð#Ð#r!   rŠ   )NN)	r�   rŽ   r�   r�   r|   rÉ   rÁ   rë   rö   r‘   r!   r   r¼   r¼   »  su   € € € € € ðð ð@ð ð ð.ð ð ð $ð $ð $ð $ð::ð ::ð ::ð ::ðx$ð $ð $ð $ð $r!   r¼   c                 ó@   — t          | t          j        j        ¦  «        S rŠ   )Ú
isinstanceÚcollectionsÚabcÚSequencerc   s    r   Úis_sequencerü   U  s   € Ý�a�œÔ1Ñ2Ô2Ð2r!   c           	      óD  — | j         \  }}t          j        | d¬¦  «        } t          |¦  «        rŸt          j        |d¬¦  «        }|j         |fk    sJ ‚t	          |                     ¦   «         dz   dz  ¦  «        }t          j        ||fd¬¦  «        }t          ||t          |¦  «        t          | ¦  «        t          |¦  «        |¦  «         nQ||z  dz   dz  }t          j        ||fd¬¦  «        }t          |||t          | ¦  «        t          |¦  «        |¦  «         |S )a>  
    Pack a set integers (i, j) where i=0:n and j=0:M into
    n bitstrings.
    Output is an uint8 array of size (n, code_size), where code_size is
    such that at most 7 bits per code are wasted.

    If nbit is an integer: all entries takes nbit bits.
    If nbit is an array: entry (i, j) takes nbit[j] bits.
    rq   r   é   é   rI   )	r   r	   r
   rü   rg   Úsumr&   Úpack_bitstrings_cr   )rP   Únbitr   ÚMÚ	code_sizeÚbs         r   Úpack_bitstringsr  Z  s$  € ð Œ7�D€A€qÝ
Ô˜Q gÐ.Ñ.Ô.€AÝ�4ÑÔð 
KÝÔ# D°Ð8Ñ8Ô8ˆØŒz˜a˜TÒ!Ð!Ð!Ð!Ý˜Ÿš™œ a™¨AÑ-Ñ.Ô.ˆ	ÝŒH�a˜�^¨7Ð3Ñ3Ô3ˆÝØˆq•(˜4‘.”.¥(¨1¡+¤+­x¸©{¬{¸Iñ	Gô 	Gð 	Gð 	Gð ˜‘X ‘\ aÑ'ˆ	ÝŒH�a˜�^¨7Ð3Ñ3Ô3ˆÝ˜!˜Q ¥h¨q¡k¤kµ8¸A±;´;À	ÑJÔJÐJØ€Hr!   c           
      ó$  — | j         \  }}|€¨t          j        |d¬¦  «        }t          |¦  «        }t	          |                     ¦   «         dz   dz  ¦  «        }||k    sJ ‚t          j        ||fd¬¦  «        }t          ||t          |¦  «        t          | ¦  «        |t          |¦  «        ¦  «         n[|}||z  dz   dz  }||k    sJ ‚t          j        ||fd¬¦  «        }t          |||t          | ¦  «        |t          |¦  «        ¦  «         |S )a   
    Unpack a set integers (i, j) where i=0:n and j=0:M from
    n bitstrings (encoded as uint8s).
    Input is an uint8 array of size (n, code_size), where code_size is
    such that at most 7 bits per code are wasted.

    Two forms:
    - when called with (array, M, nbit): there are M entries of size
      nbit per row
    - when called with (array, nbits): element (i, j) is encoded in
      nbits[j] bits
    Nrq   r   rþ   rÿ   )	r   r	   r
   rƒ   rg   r   r&   Úunpack_bitstrings_cr   )r  Ú
M_or_nbitsr  r   r  r  Úmin_code_sizerP   s           r   Úunpack_bitstringsr  u  s$  € ð ”7�L€A€yØ€|ÝÔ# J°gÐ>Ñ>Ô>ˆÝ�‰IŒIˆÝ˜TŸXšX™ZœZ¨!™^°Ñ1Ñ2Ô2ˆØ˜MÒ)Ð)Ð)Ð)ÝŒH�a˜�V 7Ð+Ñ+Ô+ˆÝØˆq•(˜4‘.”.Ý�Q‰KŒK˜¥H¨Q¡K¤Kñ	1ô 	1ð 	1ð 	1ð ˆØ˜T™ A™¨!Ñ+ˆØ˜MÒ)Ð)Ð)Ð)ÝŒH�a˜�V 7Ð+Ñ+Ô+ˆÝØˆq�$� ™œ Yµ¸±´ñ	=ô 	=ð 	=à€Hr!   )r6   )r6   N)rS   )Nr   rŒ   )r±   rŠ   )"Únumpyr	   Úfaiss.loaderr   Úcollections.abcrù   r   r$   r'   r5   r>   rD   ÚlrandrG   rR   rV   rU   r`   re   ro   ri   ru   rr   rw   r›   r�   r°   rº   r¼   rü   r  r  r  r  r‘   r!   r   ú<module>r     sD  ðð Ð Ð Ð à Ð Ð Ð à €€€à Ð Ð Ð ðð ð ð$ð ð ð$ '0¸Að ð ð ð ð2ð ð ð ðð ð ð ð 	€ðð ð ð ðð ð ð ,Ð ðð ð ð ðð ð ð8ð 8ð 8ð €ðð ð ð ð>  :Ð ð ð  ð  ð  ðN=ð =ð =ð =ð =ñ =ô =ð =ð@ð ð ð ð,ð ð ð ð ñ ô ð ð8 $°ð 3ð 3ð 3ð 3ðl0ð 0ð 0ð 0ðpS$ð S$ð S$ð S$ð S$ñ S$ô S$ð S$ðt3ð 3ð 3ð $Ð ðð ð ð2 (Ð ðð ð ð ð ð r!   