Atlfast::Interpolator Class Reference

#include <Interpolator.h>

List of all members.

Public Member Functions

 Interpolator (string)
double interpolate (deque< double >, bool performedchecks=false)
double getValue ()
void setDefault (double)
void setDefault (int, double)
void setDefault (string, double)
void setDefault (int, double, double)
void setDefault (string, double, double)
void setContinuousBoundaries ()
double getNearestValue (deque< double >)
void dump ()

Private Member Functions

 Interpolator (double, ifstream &, int &, int &, vector< int > &, int &)
void Setup (ifstream &, int &, int &, vector< int > &, int &)
void findLimits (deque< pair< double, double > > &)
void nDimensionsToJump (ifstream &, int &, int &)
bool inLimits (deque< double >, double &)
void exitParseWithMessage (string, int, string)

Private Attributes

vector< pair< double, double > > m_pairs
vector< Interpolatorm_interpolators
double m_value
deque< pair< double, double > > m_limits
deque< pair< double, double > > m_defaults
map< string, int > m_levelnames
bool m_contBounds


Detailed Description

Definition at line 55 of file Interpolator.h.


Constructor & Destructor Documentation

Atlfast::Interpolator::Interpolator ( string   ) 

Definition at line 6 of file Interpolator.cxx.

00006                                            {
00007 
00008     int level = 1;
00009     int jump = 0;
00010     vector<int> npoints;
00011     int nline = 0;
00012     
00013     // Make a filestream from the input filename to pass to Setup
00014     ifstream ifs(filename.c_str());
00015     Setup(ifs,level,jump,npoints,nline);
00016     
00017     // Fill m_limits with the limits in each dimension of all
00018     // held values
00019     findLimits(m_limits);
00020 
00021     // Initialise default return values in all dimensions to zero
00022     setDefault(0);
00023     
00024     // Check to see if number of level names (if used)
00025     // is equal to the number of levels
00026     int nlevelnames = m_levelnames.size();
00027     int nlevels = npoints.size();
00028     if ( nlevelnames && nlevelnames != nlevels ){
00029       std::cout << nlevelnames << " level identifiers given but "
00030                 << nlevels << " levels detected, exiting" << std::endl;
00031       exit(1);  
00032     }
00033     
00034     m_contBounds = false;
00035     
00036   }

Atlfast::Interpolator::Interpolator ( double  ,
ifstream &  ,
int &  ,
int &  ,
vector< int > &  ,
int &   
) [private]

Definition at line 38 of file Interpolator.cxx.

00039                                                                          :
00040     m_value(value){
00041     ++level;
00042     Setup(ifs,level,jump,npoints,nline);
00043   }


Member Function Documentation

double Atlfast::Interpolator::interpolate ( deque< double >  ,
bool  performedchecks = false 
)

Definition at line 167 of file Interpolator.cxx.

