#include <Interpolator.h>
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< Interpolator > | m_interpolators |
double | m_value |
deque< pair< double, double > > | m_limits |
deque< pair< double, double > > | m_defaults |
map< string, int > | m_levelnames |
bool | m_contBounds |
Definition at line 55 of file Interpolator.h.
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] |
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] |
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] |
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 }
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.