CVR-Lib last update 20 Sep 2009

cvrEuclideanDistantor.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1998 - 2005
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  *
00006  * This file is part of the Computer Vision and Robotics Library (CVR-Lib)
00007  *
00008  * The CVR-Lib is free software; you can redistribute it and/or
00009  * modify it under the terms of the BSD License.
00010  *
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  *
00019  * 2. Redistributions in binary form must reproduce the above copyright notice,
00020  *    this list of conditions and the following disclaimer in the documentation
00021  *    and/or other materials provided with the distribution.
00022  *
00023  * 3. Neither the name of the authors nor the names of its contributors may be
00024  *    used to endorse or promote products derived from this software without
00025  *    specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00028  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00031  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00032  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00033  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00034  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00035  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00036  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00037  * POSSIBILITY OF SUCH DAMAGE.
00038  */
00039 
00040 
00041 
00042 
00043 /**
00044  * \file   cvrEuclideanDistantor.h
00045  *         This file contains the policy classes euclideanDistantor
00046  *         and euclideanSqrDistantor, which calculate the L2 distance
00047  *         and it square, respecively
00048  * \author Jochen Wickel
00049  * \date   28.06.2000
00050  *
00051  * $Id: cvrEuclideanDistantor.h,v 1.1 2005/03/29 13:26:46 doerfler Exp $
00052  */
00053 
00054 #ifndef _CVR_EUCLIDEAN_DISTANTOR_H_
00055 #define _CVR_EUCLIDEAN_DISTANTOR_H_
00056 
00057 #include "cvrDistanceType.h"
00058 #include "cvrEuclideanDistance.h"
00059 
00060 
00061 namespace cvr {
00062 
00063 
00064   /**
00065    * Policy class used by several classifiers/trees to measure the square
00066    * of the euclidean distance between two points of type T.
00067    *
00068    * The type T MUST define the \a value_type type, which exist for example
00069    * for vectors, (t)points and (t)rgbPixels.
00070    *
00071    * If you \e really want, you can use this class directly through the
00072    * operator().
00073    *
00074    * \code
00075    * euclideanSqrDistantor< vector<double> > myDist;
00076    * dvector a,b;
00077    * ... // fill vectors with data
00078    * double dist = myDist(a,b);
00079    * \endcode
00080    *
00081    * But remember that there is also a global template function distanceSqr()
00082    * which is easier to use:
00083    *
00084    * \code
00085    * dvector a,b;
00086    * ... // fill vectors with data
00087    * double dist = distanceSqr(a,b);
00088    * \endcode
00089    *
00090    * You can of course also use the cvr::l2Distance functor, as usual with its
00091    * apply() methods.
00092    */
00093   template <class T, class D=typename distanceType<T>::square_distance_type>
00094   class euclideanSqrDistantor {
00095   public:
00096     /**
00097      * type returned by the distantor
00098      */
00099     typedef D distance_type;
00100 
00101     /**
00102      * compute the distance between a and b
00103      */
00104     inline distance_type operator()(const T& a,const T& b) const {
00105       return
00106         static_cast<distance_type>(euclideanDistanceSqr(a,b));
00107     };
00108 
00109     /**
00110      * @name Special methods for Minkowski distances
00111      */
00112     //@{
00113 
00114     /**
00115      * This member accumulates in the given accumulator, the
00116      * given element.
00117      *
00118      * It can be used when the distance need to be computed manually, but
00119      * using a distantor to still allow the flexibility of changing distances.
00120      *
00121      * For the euclideanSqrDistantor this is just acc+=(elem*elem).
00122      *
00123      * @param element component of the difference between two points.
00124      * @param accumulator variable where the elements will be accumulated.
00125      */
00126     inline void accumulate(const distance_type element,
00127                            distance_type& accumulator) const {
00128       accumulator+=(element*element);
00129     }
00130 
00131     /**
00132      * This member accumulates in the given accumulator, the difference
00133      * of the given elements.
00134      *
00135      * It can be used when the distance need to be computed manually, but
00136      * using a distantor to still allow the flexibility of changing distances.
00137      *
00138      * For the euclideanSqrDistantor this is just acc+=((elem1-elem2)^2).
00139      *
00140      * @param element1 component of the first point
00141      * @param element2 component of the second point
00142      * @param accumulator variable where the elements will be accumulated.
00143      */
00144     inline void accumulate(const typename T::value_type element1,
00145                            const typename T::value_type element2,
00146                            distance_type& accumulator) const {
00147       const distance_type tmp = static_cast<distance_type>(element2-element1);
00148       accumulator+=(tmp*tmp);
00149     }
00150 
00151     /**
00152      * Compute from the given accumulator the desired distance
00153      */
00154     inline distance_type
00155     computeDistance(const distance_type& accumulator) const {
00156       return accumulator;
00157     }
00158 
00159     /**
00160      * return the distance between two components, which is in some way
00161      * a component of the total distance (that is the reason for the name).
00162      *
00163      * For this distantor it return (element2-element1)^2
00164      */
00165     inline distance_type
00166     component(const typename T::value_type element1,
00167               const typename T::value_type element2) const {
00168       const distance_type tmp = static_cast<distance_type>(element2-element1);
00169       return tmp*tmp;
00170     }
00171 
00172     /**
00173      * Return true if the given partial computed from accumulator is less than
00174      * the given distance.
00175      *
00176      * Assume you have accumulated \a acc until now, and you want to check if
00177      * the partial distance derived from this accumulator is less than
00178      * the given distance.  So you check accLessThan(accumulator,distance)
00179      *
00180      * For this norm it computes acc < dist
00181      */
00182     inline bool accLessThan(const distance_type acc,
00183                             const distance_type dist) const {
00184       return (acc < dist);
00185     }
00186 
00187     /**
00188      * Return true if the given partial computed from accumulator is greater
00189      * than the given distance.
00190      *
00191      * Assume you have accumulated \a acc until now, and you want to check if
00192      * the partial distance derived from this accumulator is greater than
00193      * the given distance.  So you check accLessThan(accumulator,distance)
00194      *
00195      * For this norm it computes acc > dist
00196      */
00197     inline bool accGreaterThan(const distance_type acc,
00198                                const distance_type dist) const {
00199       return (acc > dist);
00200     }
00201     //@}
00202   };
00203 
00204   /**
00205    * Policy class used by several classifiers/trees to measure the
00206    * euclidean distance between two points of type T.
00207    *
00208    * The type T MUST define the \a value_type type, which exist for example
00209    * for vectors, (t)points and (t)rgbPixels.
00210    *
00211    * If you \e really want, you can use this class directly through the
00212    * operator().
00213    *
00214    * \code
00215    * euclideanDistantor< vector<double> > myDist;
00216    * dvector a,b;
00217    * ... // fill vectors with data
00218    * double dist = myDist(a,b);
00219    * \endcode
00220    *
00221    * But remember that there is also a global template function distanceSqr()
00222    * which can be more easily used:
00223    *
00224    * \code
00225    * dvector a,b;
00226    * ... // fill vectors with data
00227    * double dist = sqrt(distanceSqr(a,b));
00228    * \endcode
00229    *
00230    * You can of course also use the cvr::l2Distance functor, as usual with its
00231    * apply() methods.
00232    */
00233   template <class T, class D=typename distanceType<T>::fp_distance_type>
00234   class euclideanDistantor {
00235   public:
00236     /**
00237      * type returned by the distantor
00238      */
00239     typedef D distance_type;
00240 
00241     /**
00242      * compute the distance between a and b
00243      */
00244     inline distance_type operator()(const T& a,const T& b) const {
00245       return static_cast<distance_type>(euclideanDistance(a,b));
00246     }
00247 
00248     /**
00249      * @name Special methods for Minkowski distances
00250      */
00251     //@{
00252 
00253     /**
00254      * This member accumulates in the given accumulator, the
00255      * given element.
00256      *
00257      * It can be used when the distance need to be computed manually, but
00258      * using a distantor to still allow the flexibility of changing distances.
00259      *
00260      * For the euclideanDistantor this is just acc+=(elem*elem).
00261      *
00262      * @param element component of the difference between two points.
00263      * @param accumulator variable where the elements will be accumulated.
00264      */
00265     inline void accumulate(const distance_type element,
00266                            distance_type& accumulator) const {
00267       accumulator+=(element*element);
00268     }
00269 
00270     /**
00271      * This member accumulates in the given accumulator, the difference
00272      * of the given elements.
00273      *
00274      * It can be used when the distance need to be computed manually, but
00275      * using a distantor to still allow the flexibility of changing distances.
00276      *
00277      * For the euclideanDistantor this is just acc+=((elem2-elem1)^2).
00278      *
00279      * @param element1 component of the first point
00280      * @param element2 component of the second point
00281      * @param accumulator variable where the elements will be accumulated.
00282      */
00283     inline void accumulate(const typename T::value_type element1,
00284                            const typename T::value_type element2,
00285                            distance_type& accumulator) const {
00286       const distance_type tmp = static_cast<distance_type>(element2-element1);
00287       accumulator+=(tmp*tmp);
00288     }
00289 
00290     /**
00291      * Compute from the given accumulator the desired distance
00292      */
00293     inline distance_type
00294     computeDistance(const distance_type& accumulator) const {
00295       return sqrt(accumulator);
00296     }
00297 
00298     /**
00299      * return the distance between two components, which is in some way
00300      * a component of the total distance (that is the reason for the name).
00301      *
00302      * For this distantor it return abs(element2-element1)
00303      */
00304     inline distance_type
00305     component(const typename T::value_type element1,
00306               const typename T::value_type element2) const {
00307       return static_cast<distance_type>(abs(element2-element1));
00308     }
00309 
00310     /**
00311      * Return true if the given partial computed from accumulator is less than
00312      * the given distance.
00313      *
00314      * Assume you have accumulated \a acc until now, and you want to check if
00315      * the partial distance derived from this accumulator is less than
00316      * the given distance.  So you check accLessThan(accumulator,distance)
00317      *
00318      * For this norm it computes acc < (dist*dist)
00319      */
00320     inline bool accLessThan(const distance_type acc,
00321                             const distance_type dist) const {
00322       return (acc < (dist*dist));
00323     }
00324 
00325     /**
00326      * Return true if the given partial computed from accumulator is greater
00327      * than the given distance.
00328      *
00329      * Assume you have accumulated \a acc until now, and you want to check if
00330      * the partial distance derived from this accumulator is less than
00331      * the given distance.  So you check accLessThan(accumulator,distance)
00332      *
00333      * For this norm it computes acc > (dist*dist)
00334      */
00335     inline bool accGreaterThan(const distance_type acc,
00336                                const distance_type dist) const {
00337       return (acc > (dist*dist));
00338     }
00339     //@}
00340   };
00341 
00342 }
00343 
00344 #endif

Generated on Sun Sep 20 22:07:59 2009 for CVR-Lib by Doxygen 1.5.8