Anaphe Home Page Reference Documentation

Main Page     Namespaces     Classes     Source Code    

T_Uneven_Partition.cpp

Go to the documentation of this file.
00001 #include "HTL/T_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___      T_Uneven_Partition< T_Point >
00009 #define TEMPLATE___     
00010 #define CLASS___        T_Uneven_Partition
00011 #define T_Point         double
00012 
00013 
00014 TEMPLATE___
00015 CLASS___::T_Uneven_Partition( HTL_STD::vector<float> &some_points,
00016         End_Point_Convention a_convention )
00017 #ifdef HTL_USE_EXCEPTIONS
00018 throw (HTLExceptions::NotEnoughPoints)
00019 #endif //HTL_USE_EXCEPTIONS
00020         : I_Partition(), end_point_convention_ (a_convention)
00021 {
00022   if (some_points.size() < 2) {
00023     HTL_ERR("Less than two points specified for variable binning");
00024 #ifdef HTL_USE_EXCEPTIONS
00025     throw HTLExceptions::NotEnoughPoints();
00026 #endif //HTL_USE_EXCEPTIONS
00027   }
00028   // copy points over ...
00029   points_.resize(some_points.size());
00030   for (size_t i=0; i < some_points.size(); i++) { 
00031     points_[i] = some_points[i]; 
00032   }
00033   initializePartition();
00034 }
00035 
00036 TEMPLATE___
00037 CLASS___::T_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___::T_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         // From now on, the point `a_point' MAY be in range.
00121         // We are not this sure because of end point convention.
00122         //
00123         // Find the in range index:
00124         //
00125         an_index = 0;
00126         while( an_index < bin_count() ) {
00127                 if( a_point < upper_point( an_index ) ) break;
00128                 an_index ++;
00129         }
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         // 2. Now check whether the point `a_point' maps existing boundaries,
00138         // i.e. check whether `a_point' equals lower_point(i), i=0..count_.
00139         // If it does, then apply end-point convention:
00140         //      . RIGHT_OPEN [a;b[: nothing to do.
00141         //      . LEFT_OPEN  ]a;b]: correct index is an_index-1.
00142         //
00143         if( end_point_convention_ == LEFT_OPEN ) {
00144                 if(     (upper_point() == a_point) ||
00145                         (lower_point(an_index) == a_point) )
00146                 {
00147                         // The 1st test is NECESSARY for the rightmost point.
00148                         // It tests the case when: a_point == rightmost_point =>
00149                         // rightmost_point then belongs to the last in-range bin
00150                         // <=> an_index -- == bin_count()-1
00151                         an_index --;
00152                 }
00153         }
00154 
00155         if( an_index < 0 ) {
00156                 // Case when: a_point == leftmost_point =>
00157                 // lower_point then belongs to the H_UNDERFLOW bin:
00158                 an_extra_index = H_UNDERFLOW;
00159                 return;
00160 
00161         } else if( an_index >= bin_count() ) {
00162                 // Case when: a_point == rightmost_point and the end-point
00163                 // convention is RIGHT_OPEN => rightmost_point then belongs
00164                 // to the H_OVERFLOW bin:
00165                 an_extra_index = H_OVERFLOW;
00166                 return;
00167         }
00168 
00169         // Now we are sure that the mapped index is in range:
00170         //
00171         an_extra_index = H_IN_RANGE;
00172 
00173         //ENSURE( (an_index >= 0) && (an_index < count_) );
00174         if (! (an_index >= 0) && (an_index < count_))
00175           HTL_ERR("(an_index >= 0) && (an_index < count_)");
00176         // Valid in-range bin index.
00177 }
00178 
00179 
00180 
00181 //
00182 // Thanks preprocessor! Now unuse it:
00183 //
00184 #undef T_Point
00185 #undef CLASS___
00186 #undef TEMPLATE___
00187 
00188 


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