DataRange.cxx

Go to the documentation of this file.
00001 // @(#)root/mathcore:$Id: DataRange.cxx 36558 2010-11-09 15:13:13Z moneta $
00002 // Author: L. Moneta Wed Aug 30 11:05:02 2006
00003 
00004 /**********************************************************************
00005  *                                                                    *
00006  * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
00007  *                                                                    *
00008  *                                                                    *
00009  **********************************************************************/
00010 
00011 // Implementation file for class DataRange
00012 
00013 #include "Fit/DataRange.h"
00014 #include "Math/Error.h"
00015 
00016 #include <algorithm>
00017 #include <limits>
00018 
00019 namespace ROOT { 
00020 
00021    namespace Fit { 
00022 
00023 DataRange::DataRange(double xmin, double xmax) : 
00024    fRanges( std::vector<RangeSet> (1) )
00025 {
00026    // construct a range for [xmin, xmax] 
00027    if (xmin < xmax) { 
00028       RangeSet rx(1); 
00029       rx[0] = std::make_pair(xmin, xmax); 
00030       fRanges[0] = rx; 
00031    }
00032 }
00033 
00034 
00035 DataRange::DataRange(double xmin, double xmax, double ymin, double ymax) : 
00036    fRanges( std::vector<RangeSet> (2) )
00037 {
00038    // construct a range for [xmin, xmax] , [ymin, ymax] 
00039    if (xmin < xmax) { 
00040       RangeSet rx(1); 
00041       rx[0] = std::make_pair(xmin, xmax); 
00042       fRanges[0] = rx; 
00043    }
00044    
00045    if (ymin < ymax) { 
00046       RangeSet ry(1); 
00047       ry[0] = std::make_pair(ymin, ymax); 
00048       fRanges[1] = ry; 
00049    }
00050 }
00051 
00052 DataRange::DataRange(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax) : 
00053    fRanges( std::vector<RangeSet> (3) )
00054 {
00055    // construct a range for [xmin, xmax] , [ymin, ymax] , [zmin, zmax] 
00056    if (xmin < xmax) { 
00057       RangeSet rx(1); 
00058       rx[0] = std::make_pair(xmin, xmax); 
00059       fRanges[0] = rx; 
00060    }
00061    if (ymin < ymax) {    
00062       RangeSet ry(1); 
00063       ry[0] = std::make_pair(ymin, ymax); 
00064       fRanges[1] = ry; 
00065    }
00066    if (zmin < zmax) {    
00067       RangeSet rz(1); 
00068       rz[0] = std::make_pair(zmin, zmax); 
00069       fRanges[2] = rz; 
00070    }
00071 }
00072 
00073 bool lessRange( const std::pair<double,double> & r1, const std::pair<double,double> & r2 ) { 
00074    // compare ranges using max position so in case of included ranges smaller one comes first
00075    return r1.second <  r2.second; 
00076 }
00077 
00078 std::pair<double, double> DataRange::operator() (unsigned int icoord,unsigned int irange) const {
00079    if ( Size(icoord) >  irange )
00080       return fRanges[icoord].at(irange);
00081    else if (irange == 0)  {
00082       // return [-inf +inf] for the other dimension 
00083       double xmin = 0; double xmax = 0; 
00084       GetInfRange(xmin,xmax);
00085       return std::make_pair<double,double>(xmin,xmax);     
00086    }                                               
00087    else { 
00088       // in case the irange-th does not exist for the given coordinate
00089       MATH_ERROR_MSG("DataRange::operator()","invalid range number - return (0,0)");
00090       return std::make_pair<double,double>(0,0);     
00091    }
00092 }  
00093 
00094 void DataRange::AddRange(unsigned  int  icoord , double xmin, double xmax  ) { 
00095    // add a range [xmin,xmax] for the new coordinate icoord 
00096 
00097    if (xmin >= xmax) return;  // no op in case of bad values
00098 
00099    // case the  coordinate is larger than the current allocated vector size
00100    if (icoord >= fRanges.size() ) { 
00101       RangeSet rx(1); 
00102       rx[0] = std::make_pair(xmin, xmax); 
00103       fRanges.resize(icoord+1);
00104       fRanges[icoord] = rx; 
00105       return;
00106    } 
00107    RangeSet & rs = fRanges[icoord]; 
00108    // case the vector  of the ranges is empty in the given coordinate
00109    if ( rs.size() == 0) { 
00110       rs.push_back(std::make_pair(xmin,xmax) ); 
00111       return;
00112    } 
00113    // case of  an already existing range
00114    // need to establish a policy (use OR or AND )
00115 
00116    CleanRangeSet(icoord,xmin,xmax); 
00117    // add the new one
00118    rs.push_back(std::make_pair(xmin,xmax) ); 
00119    // sort range in increasing values of xmax 
00120    std::sort( rs.begin(), rs.end() , lessRange);
00121 
00122 }
00123 
00124 void DataRange::SetRange(unsigned  int  icoord , double xmin, double xmax  ) { 
00125    // set a new range [xmin,xmax] for the new coordinate icoord 
00126 
00127    if (xmin >= xmax) return;  // no op in case of bad values
00128 
00129    // case the  coordinate is larger than the current allocated vector size
00130    if (icoord >= fRanges.size() ) { 
00131       fRanges.resize(icoord+1);
00132       RangeSet rs(1); 
00133       rs[0] = std::make_pair(xmin, xmax); 
00134       fRanges[icoord] = rs; 
00135       return;
00136    }
00137    // add range 
00138    RangeSet & rs = fRanges[icoord]; 
00139    // deleting existing ones if (exists)
00140    if (rs.size() > 1) MATH_WARN_MSG("DataRange::SetRange","remove existing range and keep only the set one");
00141    rs.resize(1); 
00142    rs[0] =  std::make_pair(xmin, xmax); 
00143    return; 
00144 }
00145 
00146 bool DataRange::IsInside(double x, unsigned int icoord ) const { 
00147    // check if a point is in range
00148 
00149    if (Size(icoord) == 0) return true;  // no range existing (is like -inf, +inf)  
00150    const RangeSet & ranges = fRanges[icoord];
00151    for (RangeSet::const_iterator itr = ranges.begin(); itr != ranges.end(); ++itr) { 
00152       if ( x < (*itr).first ) return false; 
00153       if ( x <= (*itr).second) return true; 
00154    }
00155    return false; // point is larger than last xmax
00156 } 
00157 
00158 void DataRange::Clear(unsigned int icoord ) { 
00159    // remove all ranges for coordinate icoord
00160    if (Size(icoord) == 0) return;  // no op in this case 
00161    fRanges[icoord].clear(); 
00162 }
00163 
00164 
00165 void DataRange::CleanRangeSet(unsigned int icoord, double xmin, double xmax) { 
00166    //  remove all the existing ranges between xmin and xmax 
00167    //  called when a new range is inserted
00168 
00169    // loop on existing ranges 
00170    RangeSet & ranges = fRanges[icoord]; 
00171    for (RangeSet::iterator itr = ranges.begin(); itr != ranges.end(); ++itr) { 
00172       // delete included ranges
00173       if ( itr->first >= xmin && itr->second <= xmax) { 
00174          itr = ranges.erase(itr);
00175          // itr goes to next element, so go back before adding
00176          --itr;
00177       }
00178    }
00179    
00180 }
00181 
00182 void DataRange::GetInfRange(double &xmin, double &xmax) { 
00183    // get the full range [-inf, +inf] for xmin and xmax 
00184    xmin = -std::numeric_limits<double>::infinity(); 
00185    xmax = std::numeric_limits<double>::infinity(); 
00186 }
00187 
00188    } // end namespace Fit
00189 
00190 } // end namespace ROOT
00191 

Generated on Tue Jul 5 14:33:22 2011 for ROOT_528-00b_version by  doxygen 1.5.1