org.openimaj.knn.pq.FloatSDCNearestNeighbours Maven / Gradle / Ivy
/*
AUTOMATICALLY GENERATED BY jTemp FROM
/Users/jsh2/Work/openimaj/target/checkout/machine-learning/nearest-neighbour/src/main/jtemp/org/openimaj/knn/pq/#T#SDCNearestNeighbours.jtemp
*/
/**
* Copyright (c) 2011, The University of Southampton and the individual contributors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the University of Southampton nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.openimaj.knn.pq;
import org.openimaj.citation.annotation.Reference;
import org.openimaj.citation.annotation.ReferenceType;
import org.openimaj.feature.FloatFVComparison;
import org.openimaj.util.pair.IntFloatPair;
import org.openimaj.util.queue.BoundedPriorityQueue;
/**
* Nearest-neighbours using Symmetric Distance Computation (SDC) on Product
* Quantised vectors. In SDC, both query and the database points are quantised.
* Distances are calculated by look-up from precomputed tables of the distance
* between all centroids for each subvector.
*
* SDC has the same computational cost as ADC, but a higher error in the
* computed distance, so its use is not recommended. This implementation is
* provided for completeness only.
*
* @author Jonathon Hare ([email protected])
*/
@Reference(
type = ReferenceType.Article,
author = { "Jegou, Herve", "Douze, Matthijs", "Schmid, Cordelia" },
title = "Product Quantization for Nearest Neighbor Search",
year = "2011",
journal = "IEEE Trans. Pattern Anal. Mach. Intell.",
pages = { "117", "", "128" },
url = "http://dx.doi.org/10.1109/TPAMI.2010.57",
month = "January",
number = "1",
publisher = "IEEE Computer Society",
volume = "33",
customData = {
"issn", "0162-8828",
"numpages", "12",
"doi", "10.1109/TPAMI.2010.57",
"acmid", "1916695",
"address", "Washington, DC, USA",
"keywords", "High-dimensional indexing, High-dimensional indexing, image indexing, very large databases, approximate search., approximate search., image indexing, very large databases"
})
public class FloatSDCNearestNeighbours extends FloatADCNearestNeighbours {
float[][][] distances;
/**
* Construct the SDC with the given quantiser, centroids (corresponding to
* the quantiser's internal assigners), and data.
*
* @param pq
* the Product Quantiser
* @param pqCentroids
* the centroids corresponding to the the Product Quantiser's
* internal assigners.
* @param dataPoints
* the data to index
*/
public FloatSDCNearestNeighbours(FloatProductQuantiser pq, float[][][] pqCentroids, float[][] dataPoints) {
super(pq, dataPoints);
this.distances = new float[pq.assigners.length][][];
for (int i = 0; i < pq.assigners.length; i++) {
final float[][] centroids = pqCentroids[i];
distances[i] = new float[centroids.length][centroids.length];
for (int j = 0; j < centroids.length; j++) {
for (int k = j; k < centroids.length; k++) {
distances[i][j][k] = (float) FloatFVComparison.SUM_SQUARE.compare(centroids[j], centroids[k]);
distances[i][k][j] = distances[i][j][k];
}
}
}
}
@Override
protected void computeDistances(float[] fullQuery, BoundedPriorityQueue queue, IntFloatPair workingPair)
{
final byte[] query = pq.quantise(fullQuery);
for (int i = 0; i < data.length; i++) {
workingPair.first = i;
workingPair.second = 0;
for (int j = 0; j < query.length; j++) {
workingPair.second += distances[j][query[j] + 128][data[i][j] + 128];
}
workingPair = queue.offerItem(workingPair);
}
}
}