001/*
002        AUTOMATICALLY GENERATED BY jTemp FROM
003        /Users/jsh2/Work/openimaj/target/checkout/machine-learning/nearest-neighbour/src/main/jtemp/org/openimaj/knn/#T#NearestNeighbours.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.knn;
035
036import org.openimaj.feature.DoubleFVComparator;
037
038import org.openimaj.util.pair.IntDoublePair;
039
040/**
041 * Abstract base class for k-nearest-neighbour calculations with double[] data.
042 * 
043 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
044 * @author Sina Samangooei (ss@ecs.soton.ac.uk)
045 */
046public abstract class DoubleNearestNeighbours implements NearestNeighbours<double[], double[], IntDoublePair> {
047        /**
048         * Static method to find the sum-squared distance between
049         * a query vector and each of a set of points. Results are stored 
050         * in the dsq_out array, much must have the same length as the number
051         * of points.
052         * @param qu The query vector.
053         * @param pnts The points to compare against.
054         * @param dsq_out The resultant distances. 
055         */
056        public static void distanceFunc(final double [] qu, final double [][] pnts, double [] dsq_out) {
057                final int N = pnts.length;
058                final int D = pnts[0].length;
059                
060                for (int n=0; n < N; ++n) {
061                        dsq_out[n] = 0;
062                        for (int d=0; d<D; ++d) {
063                                dsq_out[n] += (qu[d] - pnts[n][d]) * (qu[d] - pnts[n][d]);
064                        }
065                }
066        }
067        
068        /**
069         * Static method to find the sum-squared distance between
070         * a query vector and a point. 
071         
072         * @param qu The query vector.
073         * @param pnt The point to compare against.
074         * @return The resultant distance.
075         */
076        public static double distanceFunc(final double [] qu, final double [] pnt) {
077                final int D = pnt.length;
078                
079                double dsq_out = 0;
080                for (int d=0; d<D; ++d) {
081                        dsq_out += (qu[d] - pnt[d]) * (qu[d] - pnt[d]);
082                }
083                
084                return dsq_out;
085        }
086
087        /**
088         * Static method to find a distance between
089         * a query vector and a point.
090         *
091         * @param distance the distance measure
092         * @param qu The query vector.
093         * @param pnt The point to compare against.
094         * @return The resultant distance. 
095         */
096        public static double distanceFunc(final DoubleFVComparator distance, final double [] qu, final double [] pnt) {
097                if (distance == null) {
098                        return distanceFunc(qu, pnt);
099                }
100                
101                if (distance.isDistance()) {
102                        return (double) distance.compare(qu, pnt);
103                } else {
104            return - (double) distance.compare(qu, pnt);
105                }
106        }
107        
108        /**
109         * Static method to find a distance between
110         * a query vector and each of a set of points. Results are stored 
111         * in the dsq_out array, much must have the same length as the number
112         * of points.
113         * @param distance the distance measure
114         * @param qu The query vector.
115         * @param pnts The points to compare against.
116         * @param dsq_out The resultant distances. 
117         */
118        public static void distanceFunc(final DoubleFVComparator distance, final double [] qu, final double [][] pnts, double [] dsq_out) {
119                if (distance == null) {
120                        distanceFunc(qu, pnts, dsq_out);
121                        return;
122                }
123                
124                final int N = pnts.length;
125
126                if (distance.isDistance()) {
127                        for (int n=0; n < N; ++n) {
128                                dsq_out[n] = (double) distance.compare(qu, pnts[n]);
129                        }       
130                } else {
131                        for (int n=0; n < N; ++n) {
132                                dsq_out[n] = - (double) distance.compare(qu, pnts[n]);
133                        }
134                }
135        }
136        
137        /**
138         * Get the number of dimensions of each vector in the dataset
139         * 
140         * @return the number of dimensions
141         */
142        public abstract int numDimensions();
143}