00167                                                                             {
00168     
00169     if ( !performedchecks && values.size() != m_limits.size()){ 
00170       std::cout << "Interpolator has " << m_limits.size()
00171                 << " dimensions, supplied point exists in "
00172                 << values.size() << " dimensions!" << std::endl;
00173       exit(1);
00174     }
00175     
00176     // Only check the limits the first time this function is called
00177     double def;
00178     if (!m_contBounds && !performedchecks && !inLimits(values,def))
00179       return def;
00180 
00181     performedchecks = true;
00182     
00183     
00184     double fraction,value1,value2;
00185     double value = values.front();
00186     
00187     if (m_interpolators.size()){
00188       
00189       // If m_interpolators is filled, this is not the lowest dimension and interpolate
00190       // must be called for Interpolators in the next dimension down. Use ClosestInterpolators
00191       // to find the appropriate two Interpolators
00192       
00193       values.pop_front();
00194       ClosestInterpolators ci(value);
00195       vector<Interpolator>::iterator viitr = std::adjacent_find(m_interpolators.begin(),
00196                                                                 m_interpolators.end(),
00197                                                                 ci);
00198       vector<Interpolator>::iterator viitr2;
00199       
00200       if (m_contBounds && viitr == m_interpolators.end()){
00201         if ( value < (*m_interpolators.begin()).getValue() ){
00202           viitr = m_interpolators.begin();
00203         }else{
00204           viitr = (m_interpolators.end()-1);
00205         }
00206         fraction = 0;
00207         value1 = (*viitr).interpolate(values,performedchecks);
00208         value2 = 0;
00209         
00210       }else{
00211         viitr2 = viitr + 1;
00212         // Fraction tells us where between the two points we are
00213         
00214         fraction = (value - (*viitr).getValue())/((*viitr2).getValue() - (*viitr).getValue());
00215         value1 = (*viitr).interpolate(values,performedchecks);
00216         value2 = (*viitr2).interpolate(values,performedchecks);
00217       }
00218       
00219     }else{
00220       
00221       // This is the lowest dimension. Use ClosestDoublePairs to find the appropriate two
00222       // pairs containing the values to interpolate between.
00223       
00224       ClosestDoublePairs cdp(value);
00225       vector<pair<double,double> >::iterator vdpitr = std::adjacent_find(m_pairs.begin(),
00226                                                                          m_pairs.end(),
00227                                                                          cdp);
00228       vector<pair<double,double> >::iterator vdpitr2;
00229       
00230       if (m_contBounds && vdpitr == m_pairs.end()){
00231         if ( value < (*m_pairs.begin()).first ){
00232           vdpitr = m_pairs.begin();
00233         }else{
00234           vdpitr = (m_pairs.end()-1);
00235         }
00236 
00237         fraction = 0;
00238         value1 = (*vdpitr).second;
00239         value2 = 0;
00240       }else{
00241         vdpitr2 = vdpitr + 1;
00242         // p1 and p2 are pointers to the adjacent elements found, replace them later
00243         fraction = (value - (*vdpitr).first)/((*vdpitr2).first - (*vdpitr).first);
00244         value1 = (*vdpitr).second;
00245         value2 = (*vdpitr2).second;
00246       }
00247       
00248     }
00249     
00250     // Do interpolation
00251     return value1 + fraction*(value2-value1);   
00252   }

double Atlfast::Interpolator::getValue (  )  [inline]

Definition at line 59 of file Interpolator.h.

00059 {return m_value;}

void Atlfast::Interpolator::setDefault ( double   ) 

Definition at line 350 of file Interpolator.cxx.

00350                                          {
00351 
00352     // Find number of levels to which to apply this default
00353     int nlevels = m_limits.size();
00354 
00355     // Get rid of previous defaults, if any
00356     m_defaults.clear();
00357 
00358     // For each level, add def as the default return value
00359     // for being outside limits in either direction
00360     while (nlevels--){
00361       pair<double,double> default_pair(def,def);
00362       m_defaults.push_back(default_pair);
00363     }
00364     
00365     return;
00366   }

void Atlfast::Interpolator::setDefault ( int  ,
double   
)

Definition at line 368 of file Interpolator.cxx.

00368                                                     {
00369 
00370     setDefault(level,def,def);
00371     return;
00372     
00373   }

void Atlfast::Interpolator::setDefault ( string  ,
double   
)

Definition at line 388 of file Interpolator.cxx.

00388                                                            {
00389     setDefault(levelname,def,def);
00390     return;
00391   }

void Atlfast::Interpolator::setDefault ( int  ,
double  ,
double   
)

Definition at line 375 of file Interpolator.cxx.

00375                                                                             {
00376     
00377     if (level < 1 || static_cast<std::deque<pair<double,double> >::size_type>(level) > m_limits.size()){
00378       std::cout << "Cannot set default for level " << level << std::endl;
00379       exit(1);
00380     }
00381 
00382     pair<double,double> default_pair(def_below,def_above);
00383     m_defaults[level-1] = default_pair;
00384     return;
00385     
00386   }

void Atlfast::Interpolator::setDefault ( string  ,
double  ,
double   
)

Definition at line 393 of file Interpolator.cxx.

