A utility class for functions. More...
#include <util/function.h>
Public Member Functions | |
bool | error () |
Function (const Function ©) | |
Function (std::string filename) | |
Constructor with initialisation from file. | |
Function () | |
Default constructor. | |
const util::Vector< 2, double > & | getMax () const |
Return the maximum x and y values. | |
const util::Vector< 2, double > & | getMin () const |
Return the minimum x and y values. | |
void | normalizeX (bool shift=true) |
Make sure the x axis spans from 0 to 1. | |
void | normalizeY (bool shift=true) |
Make sure the y axis spans from 0 to 1. | |
double | operator() (double x) |
Function operator. | |
Function & | operator= (const Function &) |
Copy constructor. | |
void | reread () |
Method to be implemented in subblasses to reread the file. | |
double | scaleX () const |
Get the current x scaling. | |
void | scaleX (double s) |
Scale the x axis by s. | |
double | scaleY () const |
Get the current y scaling. | |
void | scaleY (double s) |
Scale the y axis by s. | |
void | setSamples (size_t n) |
sets the number of samples to be used | |
double | shiftX () const |
Get the current x axis shift. | |
void | shiftX (double s) |
Shift the x axis by s. | |
double | shiftY () const |
Get the current y axis shift. | |
void | shiftY (double s) |
Shift the y axis by s. |
A utility class for functions.
This class is a function object that encapsulates functions in the VLAB function formats (original and fver 1 1).
Definition at line 24 of file function.h.
util::Function::Function | ( | ) |
Default constructor.
Definition at line 33 of file function.cpp.
util::Function::Function | ( | std::string | filename | ) |
Constructor with initialisation from file.
filename | The function file to load. |
Definition at line 52 of file function.cpp.
References reread().
00053 : FileObject(filename) 00054 , pts() 00055 , max() 00056 , min() 00057 , scaling_x(1) 00058 , scaling_y(1) 00059 , shift_x(0) 00060 , shift_y(0) 00061 { 00062 init(); 00063 reread(); 00064 }
const Vector< 2, double > & util::Function::getMax | ( | ) | const |
Return the maximum x and y values.
Definition at line 488 of file function.cpp.
const Vector< 2, double > & util::Function::getMin | ( | ) | const |
Return the minimum x and y values.
Definition at line 493 of file function.cpp.
void util::Function::normalizeX | ( | bool | shift = true |
) |
Make sure the x axis spans from 0 to 1.
shift | If true, it will also change the shift of the axis |
Definition at line 334 of file function.cpp.
References util::Vector< dim, T >::x().
void util::Function::normalizeY | ( | bool | shift = true |
) |
Make sure the y axis spans from 0 to 1.
shift | If true, it will also change the shift of the axis |
Definition at line 351 of file function.cpp.
References util::Vector< dim, T >::x().
00352 { 00353 double ymin = HUGE_VAL, ymax = -HUGE_VAL; 00354 double dx = (max.x() - min.x()) / samples; 00355 double x0 = min.x(); 00356 if (! cache_valid) { 00357 cache_valid = true; 00358 cache.resize (samples+1); 00359 for (size_t i = 0 ; i < samples ; i ++) 00360 cache[i].valid = false; 00361 } 00362 for(size_t i = 0 ; i < samples+1 ; ++i) 00363 { 00364 double y; 00365 if(cache[i].valid) 00366 { 00367 y = cache[i].val; 00368 } 00369 else 00370 { 00371 y = getVal(x0+dx*i); 00372 cache[i].valid = true; 00373 cache[i].val = y; 00374 } 00375 if(y < ymin) ymin = y; 00376 if(y > ymax) ymax = y; 00377 } 00378 if(shift) 00379 { 00380 shift_y = -ymin; 00381 if(ymax > ymin) 00382 scaling_y = 1/(ymax-ymin); 00383 else 00384 scaling_y = 1; 00385 } 00386 else 00387 { 00388 if(ymax != 0) 00389 { 00390 scaling_y = 1/ymax; 00391 } 00392 else 00393 { 00394 scaling_y = 1; 00395 } 00396 } 00397 }
double util::Function::operator() | ( | double | x | ) |
Function operator.
x | The position in the function. |
This returns the y-value of the function for a given x-value. If x is outside the domain of the function, the value of the function start or end point is returned. Dynamic caching is used to speed things up. Basically, the function is only evaluated at a number of places (specified in 'samples'), and otherwise the values are linearly interpolated inbetween. The real values are obtained by calling getVal ().
Definition at line 295 of file function.cpp.
References util::Vector< dim, T >::x().
00295 { 00296 x += shift_x; 00297 x *= scaling_x; 00298 if (x <= min.x()) return scaling_y*pts[0].y() + shift_y; 00299 if (x >= max.x()) return scaling_y*pts[pts.size() - 1].y() + shift_y; 00300 00301 // check for cache 00302 if (! cache_valid) { 00303 cache_valid = true; 00304 cache.resize (samples+1); 00305 for (size_t i = 0 ; i < samples ; i ++) 00306 cache[i].valid = false; 00307 } 00308 // lower index 00309 double dx = (max.x() - min.x()) / samples; 00310 size_t lo = (size_t) ((x - min.x()) / dx); 00311 size_t hi = lo + 1; 00312 // make sure we have both lo and hi 00313 double lox = min.x() + dx * lo; 00314 double hix = lox + dx; 00315 if (! cache [lo].valid) { 00316 cache [lo].valid = true; 00317 cache [lo].val = getVal (lox); 00318 } 00319 if (! cache [hi].valid) { 00320 cache [hi].valid = true; 00321 cache [hi].val = getVal (hix); 00322 } 00323 // linearly interpolate 00324 double r = (x - lox) / dx; 00325 double ret = (1-r) * cache[lo].val + r * cache[hi].val; 00326 00327 return scaling_y*ret + shift_y; 00328 }
Copy constructor.
Definition at line 83 of file function.cpp.
00083 { 00084 FileObject::operator=(f); 00085 pts = f.pts; 00086 max = f.max; 00087 min = f.min; 00088 samples = f.samples; 00089 cache_valid = f.cache_valid; 00090 cache = f.cache; 00091 error_occured = f.error_occured; 00092 scaling_x = f.scaling_x; 00093 scaling_y = f.scaling_y; 00094 shift_x = f.shift_x; 00095 shift_y = f.shift_y; 00096 return *this; 00097 }
void util::Function::reread | ( | ) | [virtual] |
Method to be implemented in subblasses to reread the file.
Implements util::FileObject.
Definition at line 103 of file function.cpp.
References QFile::close(), QString::contains(), QString::fromStdString(), QFile::handle(), QFile::open(), QString::split(), QString::startsWith(), util::Vector< dim, T >::x(), and util::Vector< dim, T >::y().
Referenced by Function().
00103 { 00104 QFile f(QString::fromStdString(filename)); 00105 error_occured = false; 00106 if(!f.open(QIODevice::ReadOnly)) 00107 { 00108 error_occured = true; 00109 err << "Error opening file " << QString::fromStdString(filename) << ": " << f.errorString() << endl; 00110 return; 00111 } 00112 #if defined(__APPLE__) || defined(linux) 00113 flock(f.handle(), LOCK_SH); 00114 #endif 00115 QTextStream ts(&f); 00116 int ptid = 0, line_nb = 0; 00117 00118 max = Vector<2,double>(-HUGE_VAL,-HUGE_VAL); 00119 min = Vector<2,double>(HUGE_VAL,HUGE_VAL); 00120 00121 while(!ts.atEnd()) 00122 { 00123 QString line = ts.readLine().trimmed(); 00124 line_nb++; 00125 if(line.startsWith("fver")) 00126 { 00127 QStringList fields = line.split(" "); 00128 if(fields.size() != 3) 00129 { 00130 REPORT_ERROR(filename, line_nb, "cannot find major and minor in function version (fver)"); 00131 return; 00132 } 00133 bool ok; 00134 int major = fields[1].toInt(&ok); 00135 if(!ok) 00136 { 00137 REPORT_ERROR(filename, line_nb, "major version number (" << fields[1] << ") is not a valid integer"); 00138 return; 00139 } 00140 int minor = fields[2].toInt(&ok); 00141 if(!ok) 00142 { 00143 REPORT_ERROR(filename, line_nb, "minor version number (" << fields[2] << ") is not a valid integer"); 00144 return; 00145 } 00146 if(major != 1 or minor != 1) 00147 { 00148 err << "Warning, this version usually deals with fver 1 1. Processing will continue but may fail" << endl; 00149 } 00150 } 00151 else if(line.startsWith("points:")) 00152 { 00153 QStringList fields = line.split(":"); 00154 if(fields.size() != 2) 00155 { 00156 REPORT_ERROR(filename, line_nb, "Invalid point number specification, there is more than one ':'"); 00157 return; 00158 } 00159 bool ok; 00160 unsigned int nbpts = fields[1].toUInt(&ok); 00161 if(!ok) 00162 { 00163 REPORT_ERROR(filename, line_nb, "Number of points (" << fields[1] << ") is not a valid integer"); 00164 return; 00165 } 00166 pts.resize(nbpts); 00167 } 00168 else if(!line.contains(":")) // specification of a points 00169 { 00170 if(ptid >= (int)pts.size()) 00171 { 00172 REPORT_ERROR(filename, line_nb, "There are more points than specified"); 00173 return; 00174 } 00175 QStringList coords = line.split(" "); 00176 if(coords.size() != 2) 00177 { 00178 REPORT_ERROR(filename, line_nb, "There are " << coords.size() << " coordinates instead of 2"); 00179 return; 00180 } 00181 double x, y; 00182 bool ok; 00183 x = coords[0].toDouble(&ok); 00184 if(!ok) 00185 { 00186 REPORT_ERROR(filename, line_nb, coords[0] << "' is not a valid double"); 00187 return; 00188 } 00189 y = coords[1].toDouble(&ok); 00190 if(!ok) 00191 { 00192 REPORT_ERROR(filename, line_nb, coords[1] << "' is not a valid double"); 00193 return; 00194 } 00195 if(x < min.x()) min.x() = x; 00196 if(y < min.y()) min.y() = y; 00197 if(x > max.x()) max.x() = x; 00198 if(y > max.y()) max.y() = y; 00199 Vector<2,double> p(x, y); 00200 pts[ptid++] = p; 00201 } 00202 // Otherwise, just ignore the line 00203 } 00204 if(ptid != (int)pts.size()) 00205 { 00206 error_occured = true; 00207 err << "Error in file " << QString::fromStdString(filename) 00208 << ", there was " << pts.size() << " points announced, but only " << ptid << " points declared" << endl; 00209 return; 00210 } 00211 00212 cache_valid = false; 00213 #if defined(__APPLE__) || defined(linux) 00214 flock(f.handle(), LOCK_UN); 00215 #endif 00216 f.close(); 00217 // ifstream in(filename.c_str()); 00218 // string buffer; 00219 00220 // if (!in || !in.good() || in.eof()) { 00221 // error_occured = true; 00222 // std::cerr << "Function - Cannot open file '" << filename << "'\n"; 00223 // return; 00224 // } 00225 // error_occured = false; 00226 00227 // in >> ws >> buffer; 00228 00229 // if (buffer == string("range:")) { 00230 // // old version 00231 00232 // double rmin, rmax; 00233 // in >> rmin >> rmax; 00234 // } 00235 // else if (buffer == string("fver")) { 00236 // int major, minor; 00237 // in >> major >> minor >> ws; 00238 00239 // if (major == 1 && minor == 1) { 00240 // getline(in, buffer); // name 00241 // getline(in, buffer); // samples 00242 // getline(in, buffer); // flip 00243 // } 00244 // } 00245 00246 // unsigned int num; 00247 // in >> buffer >> num; 00248 00249 // pts.reserve(num); 00250 00251 // bool first = true; 00252 // for (unsigned int i = 0; i < num; i++) { 00253 // double x, y; 00254 // in >> x >> y; 00255 00256 // if (first) { 00257 // max.set(x, y); 00258 // min.set(x, y); 00259 // first = false; 00260 // } 00261 // else { 00262 // if (x > max.x()) max.x(x); 00263 // if (y > max.y()) max.y(y); 00264 // if (x < min.x()) min.x(x); 00265 // if (y < min.y()) min.y(y); 00266 // } 00267 00268 // Vector<2,double> p(x, y); 00269 // pts.push_back(p); 00270 // } 00271 00272 // cache_valid = false; 00273 }
double util::Function::scaleX | ( | ) | const [inline] |
void util::Function::scaleX | ( | double | s | ) | [inline] |
Scale the x axis by s.
s | Scaling factor to apply to the axis |
Definition at line 44 of file function.h.
double util::Function::scaleY | ( | ) | const [inline] |
void util::Function::scaleY | ( | double | s | ) | [inline] |
Scale the y axis by s.
s | Scaling factor to apply to the axis |
Definition at line 49 of file function.h.
void util::Function::setSamples | ( | size_t | n | ) |
sets the number of samples to be used
n | The number of samples to use |
This sets the new number of samples and invalidates the cache.
Definition at line 280 of file function.cpp.
double util::Function::shiftX | ( | ) | const [inline] |
void util::Function::shiftX | ( | double | s | ) | [inline] |
Shift the x axis by s.
s | Shift of the axis |
Note that the shift happens after the scaling, so it should be written in the scaled reference system.
Definition at line 61 of file function.h.
double util::Function::shiftY | ( | ) | const [inline] |
void util::Function::shiftY | ( | double | s | ) | [inline] |
Shift the y axis by s.
s | Shift of the axis |
Note that the shift happens after the scaling, so it should be written in the scaled reference system.
Definition at line 69 of file function.h.