Faiss
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends
test_ivfpq_codec.cpp
1 /**
2  * Copyright (c) 2015-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD+Patents license found in the
6  * LICENSE file in the root directory of this source tree.
7  */
8 
9 #include <cstdio>
10 #include <cstdlib>
11 
12 #include <gtest/gtest.h>
13 
14 #include <faiss/IndexIVFPQ.h>
15 #include <faiss/IndexFlat.h>
16 #include <faiss/utils.h>
17 
18 
19 namespace {
20 
21 // dimension of the vectors to index
22 int d = 64;
23 
24 // size of the database we plan to index
25 size_t nb = 8000;
26 
27 
28 double eval_codec_error (long ncentroids, long m, const std::vector<float> &v)
29 {
30  faiss::IndexFlatL2 coarse_quantizer (d);
31  faiss::IndexIVFPQ index (&coarse_quantizer, d,
32  ncentroids, m, 8);
33  index.pq.cp.niter = 10; // speed up train
34  index.train (nb, v.data());
35 
36  // encode and decode to compute reconstruction error
37 
38  std::vector<long> keys (nb);
39  std::vector<uint8_t> codes (nb * m);
40  index.encode_multiple (nb, keys.data(), v.data(), codes.data(), true);
41 
42  std::vector<float> v2 (nb * d);
43  index.decode_multiple (nb, keys.data(), codes.data(), v2.data());
44 
45  return faiss::fvec_L2sqr (v.data(), v2.data(), nb * d);
46 }
47 
48 } // namespace
49 
50 
51 TEST(IVFPQ, codec) {
52 
53  std::vector <float> database (nb * d);
54  for (size_t i = 0; i < nb * d; i++) {
55  database[i] = drand48();
56  }
57 
58  double err0 = eval_codec_error(16, 8, database);
59 
60  // should be more accurate as there are more coarse centroids
61  double err1 = eval_codec_error(128, 8, database);
62  EXPECT_GT(err0, err1);
63 
64  // should be more accurate as there are more PQ codes
65  double err2 = eval_codec_error(16, 16, database);
66  EXPECT_GT(err0, err2);
67 }
float fvec_L2sqr(const float *x, const float *y, size_t d)
Squared L2 distance between two vectors.
Definition: utils_simd.cpp:502