00393                                                                                    {
00394 
00395     if ( !m_levelnames.size()){
00396       std::cout << "No level names specified in input file, cannot set default with name" << std::endl;
00397       exit(1);
00398     }
00399 
00400     if (!m_levelnames[levelname]){
00401       std::cout << "Level name " << levelname << " not found (typo?)" << std::endl;
00402       exit(1);
00403     }
00404 
00405     setDefault(m_levelnames[levelname],def_below,def_above);
00406 
00407     return;
00408   }

void Atlfast::Interpolator::setContinuousBoundaries (  )  [inline]

Definition at line 65 of file Interpolator.h.

00065 {m_contBounds = true;}

double Atlfast::Interpolator::getNearestValue ( deque< double >   ) 

Definition at line 410 of file Interpolator.cxx.

00410                                                           {
00411     
00412     double value = values.front();
00413 
00414     if (m_interpolators.size()){
00415       
00416       values.pop_front();
00417       vector<Interpolator>::iterator closestPoint;
00418       
00419       for (vector<Interpolator>::iterator intItr=m_interpolators.begin();
00420            intItr!=m_interpolators.end();++intItr){
00421         if (intItr==m_interpolators.begin() && 
00422             fabs(value-(*intItr).getValue()) < fabs(value-(*(intItr+1)).getValue()))
00423           closestPoint = intItr;
00424         else if (intItr==m_interpolators.end()-1 && 
00425                  fabs(value-(*intItr).getValue()) < fabs(value-(*(intItr-1)).getValue()))
00426           closestPoint = intItr;
00427         else if (fabs(value-(*intItr).getValue()) < fabs(value-(*(intItr-1)).getValue()) &&
00428                  fabs(value-(*intItr).getValue()) < fabs(value-(*(intItr+1)).getValue()))
00429           closestPoint = intItr;
00430       }
00431       return (*closestPoint).getNearestValue(values);      
00432       
00433     }else{
00434       
00435       vector<pair<double,double> >::iterator closestPoint;
00436       
00437       for (vector<pair<double,double> >::iterator vpdItr=m_pairs.begin();
00438            vpdItr!=m_pairs.end();++vpdItr){
00439         if (vpdItr==m_pairs.begin() && 
00440             fabs(value-(*vpdItr).first) < fabs(value-(*(vpdItr+1)).first))
00441           closestPoint = vpdItr;
00442         else if (vpdItr==m_pairs.end()-1 && 
00443                  fabs(value-(*vpdItr).first) < fabs(value-(*(vpdItr-1)).first))
00444           closestPoint = vpdItr;
00445         else if (fabs(value-(*vpdItr).first) < fabs(value-(*(vpdItr-1)).first) &&
00446                  fabs(value-(*vpdItr).first) < fabs(value-(*(vpdItr+1)).first))
00447           closestPoint = vpdItr;
00448       }
00449       return (*closestPoint).second;      
00450       
00451     }
00452   }

void Atlfast::Interpolator::dump (  ) 

Definition at line 45 of file Interpolator.cxx.

00045                          {
00046     if (m_interpolators.size()){
00047       vector<Interpolator>::iterator viitr = m_interpolators.begin();
00048       for (;viitr!=m_interpolators.end();++viitr){
00049         std::cout << "Value = " << (*viitr).getValue() << std::endl;
00050         (*viitr).dump();
00051       }
00052     }else{
00053       vector<pair<double,double> >::iterator vdpitr = m_pairs.begin();
00054       for (;vdpitr!=m_pairs.end();++vdpitr){
00055         std::cout << "Value = " << (*vdpitr).first << ", eff = " 
00056                   << (*vdpitr).second << std::endl;
00057       }
00058     }
00059   }

void Atlfast::Interpolator::Setup ( ifstream &  ,
int &  ,
int &  ,
vector< int > &  ,
int &   
) [private]

Definition at line 61 of file Interpolator.cxx.

