/** * Construct a {@link DoubleProductQuantiser} with the given * nearest-neighbour assigners. The number of dimensions of the assigners * determines how long each sub-vector is. There is a one-to-one mapping * between in the order of assigners and sub-vectors. * * @param assigners * the nearest-neighbour assigners. */ public DoubleProductQuantiser(DoubleNearestNeighboursExact[] assigners) { this.assigners = assigners; for (final DoubleNearestNeighboursExact nn : assigners) ndims += nn.numDimensions(); }
/** * Construct a {@link DoubleProductQuantiser} with the given * nearest-neighbour assigners. The number of dimensions of the assigners * determines how long each sub-vector is. There is a one-to-one mapping * between in the order of assigners and sub-vectors. * * @param assigners * the nearest-neighbour assigners. */ public DoubleProductQuantiser(DoubleNearestNeighboursExact[] assigners) { this.assigners = assigners; for (final DoubleNearestNeighboursExact nn : assigners) ndims += nn.numDimensions(); }
@Override public int numDimensions() { return nn.numDimensions(); }
/** * Decompress the quantised data by replacing each encoded index with the actual centroid subvector. * * @param qdata the quantised data * * @return the (approximate) decompressed feature */ public double[] decompress(byte[] qdata) { final double[] data = new double[ndims]; for (int i = 0, from = 0; i < assigners.length; i++) { final int len = assigners[i].numDimensions(); int index = (int)qdata[i] + 128; System.arraycopy(this.assigners[i].getPoints()[index], 0, data, from, len); from += len; } return data; } }
/** * Decompress the quantised data by replacing each encoded index with the actual centroid subvector. * * @param qdata the quantised data * * @return the (approximate) decompressed feature */ public double[] decompress(byte[] qdata) { final double[] data = new double[ndims]; for (int i = 0, from = 0; i < assigners.length; i++) { final int len = assigners[i].numDimensions(); int index = (int)qdata[i] + 128; System.arraycopy(this.assigners[i].getPoints()[index], 0, data, from, len); from += len; } return data; } }
/** * Quantise the given data using this Product Quantiser. The output is an * array of bytes corresponding to the index of the matching centroid for * each sub-vector (index numbers are offset by -128 so that 256 centroids * indexes can fit in a single byte). * * @param data * the data to quantise * @return the quantised data. */ public byte[] quantise(double[] data) { final byte[] quantised = new byte[assigners.length]; final int[] idx = { 0 }; final double[] dst = { 0 }; final double[][] qus = new double[1][0]; for (int i = 0, from = 0; i < assigners.length; i++) { final int to = assigners[i].numDimensions(); qus[0] = Arrays.copyOfRange(data, from, from + to); assigners[i].searchNN(qus, idx, dst); quantised[i] = (byte) (idx[0] - 128); from += to; } return quantised; }
/** * Quantise the given data using this Product Quantiser. The output is an * array of bytes corresponding to the index of the matching centroid for * each sub-vector (index numbers are offset by -128 so that 256 centroids * indexes can fit in a single byte). * * @param data * the data to quantise * @return the quantised data. */ public byte[] quantise(double[] data) { final byte[] quantised = new byte[assigners.length]; final int[] idx = { 0 }; final double[] dst = { 0 }; final double[][] qus = new double[1][0]; for (int i = 0, from = 0; i < assigners.length; i++) { final int to = assigners[i].numDimensions(); qus[0] = Arrays.copyOfRange(data, from, from + to); assigners[i].searchNN(qus, idx, dst); quantised[i] = (byte) (idx[0] - 128); from += to; } return quantised; }