
    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8E;DAq
!Qw'''A
!Qy)))A		$	&	&Ba[[BFa[[BFBEBDJJLLLGGAxJJLLLa4K    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	2B		b		2	2	2BHEBXFB7777
(B89
-
-
-Cr8B<<SMM	 	 	 	 
'	'	'bdAAA r8B<<JSMM		 	 	
 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    
(1I
&
&
&Cx}}ch---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    
(1G
$
$
$C|8C==#(D1111x}}chd;;;Jr!   c                 x    t          j        | d          }t          t          |          |j        |           |S r8   )r	   r&   float_randnr   r:   r;   s      r   randnrG   h   s5    
(1I
&
&
&Csx...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{{QVXa[[1117DAq	!8	$	$	$B1a!hrll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    
(Aq6
+
+
+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	0B		b	0	0	0B
A8A;!Xa["(1+BF1XX 6 6,AXb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,    171:qwqz8A;;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
2Ccggii!m$$8GaKw///D8CHG,,,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39#7#7#7#7JD$cggii!m$$8GaKw///D dEN3''%%
  
 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     2q'1112q'333a 	,)++EE)++ETV$$	TV$$	


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w2r(""""TW}}}}
  QKK	 	 	 	 	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++%%%%FaKKAGqw..FaKKAGv---- )444 '222%fG<<<1AA"	
--Xf%%Xa[[)	
 	
 	
 	
 	
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     :####:LFAq8QF$*---D8QF$*---D%-I!!3IDD	1f  
 :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24N222 8XqM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zaT!!!!* 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	2B		b		2	2	2BHEBXFB7777
"a(((A
"a	***ARLL(2,,r2q(1++x{{	
 	
 	
 	
 
'	'	'RLL(2,,r2q(1++x{{	
 	
 	
 	

 	RLL(2,,r2vz1QKK!	
 	
 	
 a4Kr!   hcc                    | j         \  }}|j         \  }}||k    sJ t          j        ||fd          }t          j        ||fd          }	|dk    rt          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 HEBXFB7777
"a(((A
"a(((A$(**>!$$>!$$%.$$enR&8&8"q	
 	
 	
 	
 
DN2r 2 2BAqN1u~a00	
 	
 	
 	

 "!a4Kr!   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 )zd: 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gpuTN)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::DGG*,,DGLLNN 	' 	'DAqEzz99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DHHHr!   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     =VVDF#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RV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%    @@@5UGB&&@@@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DF{{{{7 444a11D)'-BQwwww*>+?+?+A+A4>RRRJJq$*g.... ???!)))w((((+Atvtw??DJJq(1++tx000/??	"**46155$::::eEJJLL&9&9:::844e44455DJJLL 
  
  
  
 
  
  
  $x}q00tx||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wwyy!''))##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          |          rt          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$    7DAq
Qg...A4 
K#D888zaT!!!!aA-..	Ha^7333q(4..(1++x{{I	G 	G 	G 	G X\a'	Ha^7333!Qhqkk8A;;	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$    7LAy|#Jg>>>IITXXZZ!^122M))))HaV7+++q(4..QKKHQKK	1 	1 	1 	1 TA!+M))))HaV7+++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                 $  $ '0A    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!   