00062                                                             {
00063     
00064     // This method can certainly be improved - possibly using XML
00065     // Setup parses the input file and decides to recursively create 
00066     // more Interpolators at each new dimension
00067     // At the lowest dimension, a vector of pairs of doubles is held
00068     // instead, each pair being a point-value pairing
00069     
00070     // Add a new entry in for each new level encountered
00071     if ( npoints.size() < static_cast<std::vector<int>::size_type>(level) ) npoints.push_back(0);
00072     
00073     while (!ifs.eof()){
00074       
00075       string read_line;
00076       double read_double;
00077       
00078       getline(ifs,read_line); nline++;
00079       istringstream iss(read_line);
00080       
00081       // count number of values in this line
00082       int numbercount = 0;
00083       while (iss >> read_double) ++numbercount;
00084 
00085       if (!numbercount){
00086 
00087         // No numbers on this line, two possibilities:
00088         // 1) It's a blank line, ignore it
00089         // 2) It's a list of level identifiers at the beginning 
00090         //    of the file, store these
00091 
00092         if (nline==1){ 
00093 
00094           // These are the level identifiers
00095           // No new Interpolators have been made yet so this is the main
00096           // Interpolator and can directly access m_levelnames
00097 
00098           string level_name;
00099           int nlevel = 0;
00100           iss.clear(); iss.str(read_line);
00101           while (iss >> level_name){
00102             nlevel++;
00103             m_levelnames[level_name] = nlevel; 
00104           }
00105         }
00106         
00107         continue;
00108       }
00109       
00110       // only one value - must be a point so need to make an Interpolator
00111       if (numbercount == 1){
00112         
00113         Interpolator w(read_double,ifs,level,jump,npoints,nline);
00114         m_interpolators.push_back(w);
00115         
00116         // Take care of moving down the appropriate number of levels
00117         if (jump){
00118           if (!npoints[level-1]) npoints[level-1] = m_interpolators.size();
00119           else if ( m_interpolators.size() != static_cast<std::vector<Interpolator>::size_type>(npoints[level-1]) ){
00120             string message("inconsistent number of points");
00121             exitParseWithMessage(message,nline,read_line);
00122           }
00123           --jump; --level;
00124           return;
00125         }
00126         
00127       }else{
00128 
00129         // More than one value in read line, must the lowest dimension, 
00130         // read in the points and values from both consecutive lines and
00131         // store as pairs of doubles
00132         
00133         iss.clear(); iss.str(read_line); // Go to beginning of string?
00134         string read_second_line;
00135         getline(ifs,read_second_line); nline++;
00136         istringstream iss2(read_second_line);
00137         double read_second_double;
00138         
00139         // Check to see if the number of points is consistent
00140         while (iss >> read_double){
00141           if (!(iss2 >> read_second_double)) 
00142             exitParseWithMessage("#points > #values, reorganise input file",
00143                             nline,read_second_line);
00144           pair<double,double> lowest_dim_value(read_double,read_second_double);
00145           m_pairs.push_back(lowest_dim_value);
00146         }
00147         if (iss2 >> read_second_double)
00148           exitParseWithMessage("#points < #values, reorganise input file",
00149                           --nline,read_line);
00150         if (!npoints[level-1]) npoints[level-1] = m_pairs.size();
00151         else if ( m_pairs.size() != static_cast<std::vector<pair<double,double> >::size_type>(npoints[level-1]) ){
00152           exitParseWithMessage("inconsistent number of points in lowest dimension",
00153                           --nline,read_line);
00154         }
00155 
00156         // Find number of dimensions to jump
00157         nDimensionsToJump(ifs,level,jump);
00158 
00159         return;
00160       }
00161 
00162     }// end of while (!ifs.eof())
00163 
00164    return;
00165   }

void Atlfast::Interpolator::findLimits ( deque< pair< double, double > > &   )  [private]

Definition at line 254 of file Interpolator.cxx.

00254                                                                         {
00255     
00256     // Get limits in this quantity first
00257     // The points are assumed to be in ascending numerical order
00258     pair<double,double> limits;
00259     
00260      limits.first = (m_interpolators.size()) ? 
00261        m_interpolators.front().getValue() :
00262        m_pairs.front().first;      
00263 
00264      //std::cout << "Lower limit = " << limits.first << std::endl;
00265 
00266      limits.second = (m_interpolators.size()) ?
00267        m_interpolators.back().getValue():
00268        m_pairs.back().first;
00269     
00270      //std::cout << "Higher limit = " << limits.second << std::endl;
00271 
00272      limits_deque.push_back(limits);
00273     
00274      // Now call for next dimension
00275      if (m_interpolators.size())
00276        m_interpolators.front().findLimits(limits_deque);
00277      
00278      return;
00279      
00280    }

