-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathProductQuantizer.js
89 lines (76 loc) · 1.95 KB
/
ProductQuantizer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
class ProductQuantizer {
constructor() {
this.nbits = 8;
this.ksub = 1 << this.nbits;
this.max_points_per_cluster = 256;
this.max_points = this.max_points_per_cluster * this.ksub;
this.seed = 1234;
this.niter = 25;
this.eps = 1e-7;
}
/**
*
* @param {FtzReader} ftzReader
*/
load(ftzReader) {
this.dim = ftzReader.readInt32();
this.nsubq = ftzReader.readInt32();
this.dsub = ftzReader.readInt32();
this.lastdsub = ftzReader.readInt32();
this.centroids = ftzReader.readFloat32TypedArray(this.dim * this.ksub);
}
/**
*
* @param {Number} m
* @param {Number} i
*/
get_centroids(m, i) {
if (m == this.nsubq - 1) {
return this.centroids.subarray(m * this.ksub * this.dsub + i * this.lastdsub);
}
return this.centroids.subarray((m * this.ksub + i) * this.dsub);
}
/**
*
* @param {Vector} x
* @param {*} codes
* @param {*} t
* @param {*} alpha
*/
mulcode(x, codes, t, alpha) {
let res = 0.0;
let d = this.dsub;
let code = codes + this.nsubq * t;
for (let m = 0; m < this.nsubq; m++) {
let c = this.get_centroids(m, code[m]);
if (m == this.nsubq - 1) {
d = this.lastdsub;
}
for(let n = 0; n < d; n++) {
res += x.data[m * this.dsub + n] * c[n];
}
}
return res * alpha;
}
/**
*
* @param {Vector} x
* @param {Array} codes
* @param {Number} t
* @param {Number} alpha
*/
addcode(x, codes, t, alpha) {
let d = this.dsub;
let offset = this.nsubq * t;
for (let m = 0; m < this.nsubq; m++) {
let c = this.get_centroids(m, codes[m + offset]);
if (m == this.nsubq - 1) {
d = this.lastdsub;
}
for(let n = 0; n < d; n++) {
x.data[m * this.dsub + n] += alpha * c[n];
}
}
}
}
module.exports = ProductQuantizer;