@Override public ShortNearestNeighboursExact create(short[][] data) { return new ShortNearestNeighboursExact(data, distance); } }
/** * 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(short[] data) { final byte[] quantised = new byte[assigners.length]; final int[] idx = { 0 }; final float[] dst = { 0 }; final short[][] qus = new short[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; }
/** * 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 short[] decompress(byte[] qdata) { final short[] data = new short[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; } }
@Override public List<IntFloatPair> searchKNN(short[] query, int K) { // Fix for when the user asks for too many points. K = Math.min(K, pnts.length); final BoundedPriorityQueue<IntFloatPair> queue = new BoundedPriorityQueue<IntFloatPair>(K, IntFloatPair.SECOND_ITEM_ASCENDING_COMPARATOR); //prepare working data List<IntFloatPair> list = new ArrayList<IntFloatPair>(K + 1); for (int i = 0; i < K + 1; i++) { list.add(new IntFloatPair()); } // search return search(query, queue, list); }
@Override public int[] assign(short[][] data) { int [] argmins = new int [data.length]; float [] mins = new float [data.length]; nn.searchNN(data, argmins, mins); return argmins; }
@Override public int numDimensions() { return nn.numDimensions(); }
private List<IntFloatPair> search(short[] query, BoundedPriorityQueue<IntFloatPair> queue, List<IntFloatPair> results) { IntFloatPair wp = null; // reset all values in the queue to MAX, -1 for (final IntFloatPair p : results) { p.second = Float.MAX_VALUE; p.first = -1; wp = queue.offerItem(p); } // perform the search for (int i = 0; i < this.pnts.length; i++) { wp.second = distanceFunc(distance, query, pnts[i]); wp.first = i; wp = queue.offerItem(wp); } return queue.toOrderedListDestructive(); }
@Override public int size() { return nn.size(); }
@Override public HardAssigner<short[], float[], IntFloatPair> defaultHardAssigner() { if (nn instanceof ShortNearestNeighboursExact) return new ExactShortAssigner(this, ((ShortNearestNeighboursExact)nn).distanceComparator()); return new KDTreeShortEuclideanAssigner(this); }
@Override public List<IntFloatPair> searchKNN(short[] query, int K) { // Fix for when the user asks for too many points. K = Math.min(K, pnts.length); final BoundedPriorityQueue<IntFloatPair> queue = new BoundedPriorityQueue<IntFloatPair>(K, IntFloatPair.SECOND_ITEM_ASCENDING_COMPARATOR); //prepare working data List<IntFloatPair> list = new ArrayList<IntFloatPair>(K + 1); for (int i = 0; i < K + 1; i++) { list.add(new IntFloatPair()); } // search return search(query, queue, list); }
@Override public void assignDistance(short[][] data, int[] indices, float[] distances) { nn.searchNN(data, indices, distances); }
/** * Construct a {@link ShortProductQuantiser} 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 ShortProductQuantiser(ShortNearestNeighboursExact[] assigners) { this.assigners = assigners; for (final ShortNearestNeighboursExact nn : assigners) ndims += nn.numDimensions(); }
private List<IntFloatPair> search(short[] query, BoundedPriorityQueue<IntFloatPair> queue, List<IntFloatPair> results) { IntFloatPair wp = null; // reset all values in the queue to MAX, -1 for (final IntFloatPair p : results) { p.second = Float.MAX_VALUE; p.first = -1; wp = queue.offerItem(p); } // perform the search for (int i = 0; i < this.pnts.length; i++) { wp.second = distanceFunc(distance, query, pnts[i]); wp.first = i; wp = queue.offerItem(wp); } return queue.toOrderedListDestructive(); }
@Override public ShortNearestNeighboursExact create(short[][] data) { return new ShortNearestNeighboursExact(data, distance); } }
/** * 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(short[] data) { final byte[] quantised = new byte[assigners.length]; final int[] idx = { 0 }; final float[] dst = { 0 }; final short[][] qus = new short[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; }
/** * 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 short[] decompress(byte[] qdata) { final short[] data = new short[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; } }
@Override public IntFloatPair searchNN(final short[] query) { final BoundedPriorityQueue<IntFloatPair> queue = new BoundedPriorityQueue<IntFloatPair>(1, IntFloatPair.SECOND_ITEM_ASCENDING_COMPARATOR); //prepare working data List<IntFloatPair> list = new ArrayList<IntFloatPair>(2); list.add(new IntFloatPair()); list.add(new IntFloatPair()); return search(query, queue, list).get(0); }
@Override public IntFloatPair assignDistance(short[] data) { int [] index = new int [1]; float [] distance = new float [1]; nn.searchNN(new short[][] { data }, index, distance); return new IntFloatPair(index[0], distance[0]); }
/** * Construct a {@link ShortProductQuantiser} 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 ShortProductQuantiser(ShortNearestNeighboursExact[] assigners) { this.assigners = assigners; for (final ShortNearestNeighboursExact nn : assigners) ndims += nn.numDimensions(); }
/** * Construct the assigner using the given cluster data and * distance function. * * @param data the cluster data * @param comparison the distance function */ public ExactShortAssigner(short[][] data, ShortFVComparator comparison) { nn = new ShortNearestNeighboursExact(data, comparison); }