void Atlfast::Interpolator::nDimensionsToJump ( ifstream &  ,
int &  ,
int &   
) [private]

Definition at line 282 of file Interpolator.cxx.

00282                                                                          {
00283 
00284     // How many dimensions to jump up?
00285     
00286     // Current position in file buffer, we're just looking ahead
00287     // so will reset to this position afterwards
00288     int position = ifs.tellg();
00289     
00290     int nsingleentries = 0;
00291     bool singleentry = true;
00292     
00293     // Count number of lines with just a single value
00294     while (singleentry && !ifs.eof()){
00295       
00296       string read_line;
00297       getline(ifs,read_line);
00298       istringstream iss(read_line);
00299       int numbercount = 0;
00300       double read_double;
00301       while (iss >> read_double) ++numbercount;
00302       if (!numbercount) continue;
00303       if (numbercount == 1) ++nsingleentries;
00304       else singleentry = false;
00305       
00306     }
00307     
00308     // If we've hit the end of the input file, jump up 
00309     // the total number of dimensions to finish off the
00310     // setup
00311     if (ifs.eof()) nsingleentries = level;
00312     
00313     --level;
00314     
00315     // Reset the buffer position
00316     ifs.seekg(position);
00317 
00318     // Record number of dimensions to jump up
00319     jump = nsingleentries - 1;
00320 
00321     return;
00322     
00323   }

bool Atlfast::Interpolator::inLimits ( deque< double >  ,
double &   
) [private]

Definition at line 325 of file Interpolator.cxx.

00325                                                               {
00326 
00327     // Make local copy of held point limits so we can safely
00328     // delete entries
00329     deque<double> values_copy = values;
00330     deque<pair<double,double> > limits = m_limits;
00331     deque<pair<double,double> > defaults = m_defaults;
00332     
00333     // Check each value is within the limits of a given dimension
00334     while (values.size()){
00335       if ( values.front() < limits.front().first ){
00336         def = m_contBounds ? getNearestValue(values_copy) : defaults.front().first;
00337         return false;
00338       }
00339       if ( values.front() > limits.front().second ){
00340         def = m_contBounds ? getNearestValue(values_copy) : defaults.front().second;
00341         return false;
00342       }
00343       values.pop_front();
00344       limits.pop_front();
00345       defaults.pop_front();
00346     }
00347     return true;
00348   }

void Atlfast::Interpolator::exitParseWithMessage ( string  ,
int  ,
string   
) [private]

Definition at line 454 of file Interpolator.cxx.

00454                                                                                {
00455     std::cout << "Exiting Interpolator, " << message << std::endl;
00456     std::cout << "Problem occurred at about line " << nline << " of input file:" << std::endl;
00457     std::cout << line << std::endl;
00458     exit(1);
00459   }


Member Data Documentation

vector<pair<double,double> > Atlfast::Interpolator::m_pairs [private]

Definition at line 75 of file Interpolator.h.

vector<Interpolator> Atlfast::Interpolator::m_interpolators [private]

Definition at line 76 of file Interpolator.h.

double Atlfast::Interpolator::m_value [private]

Definition at line 77 of file Interpolator.h.

deque<pair<double,double> > Atlfast::Interpolator::m_limits [private]

Definition at line 78 of file Interpolator.h.

deque<pair<double,double> > Atlfast::Interpolator::m_defaults [private]

Definition at line 79 of file Interpolator.h.

map<string,int> Atlfast::Interpolator::m_levelnames [private]

Definition at line 80 of file Interpolator.h.

bool Atlfast::Interpolator::m_contBounds [private]

Definition at line 81 of file Interpolator.h.


The documentation for this class was generated from the following files:
Generated on Fri Sep 21 13:00:21 2007 for AtlfastEvent by  doxygen 1.5.1