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.LongFVComparator;
037import org.openimaj.knn.LongNearestNeighboursExact;
038import org.openimaj.ml.clustering.assignment.HardAssigner;
039import org.openimaj.ml.clustering.CentroidsProvider;
040import org.openimaj.util.pair.IntDoublePair;
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 ExactLongAssigner implements HardAssigner<long[], double[], IntDoublePair> {
049        protected LongNearestNeighboursExact 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 ExactLongAssigner(CentroidsProvider<long[]> 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 ExactLongAssigner(CentroidsProvider<long[]> provider, LongFVComparator comparison) {
069                nn = new LongNearestNeighboursExact(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 ExactLongAssigner(long[][] data, LongFVComparator comparison) {
080                nn = new LongNearestNeighboursExact(data, comparison);
081        }
082        
083        @Override
084        public int[] assign(long[][] data) {
085                int [] argmins = new int [data.length];
086                double [] mins = new double [data.length];
087                
088                nn.searchNN(data, argmins, mins);
089                
090                return argmins;
091        }
092
093        @Override
094        public int assign(long[] data) {
095                return assign(new long[][] { data })[0];
096        }
097
098        @Override
099        public void assignDistance(long[][] data, int[] indices, double[] distances) {
100                nn.searchNN(data, indices, distances);
101        }
102
103        @Override
104        public IntDoublePair assignDistance(long[] data) {
105                int [] index = new int [1];
106                double [] distance = new double [1];
107                
108                nn.searchNN(new long[][] { data }, index, distance);
109                
110                return new IntDoublePair(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 LongNearestNeighboursExact getNN() {
129                return this.nn;
130        }
131}