001/*
002        AUTOMATICALLY GENERATED BY jTemp FROM
003        /Users/jsh2/Work/openimaj/target/checkout/machine-learning/clustering/src/main/jtemp/org/openimaj/ml/clustering/assignment/hard/Exact#T#Assigner.jtemp
004*/
005/**
006 * Copyright (c) 2011, The University of Southampton and the individual contributors.
007 * All rights reserved.
008 *
009 * Redistribution and use in source and binary forms, with or without modification,
010 * are permitted provided that the following conditions are met:
011 *
012 *   *  Redistributions of source code must retain the above copyright notice,
013 *      this list of conditions and the following disclaimer.
014 *
015 *   *  Redistributions in binary form must reproduce the above copyright notice,
016 *      this list of conditions and the following disclaimer in the documentation
017 *      and/or other materials provided with the distribution.
018 *
019 *   *  Neither the name of the University of Southampton nor the names of its
020 *      contributors may be used to endorse or promote products derived from this
021 *      software without specific prior written permission.
022 *
023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
024 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
025 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
026 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
027 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
028 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
029 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
030 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
031 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
032 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
033 */
034package org.openimaj.ml.clustering.assignment.hard;
035
036import org.openimaj.feature.IntFVComparator;
037import org.openimaj.knn.IntNearestNeighboursExact;
038import org.openimaj.ml.clustering.assignment.HardAssigner;
039import org.openimaj.ml.clustering.CentroidsProvider;
040import org.openimaj.util.pair.IntFloatPair;
041
042/**
043 * A {@link HardAssigner} that assigns points to the closest
044 * cluster based on the distance to the centroid.
045 * 
046 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
047 */
048public class ExactIntAssigner implements HardAssigner<int[], float[], IntFloatPair> {
049        protected IntNearestNeighboursExact nn;
050        
051        /**
052         * Construct the assigner using the given cluster data. The
053         * distance function defaults to Euclidean.
054         * 
055         * @param provider the cluster data provider
056         */
057        public ExactIntAssigner(CentroidsProvider<int[]> provider) {
058                this(provider, null);
059        }
060        
061        /**
062         * Construct the assigner using the given cluster data and 
063         * distance function.
064         * 
065         * @param provider the cluster data provider
066         * @param comparison the distance function
067         */
068        public ExactIntAssigner(CentroidsProvider<int[]> provider, IntFVComparator comparison) {
069                nn = new IntNearestNeighboursExact(provider.getCentroids(), comparison);
070        }
071        
072        /**
073         * Construct the assigner using the given cluster data and 
074         * distance function.
075         * 
076         * @param data the cluster data
077         * @param comparison the distance function
078         */
079        public ExactIntAssigner(int[][] data, IntFVComparator comparison) {
080                nn = new IntNearestNeighboursExact(data, comparison);
081        }
082        
083        @Override
084        public int[] assign(int[][] data) {
085                int [] argmins = new int [data.length];
086                float [] mins = new float [data.length];
087                
088                nn.searchNN(data, argmins, mins);
089                
090                return argmins;
091        }
092
093        @Override
094        public int assign(int[] data) {
095                return assign(new int[][] { data })[0];
096        }
097
098        @Override
099        public void assignDistance(int[][] data, int[] indices, float[] distances) {
100                nn.searchNN(data, indices, distances);
101        }
102
103        @Override
104        public IntFloatPair assignDistance(int[] data) {
105                int [] index = new int [1];
106                float [] distance = new float [1];
107                
108                nn.searchNN(new int[][] { data }, index, distance);
109                
110                return new IntFloatPair(index[0], distance[0]);
111        }
112        
113        @Override
114        public int size() {
115            return nn.size();
116        }
117        
118        @Override
119        public int numDimensions() {
120            return nn.numDimensions();
121        }
122        
123        /**
124         * Get the underlying nearest-neighbour implementation.
125         * 
126         * @return the underlying nearest-neighbour implementation.
127         */
128        public IntNearestNeighboursExact getNN() {
129                return this.nn;
130        }
131}