Faiss

- Main Page
- Namespaces
- Classes
- Files

- File List

All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends
/data/users/hoss/faiss/VectorTransform.h
1 /**
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 // -*- c++ -*-
9
10 #ifndef FAISS_VECTOR_TRANSFORM_H
11 #define FAISS_VECTOR_TRANSFORM_H
12
13 /** Defines a few objects that apply transformations to a set of
14 * vectors Often these are pre-processing steps.
15 */
16
17 #include <vector>
18
19 #include "Index.h"
20
21
22 namespace faiss {
23
24
25 /** Any transformation applied on a set of vectors */
26 struct VectorTransform {
27
28 typedef Index::idx_t idx_t;
29
30 int d_in; ///! input dimension
31 int d_out; ///! output dimension
32
33 explicit VectorTransform (int d_in = 0, int d_out = 0):
34 d_in(d_in), d_out(d_out), is_trained(true)
35 {}
36
37
38 /// set if the VectorTransform does not require training, or if
39 /// training is done already
40 bool is_trained;
41
42
43 /** Perform training on a representative set of vectors. Does
44 * nothing by default.
45 *
46 * @param n nb of training vectors
47 * @param x training vecors, size n * d
48 */
49 virtual void train (idx_t n, const float *x);
50
51 /** apply the random roation, return new allocated matrix
52 * @param x size n * d_in
53 * @return size n * d_out
54 */
55 float *apply (idx_t n, const float * x) const;
56
57 /// same as apply, but result is pre-allocated
58 virtual void apply_noalloc (idx_t n, const float * x,
59 float *xt) const = 0;
60
61 /// reverse transformation. May not be implemented or may return
62 /// approximate result
63 virtual void reverse_transform (idx_t n, const float * xt,
64 float *x) const;
65
66 virtual ~VectorTransform () {}
67
68 };
69
70
71
72 /** Generic linear transformation, with bias term applied on output
73 * y = A * x + b
74 */
75 struct LinearTransform: VectorTransform {
76
77 bool have_bias; ///! whether to use the bias term
78
79 /// check if matrix A is orthonormal (enables reverse_transform)
80 bool is_orthonormal;
81
82 /// Transformation matrix, size d_out * d_in
83 std::vector<float> A;
84
85 /// bias vector, size d_out
86 std::vector<float> b;
87
88 /// both d_in > d_out and d_out < d_in are supported
89 explicit LinearTransform (int d_in = 0, int d_out = 0,
90 bool have_bias = false);
91
92 /// same as apply, but result is pre-allocated
93 void apply_noalloc(idx_t n, const float* x, float* xt) const override;
94
95 /// compute x = A^T * (x - b)
96 /// is reverse transform if A has orthonormal lines
97 void transform_transpose (idx_t n, const float * y,
98 float *x) const;
99
100 /// works only if is_orthonormal
101 void reverse_transform (idx_t n, const float * xt,
102 float *x) const override;
103
104 /// compute A^T * A to set the is_orthonormal flag
105 void set_is_orthonormal ();
106
107 bool verbose;
108
109 ~LinearTransform() override {}
110 };
111
112
113
114 /// Randomly rotate a set of vectors
115 struct RandomRotationMatrix: LinearTransform {
116
117 /// both d_in > d_out and d_out < d_in are supported
118 RandomRotationMatrix (int d_in, int d_out):
119 LinearTransform(d_in, d_out, false) {}
120
121 /// must be called before the transform is used
122 void init(int seed);
123
124 // intializes with an arbitrary seed
125 void train(Index::idx_t n, const float* x) override;
126
127 RandomRotationMatrix () {}
128 };
129
130
131 /** Applies a principal component analysis on a set of vectors,
132 * with optionally whitening and random rotation. */
133 struct PCAMatrix: LinearTransform {
134
135 /** after transformation the components are multiplied by
136 * eigenvalues^eigen_power
137 *
138 * =0: no whitening
139 * =-0.5: full whitening
140 */
141 float eigen_power;
142
143 /// random rotation after PCA
144 bool random_rotation;
145
146 /// ratio between # training vectors and dimension
147 size_t max_points_per_d;
148
149 /// try to distribute output eigenvectors in this many bins
150 int balanced_bins;
151
152 /// Mean, size d_in
153 std::vector<float> mean;
154
155 /// eigenvalues of covariance matrix (= squared singular values)
156 std::vector<float> eigenvalues;
157
158 /// PCA matrix, size d_in * d_in
159 std::vector<float> PCAMat;
160
161 // the final matrix is computed after random rotation and/or whitening
162 explicit PCAMatrix (int d_in = 0, int d_out = 0,
163 float eigen_power = 0, bool random_rotation = false);
164
165 /// train on n vectors. If n < d_in then the eigenvector matrix
166 /// will be completed with 0s
167 void train(Index::idx_t n, const float* x) override;
168
169 /// copy pre-trained PCA matrix
170 void copy_from (const PCAMatrix & other);
171
172 /// called after mean, PCAMat and eigenvalues are computed
173 void prepare_Ab();
174
175 };
176
177
178 struct ProductQuantizer;
179
180 /** Applies a rotation to align the dimensions with a PQ to minimize
181 * the reconstruction error. Can be used before an IndexPQ or an
182 * IndexIVFPQ. The method is the non-parametric version described in:
183 *
184 * "Optimized Product Quantization for Approximate Nearest Neighbor Search"
185 * Tiezheng Ge, Kaiming He, Qifa Ke, Jian Sun, CVPR'13
186 *
187 */
188 struct OPQMatrix: LinearTransform {
189
190 int M; ///< nb of subquantizers
191 int niter; ///< Number of outer training iterations
192 int niter_pq; ///< Number of training iterations for the PQ
193 int niter_pq_0; ///< same, for the first outer iteration
194
195 /// if there are too many training points, resample
196 size_t max_train_points;
197 bool verbose;
198
199 /// if non-NULL, use this product quantizer for training
200 /// should be constructed with (d_out, M, _)
201 ProductQuantizer * pq;
202
203 /// if d2 != -1, output vectors of this dimension
204 explicit OPQMatrix (int d = 0, int M = 1, int d2 = -1);
205
206 void train(Index::idx_t n, const float* x) override;
207 };
208
209
210 /** remap dimensions for intput vectors, possibly inserting 0s
211 * strictly speaking this is also a linear transform but we don't want
212 * to compute it with matrix multiplies */
213 struct RemapDimensionsTransform: VectorTransform {
214
215 /// map from output dimension to input, size d_out
216 /// -1 -> set output to 0
217 std::vector<int> map;
218
219 RemapDimensionsTransform (int d_in, int d_out, const int *map);
220
221 /// remap input to output, skipping or inserting dimensions as needed
222 /// if uniform: distribute dimensions uniformly
223 /// otherwise just take the d_out first ones.
224 RemapDimensionsTransform (int d_in, int d_out, bool uniform = true);
225
226 void apply_noalloc(idx_t n, const float* x, float* xt) const override;
227
228 /// reverse transform correct only when the mapping is a permuation
229 void reverse_transform(idx_t n, const float* xt, float* x) const override;
230
231 RemapDimensionsTransform () {}
232 };
233
234
235 /** per-vector normalization */
236 struct NormalizationTransform: VectorTransform {
237 float norm;
238
239 explicit NormalizationTransform (int d, float norm = 2.0);
240 NormalizationTransform ();
241
242 void apply_noalloc(idx_t n, const float* x, float* xt) const override;
243
244 /// Identity transform since norm is not revertible
245 void reverse_transform(idx_t n, const float* xt, float* x) const override;
246 };
247
248 /** Subtract the mean of each component from the vectors. */
249 struct CenteringTransform: VectorTransform {
250
251 /// Mean, size d_in = d_out
252 std::vector<float> mean;
253
254 explicit CenteringTransform (int d = 0);
255
256 /// train on n vectors.
257 void train(Index::idx_t n, const float* x) override;
258
259 /// subtract the mean
260 void apply_noalloc(idx_t n, const float* x, float* xt) const override;
261
262 /// add the mean
263 void reverse_transform (idx_t n, const float * xt,
264 float *x) const override;
265
266 };
267
268
269 /** Index that applies a LinearTransform transform on vectors before
270 * handing them over to a sub-index */
271 struct IndexPreTransform: Index {
272
273 std::vector<VectorTransform *> chain; ///! chain of tranforms
274 Index * index; ///! the sub-index
275
276 bool own_fields; ///! whether pointers are deleted in destructor
277
278 explicit IndexPreTransform (Index *index);
279
280 IndexPreTransform ();
281
282 /// ltrans is the last transform before the index
283 IndexPreTransform (VectorTransform * ltrans, Index * index);
284
285 void prepend_transform (VectorTransform * ltrans);
286
287 void train(idx_t n, const float* x) override;
288
289 void add(idx_t n, const float* x) override;
290
291 void add_with_ids(idx_t n, const float* x, const long* xids) override;
292
293 void reset() override;
294
295 /** removes IDs from the index. Not supported by all indexes.
296 */
297 long remove_ids(const IDSelector& sel) override;
298
299 void search(
300 idx_t n,
301 const float* x,
302 idx_t k,
303 float* distances,
304 idx_t* labels) const override;
305
306
307 /* range search, no attempt is done to change the radius */
308 void range_search (idx_t n, const float* x, float radius,
309 RangeSearchResult* result) const override;
310
311
312 void reconstruct (idx_t key, float * recons) const override;
313
314 void reconstruct_n (idx_t i0, idx_t ni, float *recons)
315 const override;
316
317 void search_and_reconstruct (idx_t n, const float *x, idx_t k,
318 float *distances, idx_t *labels,
319 float *recons) const override;
320
321 /// apply the transforms in the chain. The returned float * may be
322 /// equal to x, otherwise it should be deallocated.
323 const float * apply_chain (idx_t n, const float *x) const;
324
325 /// Reverse the transforms in the chain. May not be implemented for
326 /// all transforms in the chain or may return approximate results.
327 void reverse_chain (idx_t n, const float* xt, float* x) const;
328
329 ~IndexPreTransform() override;
330 };
331
332
333 } // namespace faiss
334
335
336 #endif
faiss::LinearTransform::transform_transpose
void transform_transpose(idx_t n, const float *y, float *x) const
Definition: VectorTransform.cpp:135
faiss::IndexPreTransform::index
Index * index
! chain of tranforms
Definition: VectorTransform.h:274
faiss::RandomRotationMatrix
Randomly rotate a set of vectors.
Definition: VectorTransform.h:115
faiss::OPQMatrix::niter
int niter
Number of outer training iterations.
Definition: VectorTransform.h:191
faiss::CenteringTransform::train
void train(Index::idx_t n, const float *x) override
train on n vectors.
Definition: VectorTransform.cpp:812
faiss::RandomRotationMatrix::RandomRotationMatrix
RandomRotationMatrix(int d_in, int d_out)
both d_in &gt; d_out and d_out &lt; d_in are supported
Definition: VectorTransform.h:118
faiss::RandomRotationMatrix::init
void init(int seed)
must be called before the transform is used
Definition: VectorTransform.cpp:215
faiss::IndexPreTransform::range_search
void range_search(idx_t n, const float *x, float radius, RangeSearchResult *result) const override
Definition: VectorTransform.cpp:1024
faiss::IndexPreTransform::reset
void reset() override
removes all elements from the database.
Definition: VectorTransform.cpp:1035
faiss::OPQMatrix::niter_pq
int niter_pq
Number of training iterations for the PQ.
Definition: VectorTransform.h:192
faiss::LinearTransform::A
std::vector< float > A
Transformation matrix, size d_out * d_in.
Definition: VectorTransform.h:83
faiss::CenteringTransform::mean
std::vector< float > mean
Mean, size d_in = d_out.
Definition: VectorTransform.h:252
faiss::PCAMatrix::eigen_power
float eigen_power
Definition: VectorTransform.h:141
faiss::IDSelector
Definition: AuxIndexStructures.h:54
faiss::LinearTransform::LinearTransform
LinearTransform(int d_in=0, int d_out=0, bool have_bias=false)
both d_in &gt; d_out and d_out &lt; d_in are supported
Definition: VectorTransform.cpp:98
faiss::PCAMatrix
Definition: VectorTransform.h:133
faiss::VectorTransform::VectorTransform
VectorTransform(int d_in=0, int d_out=0)
! output dimension
Definition: VectorTransform.h:33
faiss::LinearTransform::set_is_orthonormal
void set_is_orthonormal()
compute A^T * A to set the is_orthonormal flag
Definition: VectorTransform.cpp:160
faiss::OPQMatrix::pq
ProductQuantizer * pq
Definition: VectorTransform.h:201
faiss::OPQMatrix
Definition: VectorTransform.h:188
faiss::PCAMatrix::train
void train(Index::idx_t n, const float *x) override
Definition: VectorTransform.cpp:325
faiss::IndexPreTransform
Definition: VectorTransform.h:271
faiss::PCAMatrix::mean
std::vector< float > mean
Mean, size d_in.
Definition: VectorTransform.h:153
faiss::RemapDimensionsTransform::map
std::vector< int > map
Definition: VectorTransform.h:217
faiss::IndexPreTransform::apply_chain
const float * apply_chain(idx_t n, const float *x) const
Definition: VectorTransform.cpp:964
faiss::PCAMatrix::PCAMat
std::vector< float > PCAMat
PCA matrix, size d_in * d_in.
Definition: VectorTransform.h:159
faiss::IndexPreTransform::train
void train(idx_t n, const float *x) override
Definition: VectorTransform.cpp:906
faiss::Index::idx_t
long idx_t
all indices are this type
Definition: Index.h:62
faiss::LinearTransform::b
std::vector< float > b
bias vector, size d_out
Definition: VectorTransform.h:86
faiss::LinearTransform::reverse_transform
void reverse_transform(idx_t n, const float *xt, float *x) const override
works only if is_orthonormal
Definition: VectorTransform.cpp:199
faiss::NormalizationTransform::reverse_transform
void reverse_transform(idx_t n, const float *xt, float *x) const override
Identity transform since norm is not revertible.
Definition: VectorTransform.cpp:796
faiss::LinearTransform
Definition: VectorTransform.h:75
faiss::OPQMatrix::train
void train(Index::idx_t n, const float *x) override
Definition: VectorTransform.cpp:598
faiss::PCAMatrix::balanced_bins
int balanced_bins
try to distribute output eigenvectors in this many bins
Definition: VectorTransform.h:150
faiss::VectorTransform::is_trained
bool is_trained
Definition: VectorTransform.h:40
faiss::RandomRotationMatrix::train
void train(Index::idx_t n, const float *x) override
Definition: VectorTransform.cpp:242
faiss::IndexPreTransform::reconstruct_n
void reconstruct_n(idx_t i0, idx_t ni, float *recons) const override
Definition: VectorTransform.cpp:1059
faiss::CenteringTransform::reverse_transform
void reverse_transform(idx_t n, const float *xt, float *x) const override
add the mean
Definition: VectorTransform.cpp:840
faiss::NormalizationTransform::apply_noalloc
void apply_noalloc(idx_t n, const float *x, float *xt) const override
same as apply, but result is pre-allocated
Definition: VectorTransform.cpp:786
faiss::CenteringTransform
Definition: VectorTransform.h:249
faiss::VectorTransform
Definition: VectorTransform.h:26
faiss::IndexPreTransform::own_fields
bool own_fields
! the sub-index
Definition: VectorTransform.h:276
faiss::OPQMatrix::niter_pq_0
int niter_pq_0
same, for the first outer iteration
Definition: VectorTransform.h:193
faiss::RangeSearchResult
Definition: AuxIndexStructures.h:31
faiss::VectorTransform::train
virtual void train(idx_t n, const float *x)
Definition: VectorTransform.cpp:78
faiss::VectorTransform::reverse_transform
virtual void reverse_transform(idx_t n, const float *xt, float *x) const
Definition: VectorTransform.cpp:83
faiss::IndexPreTransform::search_and_reconstruct
void search_and_reconstruct(idx_t n, const float *x, idx_t k, float *distances, idx_t *labels, float *recons) const override
Definition: VectorTransform.cpp:1071
faiss::RemapDimensionsTransform::reverse_transform
void reverse_transform(idx_t n, const float *xt, float *x) const override
reverse transform correct only when the mapping is a permuation
Definition: VectorTransform.cpp:1139
faiss::RemapDimensionsTransform
Definition: VectorTransform.h:213
faiss::OPQMatrix::max_train_points
size_t max_train_points
if there are too many training points, resample
Definition: VectorTransform.h:196
faiss::PCAMatrix::copy_from
void copy_from(const PCAMatrix &other)
copy pre-trained PCA matrix
Definition: VectorTransform.cpp:467
faiss::VectorTransform::d_out
int d_out
! input dimension
Definition: VectorTransform.h:31
faiss::OPQMatrix::OPQMatrix
OPQMatrix(int d=0, int M=1, int d2=-1)
if d2 != -1, output vectors of this dimension
Definition: VectorTransform.cpp:583
faiss::Index
Definition: Index.h:61
faiss::PCAMatrix::prepare_Ab
void prepare_Ab()
called after mean, PCAMat and eigenvalues are computed
Definition: VectorTransform.cpp:477
faiss::IndexPreTransform::add
void add(idx_t n, const float *x) override
Definition: VectorTransform.cpp:993
faiss::RemapDimensionsTransform::apply_noalloc
void apply_noalloc(idx_t n, const float *x, float *xt) const override
same as apply, but result is pre-allocated
Definition: VectorTransform.cpp:1127
faiss::ProductQuantizer
Definition: ProductQuantizer.h:23
faiss::IndexPreTransform::reverse_chain
void reverse_chain(idx_t n, const float *xt, float *x) const
Definition: VectorTransform.cpp:979
faiss::LinearTransform::is_orthonormal
bool is_orthonormal
! whether to use the bias term
Definition: VectorTransform.h:80
faiss::PCAMatrix::eigenvalues
std::vector< float > eigenvalues
eigenvalues of covariance matrix (= squared singular values)
Definition: VectorTransform.h:156
faiss::IndexPreTransform::search
void search(idx_t n, const float *x, idx_t k, float *distances, idx_t *labels) const override
Definition: VectorTransform.cpp:1015
faiss::NormalizationTransform
Definition: VectorTransform.h:236
faiss::IndexPreTransform::add_with_ids
void add_with_ids(idx_t n, const float *x, const long *xids) override
Definition: VectorTransform.cpp:1002
faiss::PCAMatrix::random_rotation
bool random_rotation
random rotation after PCA
Definition: VectorTransform.h:144
faiss::PCAMatrix::max_points_per_d
size_t max_points_per_d
ratio between # training vectors and dimension
Definition: VectorTransform.h:147
faiss::VectorTransform::apply
float * apply(idx_t n, const float *x) const
Definition: VectorTransform.cpp:70
faiss::IndexPreTransform::remove_ids
long remove_ids(const IDSelector &sel) override
Definition: VectorTransform.cpp:1040
faiss::VectorTransform::apply_noalloc
virtual void apply_noalloc(idx_t n, const float *x, float *xt) const =0
same as apply, but result is pre-allocated
faiss::IndexPreTransform::reconstruct
void reconstruct(idx_t key, float *recons) const override
Definition: VectorTransform.cpp:1047
faiss::CenteringTransform::apply_noalloc
void apply_noalloc(idx_t n, const float *x, float *xt) const override
subtract the mean
Definition: VectorTransform.cpp:829
faiss::OPQMatrix::M
int M
nb of subquantizers
Definition: VectorTransform.h:190
faiss::LinearTransform::apply_noalloc
void apply_noalloc(idx_t n, const float *x, float *xt) const override
same as apply, but result is pre-allocated
Definition: VectorTransform.cpp:106