bounds_aux.h

00001 /* MLPACK 0.2
00002  *
00003  * Copyright (c) 2008, 2009 Alexander Gray,
00004  *                          Garry Boyer,
00005  *                          Ryan Riegel,
00006  *                          Nikolaos Vasiloglou,
00007  *                          Dongryeol Lee,
00008  *                          Chip Mappus, 
00009  *                          Nishant Mehta,
00010  *                          Hua Ouyang,
00011  *                          Parikshit Ram,
00012  *                          Long Tran,
00013  *                          Wee Chin Wong
00014  *
00015  * Copyright (c) 2008, 2009 Georgia Institute of Technology
00016  *
00017  * This program is free software; you can redistribute it and/or
00018  * modify it under the terms of the GNU General Public License as
00019  * published by the Free Software Foundation; either version 2 of the
00020  * License, or (at your option) any later version.
00021  *
00022  * This program is distributed in the hope that it will be useful, but
00023  * WITHOUT ANY WARRANTY; without even the implied warranty of
00024  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00025  * General Public License for more details.
00026  *
00027  * You should have received a copy of the GNU General Public License
00028  * along with this program; if not, write to the Free Software
00029  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00030  * 02110-1301, USA.
00031  */
00032 #ifndef BOUNDS_AUX_H
00033 #define BOUNDS_AUX_H
00034 
00035 #include "fastlib/fastlib.h"
00036 //#include "fastlib/fastlib_int.h"
00037 
00038 namespace bounds_aux {
00039   
00040   template<int t_pow>
00041   void MaxDistanceSq(const DHrectBound<t_pow> &bound1, 
00042                      const DHrectBound<t_pow> &bound2,
00043                      Vector &furthest_point_in_bound1,
00044                      double &furthest_dsqd) {
00045                        
00046     int dim = furthest_point_in_bound1.length();
00047     furthest_dsqd = 0;
00048 
00049     for (index_t d = 0; d < dim; d++) {
00050       
00051       const DRange &bound1_range = bound1.get(d);
00052       const DRange &bound2_range = bound2.get(d);
00053       
00054       double v1 = bound2_range.hi - bound1_range.lo;
00055       double v2 = bound1_range.hi - bound2_range.lo;
00056       double v;
00057       
00058       if(v1 > v2) {
00059         furthest_point_in_bound1[d] = bound1_range.lo;
00060         v = v1;
00061       }
00062       else {
00063         furthest_point_in_bound1[d] = bound1_range.hi;
00064         v = v2;
00065       }
00066       furthest_dsqd += math::PowAbs<t_pow, 1>(v); // v is non-negative
00067     }
00068     furthest_dsqd = math::Pow<2, t_pow>(furthest_dsqd);
00069   }
00070 
00071   template<int t_pow>
00072   void MaxDistanceSq(const DHrectBound<t_pow> &bound1, 
00073                      Vector &bound2_centroid,
00074                      Vector &furthest_point_in_bound1,
00075                      double &furthest_dsqd) {
00076                        
00077     int dim = furthest_point_in_bound1.length();
00078     furthest_dsqd = 0;
00079 
00080     for (index_t d = 0; d < dim; d++) {
00081       
00082       const DRange &bound1_range = bound1.get(d);
00083       
00084       double v1 = bound2_centroid[d] - bound1_range.lo;
00085       double v2 = bound1_range.hi - bound2_centroid[d];
00086       double v;
00087       
00088       if(v1 > v2) {
00089         furthest_point_in_bound1[d] = bound1_range.lo;
00090         v = v1;
00091       }
00092       else {
00093         furthest_point_in_bound1[d] = bound1_range.hi;
00094         v = v2;
00095       }
00096       furthest_dsqd += math::PowAbs<t_pow, 1>(v); // v is non-negative
00097     }
00098     furthest_dsqd = math::Pow<2, t_pow>(furthest_dsqd);
00099   }
00100 
00101   template<int t_pow, typename TVector>
00102   void MaxDistanceSq(const DBallBound < LMetric<t_pow>, TVector > &bound1, 
00103                      Vector &bound2_centroid,
00104                      Vector &furthest_point_in_bound1,
00105                      double &furthest_dsqd) {
00106                        
00107     furthest_dsqd = 0;
00108     
00109     // First compute the distance between the centroid of the bounding
00110     // ball and the given point.
00111     double distance = 
00112       LMetric<t_pow>::Distance(bound1.center(), bound2_centroid);
00113     
00114     // Compute the unit vector that has the same direction as the
00115     // vector pointing from the given point to the bounding ball
00116     // center.
00117     Vector unit_vector;
00118     la::SubInit(bound2_centroid, bound1.center(), &unit_vector);
00119     la::Scale(1.0 / distance, &unit_vector);
00120 
00121     furthest_point_in_bound1.CopyValues(bound1.center());
00122     la::AddExpert(bound1.radius(), unit_vector, &furthest_point_in_bound1);
00123     
00124     furthest_dsqd = math::Pow<2, t_pow>
00125       (la::RawLMetric<t_pow>(bound2_centroid.length(), 
00126                              furthest_point_in_bound1.ptr(), 
00127                              bound2_centroid.ptr()));
00128   }
00129 
00134   template<int t_pow, typename TVector>
00135   double MaxSideLengthOfBoundingBox
00136   (const DBallBound < LMetric<t_pow>, TVector > &ball_bound) {
00137     return ball_bound.radius() * 2;
00138   }
00139   
00144   template<int t_pow>
00145   double MaxSideLengthOfBoundingBox(const DHrectBound<t_pow> &bound) {
00146 
00147     double max_length = 0;
00148 
00149     for(index_t d = 0; d < bound.dim(); d++) {
00150       const DRange &range = bound.get(d);
00151       max_length = std::max(max_length, range.width());
00152     }
00153     return max_length;
00154   }
00155   
00159   template<int t_pow, typename TVector>
00160   double MaxL1Distance
00161   (const DBallBound < LMetric<t_pow>, TVector > &ball_bound1,
00162    const DBallBound < LMetric<t_pow>, TVector > &ball_bound2,
00163    int *dimension) {
00164     
00165     const Vector &center1 = ball_bound1.center();
00166     const Vector &center2 = ball_bound2.center();
00167     int dim = ball_bound1.center().length();
00168     double l1_distance = 0;
00169     for(index_t d = 0; d < dim; d++) {
00170       l1_distance += fabs(center1[d] - center2[d]);
00171     }
00172     l1_distance += ball_bound1.radius() + ball_bound2.radius();
00173     *dimension = center1.length();
00174     return l1_distance;
00175   }
00176 
00180   template<int t_pow>
00181   double MaxL1Distance(const DHrectBound<t_pow> &bound1,
00182                        const DHrectBound<t_pow> &bound2, int *dimension) {
00183 
00184     double farthest_distance_manhattan = 0;
00185     for(index_t d = 0; d < bound1.dim(); d++) {
00186       const DRange &range1 = bound1.get(d);
00187       const DRange &range2 = bound2.get(d);
00188       double bound1_centroid_coord = range1.lo + range1.width() / 2;
00189 
00190       farthest_distance_manhattan =
00191         max(farthest_distance_manhattan,
00192             max(fabs(bound1_centroid_coord - range2.lo),
00193                 fabs(bound1_centroid_coord - range2.hi)));
00194     }
00195     *dimension = bound1.dim();
00196     return farthest_distance_manhattan;
00197   }
00198 
00201   static int qsort_compar_(const void *a, const void *b) {
00202     
00203     index_t a_dereferenced = *((index_t *) a);
00204     index_t b_dereferenced = *((index_t *) b);
00205     
00206     if(a_dereferenced < b_dereferenced) {
00207       return -1;
00208     }
00209     else if(a_dereferenced > b_dereferenced) {
00210       return 1;
00211     }
00212     else {
00213       return 0;
00214     }
00215   }
00216 
00217   double RandomizedDistanceSqEuclidean(index_t length, const double *a, 
00218                                        const double *b) {
00219     
00220     int num_samples = (int) sqrt(length);
00221     double sample_mean = 0;
00222     ArrayList<index_t> dimension_indices;
00223     dimension_indices.Init(num_samples);
00224     for(index_t i = 0; i < num_samples; i++) {
00225       dimension_indices[i] = math::RandInt(0, length);
00226     }
00227     qsort(dimension_indices.begin(), num_samples, sizeof(index_t), 
00228           &qsort_compar_);
00229     
00230     for(index_t i = 0; i < num_samples; i++) {      
00231       sample_mean += math::Sqr(a[dimension_indices[i]] - 
00232                                b[dimension_indices[i]]);
00233     }
00234 
00235     sample_mean /= ((double) num_samples);    
00236     return sample_mean * length;
00237   }
00238 
00239 };
00240 
00241 #endif
Generated on Mon Jan 24 12:04:38 2011 for FASTlib by  doxygen 1.6.3