package gr.iti.mklab.visual.quantization; /** * This class is used for computing residual vectors, given a coarse quantizer. * * @author Eleftherios Spyromitros-Xioufis * */ public class ResidualVectorComputation { private double[][] coarseQuantizer; private int vectorLength; private int numCentroids; public ResidualVectorComputation(double[][] coarseQuantizer, int vectorLength, int numCentroids) throws Exception { if (numCentroids != coarseQuantizer.length) { throw new Exception("The given number of centroids does not match the number of centroids in the coarse quantizer."); } if (vectorLength != coarseQuantizer[0].length) { throw new Exception("The given vector length does not match with the centroid length."); } this.coarseQuantizer = coarseQuantizer; this.vectorLength = vectorLength; this.numCentroids = numCentroids; } public double[] ComputeResidualVector(double[] vector) throws Exception { if (vector.length != vectorLength) { throw new Exception("The given vector length does not match with the length of the coarse quantizer's centroids"); } int nearestCentroidIndex = computeNearestCentroid(vector); double[] residualVector = new double[vectorLength]; for (int i = 0; i < vectorLength; i++) { residualVector[i] = coarseQuantizer[nearestCentroidIndex][i] - vector[i]; } return residualVector; } /** * Finds and returns the index of the coarse quantizer's centroid which is closer to the given vector. * * @param vector * @return */ private int computeNearestCentroid(double[] vector) { int centroidIndex = -1; double minDistance = Double.MAX_VALUE; for (int i = 0; i < numCentroids; i++) { double distance = 0; for (int j = 0; j < vectorLength; j++) { distance += (coarseQuantizer[i][j] - vector[j]) * (coarseQuantizer[i][j] - vector[j]); if (distance >= minDistance) { break; } } if (distance < minDistance) { minDistance = distance; centroidIndex = i; } } return centroidIndex; } }