11 #include "IndexFlat.h"
17 #include "FaissAssert.h"
19 #include "AuxIndexStructures.h"
24 IndexFlat::IndexFlat (idx_t d,
MetricType metric):
32 xb.insert(
xb.end(), x, x + n *
d);
44 float *distances,
idx_t *labels)
const
50 size_t(n), size_t(k), labels, distances};
54 size_t(n), size_t(k), labels, distances};
63 case METRIC_INNER_PRODUCT:
79 const idx_t *labels)
const
82 case METRIC_INNER_PRODUCT:
83 fvec_inner_products_by_idx (
85 x,
xb.data(), labels,
d, n, k);
90 x,
xb.data(), labels,
d, n, k);
100 if (sel.is_member (i)) {
104 memmove (&
xb[
d * j], &
xb[
d * i],
sizeof(
xb[0]) *
d);
109 long nremove = ntotal - j;
112 xb.resize (ntotal *
d);
121 memcpy (recons, &(
xb[key *
d]),
sizeof(*recons) * d);
128 IndexFlatL2BaseShift::IndexFlatL2BaseShift (idx_t d,
size_t nshift,
const float *shift):
131 memcpy (this->shift.data(), shift,
sizeof(float) * nshift);
141 FAISS_THROW_IF_NOT (shift.size() ==
ntotal);
144 size_t(n), size_t(k), labels, distances};
154 IndexRefineFlat::IndexRefineFlat (
Index *base_index):
155 Index (base_index->d, base_index->metric_type),
156 refine_index (base_index->d, base_index->metric_type),
157 base_index (base_index), own_fields (false),
161 FAISS_THROW_IF_NOT_MSG (base_index->
ntotal == 0,
162 "base_index should be empty in the beginning");
165 IndexRefineFlat::IndexRefineFlat () {
196 static void reorder_2_heaps (
198 idx_t k, idx_t *labels,
float *distances,
199 idx_t k_base,
const idx_t *base_labels,
const float *base_distances)
201 #pragma omp parallel for
202 for (idx_t i = 0; i < n; i++) {
203 idx_t *idxo = labels + i * k;
204 float *diso = distances + i * k;
205 const idx_t *idxi = base_labels + i * k_base;
206 const float *disi = base_distances + i * k_base;
208 heap_heapify<C> (k, diso, idxo, disi, idxi, k);
210 heap_addn<C> (k, diso, idxo, disi + k, idxi + k, k_base - k);
212 heap_reorder<C> (k, diso, idxo);
221 idx_t n,
const float *x, idx_t k,
222 float *distances, idx_t *labels)
const
226 idx_t * base_labels = labels;
227 float * base_distances = distances;
233 base_labels =
new idx_t [n * k_base];
234 del1.set (base_labels);
235 base_distances =
new float [n * k_base];
236 del2.set (base_distances);
241 for (
int i = 0; i < n * k_base; i++)
242 assert (base_labels[i] >= -1 &&
247 n, x, k_base, base_distances, base_labels);
253 n, k, labels, distances,
254 k_base, base_labels, base_distances);
259 n, k, labels, distances,
260 k_base, base_labels, base_distances);
267 IndexRefineFlat::~IndexRefineFlat ()
277 IndexFlat1D::IndexFlat1D (
bool continuous_update):
279 continuous_update (continuous_update)
291 fvec_argsort_parallel (
ntotal,
xb.data(), (
size_t*)
perm.data());
315 FAISS_THROW_IF_NOT_MSG (
perm.size() ==
ntotal,
316 "Call update_permutation before search");
318 #pragma omp parallel for
319 for (idx_t i = 0; i < n; i++) {
322 float *D = distances + i * k;
323 idx_t *I = labels + i * k;
326 idx_t i0 = 0, i1 =
ntotal;
334 if (
xb[
perm[i1 - 1]] <= q) {
339 while (i0 + 1 < i1) {
340 idx_t imed = (i0 + i1) / 2;
341 if (
xb[
perm[imed]] <= q) i0 = imed;
349 float xleft =
xb[
perm[i0]];
350 float xright =
xb[perm[i1]];
352 if (q - xleft < xright - q) {
356 if (i0 < 0) {
goto finish_right; }
361 if (i1 >=
ntotal) {
goto finish_left; }
void knn_L2sqr_base_shift(const float *x, const float *y, size_t d, size_t nx, size_t ny, float_maxheap_array_t *res, const float *base_shift)
void search(idx_t n, const float *x, idx_t k, float *distances, idx_t *labels) const override
void reset() override
removes all elements from the database.
virtual void reset()=0
removes all elements from the database.
bool continuous_update
is the permutation updated continuously?
void search(idx_t n, const float *x, idx_t k, float *distances, idx_t *labels) const override
void reset() override
removes all elements from the database.
void update_permutation()
virtual void train(idx_t n, const float *x)
void reconstruct(idx_t key, float *recons) const override
void add(idx_t n, const float *x) override
long remove_ids(const IDSelector &sel) override
void search(idx_t n, const float *x, idx_t k, float *distances, idx_t *labels) const override
Index * base_index
faster index to pre-select the vectors that should be filtered
IndexFlat refine_index
storage for full vectors
bool own_fields
should the base index be deallocated?
void range_search(idx_t n, const float *x, float radius, RangeSearchResult *result) const override
void train(idx_t n, const float *x) override
virtual void add(idx_t n, const float *x)=0
long idx_t
all indices are this type
void range_search_inner_product(const float *x, const float *y, size_t d, size_t nx, size_t ny, float radius, RangeSearchResult *res)
same as range_search_L2sqr for the inner product similarity
idx_t ntotal
total nb of indexed vectors
void knn_inner_product(const float *x, const float *y, size_t d, size_t nx, size_t ny, float_minheap_array_t *res)
void add(idx_t n, const float *x) override
void search(idx_t n, const float *x, idx_t k, float *distances, idx_t *labels) const override
Warn: the distances returned are L1 not L2.
virtual void search(idx_t n, const float *x, idx_t k, float *distances, idx_t *labels) const =0
void range_search_L2sqr(const float *x, const float *y, size_t d, size_t nx, size_t ny, float radius, RangeSearchResult *res)
void compute_distance_subset(idx_t n, const float *x, idx_t k, float *distances, const idx_t *labels) const
MetricType metric_type
type of metric this index uses for search
void knn_L2sqr(const float *x, const float *y, size_t d, size_t nx, size_t ny, float_maxheap_array_t *res)
bool is_trained
set if the Index does not require training, or if training is done already
std::vector< float > xb
database vectors, size ntotal * d
void reset() override
removes all elements from the database.
std::vector< idx_t > perm
sorted database indices
MetricType
Some algorithms support both an inner product version and a L2 search version.
void add(idx_t n, const float *x) override