/** * Construct the assigner using the given cluster data and * distance function. * * @param data the cluster data * @param comparison the distance function */ public ExactIntAssigner(int[][] data, IntFVComparator comparison) { nn = new IntNearestNeighboursExact(data, comparison); }
/** * 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(int[] data) { final byte[] quantised = new byte[assigners.length]; final int[] idx = { 0 }; final float[] dst = { 0 }; final int[][] qus = new int[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 int[] decompress(byte[] qdata) { final int[] data = new int[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 int[] assign(int[][] data) { int [] argmins = new int [data.length]; float [] mins = new float [data.length]; nn.searchNN(data, argmins, mins); return argmins; }
@Override public List<IntFloatPair> searchKNN(int[] 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 numDimensions() { return nn.numDimensions(); }
private List<IntFloatPair> search(int[] 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<int[], float[], IntFloatPair> defaultHardAssigner() { if (nn instanceof IntNearestNeighboursExact) return new ExactIntAssigner(this, ((IntNearestNeighboursExact)nn).distanceComparator()); return new KDTreeIntEuclideanAssigner(this); }
@Override public void assignDistance(int[][] data, int[] indices, float[] distances) { nn.searchNN(data, indices, distances); }
@Override public List<IntFloatPair> searchKNN(int[] 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); }
/** * Construct a {@link IntProductQuantiser} 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 IntProductQuantiser(IntNearestNeighboursExact[] assigners) { this.assigners = assigners; for (final IntNearestNeighboursExact nn : assigners) ndims += nn.numDimensions(); }
private List<IntFloatPair> search(int[] 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 IntNearestNeighboursExact create(int[][] data) { return new IntNearestNeighboursExact(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(int[] data) { final byte[] quantised = new byte[assigners.length]; final int[] idx = { 0 }; final float[] dst = { 0 }; final int[][] qus = new int[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 int[] decompress(byte[] qdata) { final int[] data = new int[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 assignDistance(int[] data) { int [] index = new int [1]; float [] distance = new float [1]; nn.searchNN(new int[][] { data }, index, distance); return new IntFloatPair(index[0], distance[0]); }
@Override public IntFloatPair searchNN(final int[] 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); }
/** * Construct a {@link IntProductQuantiser} 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 IntProductQuantiser(IntNearestNeighboursExact[] assigners) { this.assigners = assigners; for (final IntNearestNeighboursExact nn : assigners) ndims += nn.numDimensions(); }
@Override public IntNearestNeighboursExact create(int[][] data) { return new IntNearestNeighboursExact(data, distance); } }