Anaphe Home Page Reference Documentation

Main Page     Namespaces     Classes     Source Code    

P_Uneven_Partition.cpp

Go to the documentation of this file.
00001 #include "HTL/P_Uneven_Partition.h"
00002 
00003 
00004 //
00005 // Let's get lazy and use the preprocessor:
00006 //
00007 //#define TEMPLATE___   template< class T_Point >
00008 //#define CLASS___      P_Uneven_Partition< T_Point >
00009 #define TEMPLATE___     
00010 #define CLASS___        P_Uneven_Partition
00011 #define T_Point         double
00012 
00013 TEMPLATE___
00014 CLASS___::P_Uneven_Partition( HTL_STD::vector<float> &some_points,
00015         End_Point_Convention a_convention )
00016 #ifdef HTL_USE_EXCEPTIONS
00017 throw (HTLExceptions::NotEnoughPoints)
00018 #endif //HTL_USE_EXCEPTIONS
00019         : I_Partition(), end_point_convention_ (a_convention)
00020 {
00021   if (some_points.size() < 2) {
00022     HTL_ERR("Less than two points specified for variable binning");
00023 #ifdef HTL_USE_EXCEPTIONS
00024     throw HTLExceptions::NotEnoughPoints();
00025 #endif //HTL_USE_EXCEPTIONS
00026   }
00027   // copy points over ...
00028   points_.resize(some_points.size());
00029   for (size_t i=0; i < some_points.size(); i++) { 
00030     points_[i] = some_points[i]; 
00031   }
00032 
00033   initializePartition();
00034 }
00035 
00036 TEMPLATE___
00037 CLASS___::P_Uneven_Partition( HTL_STD::vector<double> &some_points,
00038         End_Point_Convention a_convention )
00039 #ifdef HTL_USE_EXCEPTIONS
00040 throw (HTLExceptions::NotEnoughPoints)
00041 #endif //HTL_USE_EXCEPTIONS
00042         : I_Partition(), end_point_convention_ (a_convention)
00043 {
00044   if (some_points.size() < 2) {
00045     HTL_ERR("Less than two points specified for variable binning");
00046 #ifdef HTL_USE_EXCEPTIONS
00047     throw HTLExceptions::NotEnoughPoints();
00048 #endif //HTL_USE_EXCEPTIONS
00049   }
00050   // copy points over ...
00051   points_.resize(some_points.size());
00052   for (size_t i=0; i < some_points.size(); i++) { 
00053     points_[i] = some_points[i];
00054   }
00055   initializePartition();
00056 }
00057 
00058 TEMPLATE___
00059 void CLASS___::initializePartition()
00060 {
00061   count_ = points_.size() - 1; // Number of in-range bins.
00062   lower_point_ = points_[0];
00063   upper_point_ = points_[ count_ ];
00064 }
00065 
00066 TEMPLATE___
00067 CLASS___::P_Uneven_Partition( I_Partition &another )
00068 #ifdef HTL_USE_EXCEPTIONS
00069 throw (HTLExceptions::NotEnoughPoints)
00070 #endif //HTL_USE_EXCEPTIONS
00071         : points_( another.bin_count()+1 )
00072 {
00073   count_ = another.bin_count();
00074   if (count_ > 1) {
00075     lower_point_ = T_Point( another.i_lower_point() );
00076     upper_point_ = T_Point( another.i_upper_point() );
00077     for( Index i=0; i<count_; i++ ) {
00078       points_[i] = T_Point( another.i_lower_point(i) );
00079     }
00080     points_[count_] = upper_point_;
00081     end_point_convention_ = another.end_point_convention();
00082   } else {
00083     HTL_ERR("Less than two points specified for variable binning");
00084 #ifdef HTL_USE_EXCEPTIONS
00085     throw HTLExceptions::NotEnoughPoints();
00086 #endif //HTL_USE_EXCEPTIONS
00087   }
00088 }
00089 
00090 
00091 TEMPLATE___
00092 void CLASS___::map_index1( T_Point a_point, Index &an_index, 
00093         Extra_Index &an_extra_index )
00094 {
00095         // Note: the returned value of `an_index' must not be relied on 
00096         // when `a_mapped_index' is out of range.
00097 
00098         // Update extra index:
00099         //
00100         // 1. Simple case:
00101         //      a_point not in [lower_point; upper_point]
00102         //
00103         if( a_point < lower_point() ) {
00104                 // Simple case: a_point < lower_point:
00105                 an_extra_index = H_UNDERFLOW;
00106                 return;
00107 
00108         } else if( a_point > upper_point() ) {
00109                 // Simple case: a_point > upper_point:
00110                 an_extra_index = H_OVERFLOW;
00111                 return;
00112         }
00113 
00114         //ENSURE( a_point >= lower_point() && a_point <= upper_point() );
00115         if (!( a_point >= lower_point() && a_point <= upper_point() )) {
00116           HTL_ERR("a_point >= lower_point() && a_point <= upper_point()");
00117           return;
00118         }
00119 
00120 
00121         // From now on, the point `a_point' MAY be in range.
00122         // We are not this sure because of end point convention.
00123         //
00124         // Find the in range index:
00125         //
00126         an_index = 0;
00127         while( an_index < bin_count() ) {
00128                 if( a_point < upper_point( an_index ) ) break;
00129                 an_index ++;
00130         }
00131         //ENSURE( an_index >= 0 && an_index <= count_ );
00132         if (!( an_index >= 0 && an_index <= count_ )) {
00133           HTL_ERR("( an_index >= 0 && an_index <= count_ )");
00134           return;
00135         }
00136 
00137 
00138         // 2. Now check whether the point `a_point' maps existing boundaries,
00139         // i.e. check whether `a_point' equals lower_point(i), i=0..count_.
00140         // If it does, then apply end-point convention:
00141         //      . RIGHT_OPEN [a;b[: nothing to do.
00142         //      . LEFT_OPEN  ]a;b]: correct index is an_index-1.
00143         //
00144         if( end_point_convention_ == LEFT_OPEN ) {
00145                 if(     (upper_point() == a_point) ||
00146                         (lower_point(an_index) == a_point) )
00147                 {
00148                         // The 1st test is NECESSARY for the rightmost point.
00149                         // It tests the case when: a_point == rightmost_point =>
00150                         // rightmost_point then belongs to the last in-range bin
00151                         // <=> an_index -- == bin_count()-1
00152                         an_index --;
00153                 }
00154         }
00155 
00156         if( an_index < 0 ) {
00157                 // Case when: a_point == leftmost_point =>
00158                 // lower_point then belongs to the H_UNDERFLOW bin:
00159                 an_extra_index = H_UNDERFLOW;
00160                 return;
00161 
00162         } else if( an_index >= bin_count() ) {
00163                 // Case when: a_point == rightmost_point and the end-point
00164                 // convention is RIGHT_OPEN => rightmost_point then belongs
00165                 // to the H_OVERFLOW bin:
00166                 an_extra_index = H_OVERFLOW;
00167                 return;
00168         }
00169 
00170         // Now we are sure that the mapped index is in range:
00171         //
00172         an_extra_index = H_IN_RANGE;
00173 
00174         //ENSURE( (an_index >= 0) && (an_index < count_) );
00175         if (! (an_index >= 0) && (an_index < count_))
00176           HTL_ERR("(an_index >= 0) && (an_index < count_)");
00177         // Valid in-range bin index.
00178 }
00179 
00180 
00181 
00182 //
00183 // Thanks preprocessor! Now unuse it:
00184 //
00185 #undef T_Point
00186 #undef CLASS___
00187 #undef TEMPLATE___
00188 
00189 


Anaphe documentation generated by Doxygen (www.doxygen.org)