latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * This file is part of the LTI-Computer Vision Library (LTI-Lib) 00006 * 00007 * The LTI-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License (LGPL) 00009 * as published by the Free Software Foundation; either version 2.1 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * The LTI-Lib is distributed in the hope that it will be 00013 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00014 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with the LTI-Lib; see the file LICENSE. If 00019 * not, write to the Free Software Foundation, Inc., 59 Temple Place - 00020 * Suite 330, Boston, MA 02111-1307, USA. 00021 */ 00022 00023 00024 /*---------------------------------------------------------------- 00025 * project ....: LTI Digital Image/Signal Processing Library 00026 * file .......: ltiCubicSpline.h 00027 * authors ....: Ruediger Weiler 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 28.5.2001 00030 * revisions ..: $Id: ltiCubicSpline.h,v 1.11 2006/09/05 10:39:10 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_CUBICSPLINE_H_ 00034 #define _LTI_CUBICSPLINE_H_ 00035 00036 00037 #include "ltiPointList.h" 00038 #include "ltiVariablySpacedSamplesInterpolator.h" 00039 00040 namespace lti { 00041 /** 00042 * This functor implements a cubic spline interpolation 00043 * for tabulated functions. The input parameters are some 00044 * sampling points in a tpointList<double>. The requirements 00045 * of the input points are that they must be a kind of function. 00046 * Therefore this rule x(n) < x(n+1) is required for each n 00047 * and the list must consist of at least three points. 00048 * Furthermore the parameters consist of the derivatives at the 00049 * beginning (first point) and end of the function (last point). 00050 * If the parameter useNaturalDerivatives is \a true the derivatives 00051 * from the parameters are ignored and the algorithm calculates 00052 * the optimal derivatives at the beginning and end. 00053 * 00054 * The template T type corresponds to the coordinate types. Only the 00055 * float, double and int types are supported. 00056 */ 00057 template <class T> 00058 class cubicSpline : public variablySpacedSamplesInterpolator { 00059 public: 00060 // -------------------------------------------------- 00061 // cubicSpline::parameters 00062 // -------------------------------------------------- 00063 00064 /** 00065 * the parameters for the class cubicSpline 00066 */ 00067 class parameters : public variablySpacedSamplesInterpolator::parameters { 00068 public: 00069 /** 00070 * default constructor 00071 */ 00072 parameters() : variablySpacedSamplesInterpolator::parameters() { 00073 //TODO: Initialize your parameter values! 00074 // If you add more parameters manually, do not forget to do following: 00075 // 1. indicate in the default constructor the default values 00076 // 2. make sure that the copy member also copy your new parameters 00077 // 3. make sure that the read and write members also read and 00078 // write your parameters 00079 00080 //use the natural Condition is the default 00081 useNaturalDerivatives = true; 00082 00083 //the default derivative is 0 00084 derivativeAtLastPoint = double(0); 00085 derivativeAtFirstPoint = double(0); 00086 00087 samplingPoints.clear(); 00088 }; 00089 00090 /** 00091 * copy constructor 00092 * @param other the parameters object to be copied 00093 */ 00094 parameters(const parameters& other) 00095 : variablySpacedSamplesInterpolator::parameters() { 00096 copy(other); 00097 }; 00098 00099 /** 00100 * destructor 00101 */ 00102 ~parameters() { 00103 }; 00104 00105 /** 00106 * returns name of this type 00107 */ 00108 const char* getTypeName() const { 00109 return "cubicSpline::parameters"; 00110 }; 00111 00112 /** 00113 * copy the contents of a parameters object 00114 * @param other the parameters object to be copied 00115 * @return a reference to this parameters object 00116 */ 00117 parameters& copy(const parameters& other) { 00118 # ifndef _LTI_MSC_6 00119 // MS Visual C++ 6 is not able to compile this... 00120 variablySpacedSamplesInterpolator::parameters::copy(other); 00121 # else 00122 // ...so we have to use this workaround. 00123 // Conditional on that, copy may not be virtual. 00124 variablySpacedSamplesInterpolator::parameters& (variablySpacedSamplesInterpolator::parameters::* p_copy) 00125 (const variablySpacedSamplesInterpolator::parameters&) = 00126 variablySpacedSamplesInterpolator::parameters::copy; 00127 (this->*p_copy)(other); 00128 # endif 00129 00130 00131 derivativeAtLastPoint = other.derivativeAtLastPoint; 00132 derivativeAtFirstPoint = other.derivativeAtFirstPoint; 00133 samplingPoints = other.samplingPoints; 00134 useNaturalDerivatives = other.useNaturalDerivatives; 00135 00136 return *this; 00137 }; 00138 00139 /** 00140 * copy the contents of a parameters object 00141 * @param other the parameters object to be copied 00142 * @return a reference to this parameters object 00143 */ 00144 parameters& operator=(const parameters& other) { 00145 return copy(other); 00146 }; 00147 00148 /** 00149 * returns a pointer to a clone of the parameters 00150 */ 00151 virtual functor::parameters* clone() const { 00152 return new parameters(*this); 00153 }; 00154 00155 # ifndef _LTI_MSC_6 00156 /** 00157 * write the parameters in the given ioHandler 00158 * @param handler the ioHandler to be used 00159 * @param complete if true (the default) the enclosing begin/end will 00160 * be also written, otherwise only the data block will be written. 00161 * @return true if write was successful 00162 */ 00163 bool write(ioHandler& handler, const bool complete=true) const 00164 # else 00165 bool writeMS(ioHandler& handler, const bool complete=true) const 00166 # endif 00167 { 00168 bool b = true; 00169 if (complete) { 00170 b = handler.writeBegin(); 00171 } 00172 00173 if (b) { 00174 00175 lti::write(handler,"useNaturalDerivatives",useNaturalDerivatives); 00176 lti::write(handler,"derivativeAtLastPoint",derivativeAtLastPoint); 00177 lti::write(handler,"derivativeAtFirstPoint",derivativeAtFirstPoint); 00178 lti::write(handler,"samplingPoints",samplingPoints); 00179 } 00180 00181 # ifndef _LTI_MSC_6 00182 // This is the standard C++ code, which MS Visual C++ 6 is not able to 00183 // compile... 00184 b = b && variablySpacedSamplesInterpolator::parameters::write(handler,false); 00185 # else 00186 bool 00187 (variablySpacedSamplesInterpolator::parameters::* p_writeMS)(ioHandler&,const bool) const = 00188 variablySpacedSamplesInterpolator::parameters::writeMS; 00189 b = b && (this->*p_writeMS)(handler,false); 00190 # endif 00191 00192 if (complete) { 00193 b = b && handler.writeEnd(); 00194 } 00195 00196 return b; 00197 } 00198 00199 # ifdef _LTI_MSC_6 00200 /** 00201 * write the parameters in the given ioHandler 00202 * @param handler the ioHandler to be used 00203 * @param complete if true (the default) the enclosing begin/end will 00204 * be also written, otherwise only the data block will be written. 00205 * @return true if write was successful 00206 */ 00207 bool write(ioHandler& handler, const bool complete=true) const { 00208 // ...we need this workaround to cope with another really 00209 // awful MSVC bug. 00210 return writeMS(handler,complete); 00211 } 00212 # endif 00213 00214 /** 00215 * read the parameters from the given ioHandler 00216 * @param handler the ioHandler to be used 00217 * @param complete if true (the default) the enclosing begin/end will 00218 * be also read, otherwise only the data block will be read. 00219 * @return true if write was successful 00220 */ 00221 # ifndef _LTI_MSC_6 00222 bool read(ioHandler& handler, const bool complete=true) 00223 # else 00224 /** 00225 * this function is required by MSVC only, as a workaround for a 00226 * very awful bug, which exists since MSVC V.4.0, and still by 00227 * V.6.0 with all bugfixes (so called "service packs") remains 00228 * there... This method is also public due to another bug, so please 00229 * NEVER EVER call this method directly: use read() instead 00230 */ 00231 bool readMS(ioHandler& handler, const bool complete=true) 00232 # endif 00233 { 00234 bool b = true; 00235 if (complete) { 00236 b = handler.readBegin(); 00237 } 00238 00239 if (b) { 00240 00241 lti::read(handler,"useNaturalDerivatives",useNaturalDerivatives); 00242 lti::read(handler,"derivativeAtLastPoint",derivativeAtLastPoint); 00243 lti::read(handler,"derivativeAtFirstPoint",derivativeAtFirstPoint); 00244 lti::read(handler,"samplingPoints",samplingPoints); 00245 } 00246 00247 # ifndef _LTI_MSC_6 00248 // This is the standard C++ code, which MS Visual C++ 6 is not able to 00249 // compile... 00250 b = b && variablySpacedSamplesInterpolator::parameters::read(handler,false); 00251 # else 00252 bool (variablySpacedSamplesInterpolator::parameters::* p_readMS)(ioHandler&,const bool) = 00253 variablySpacedSamplesInterpolator::parameters::readMS; 00254 b = b && (this->*p_readMS)(handler,false); 00255 # endif 00256 00257 if (complete) { 00258 b = b && handler.readEnd(); 00259 } 00260 00261 return b; 00262 } 00263 00264 # ifdef _LTI_MSC_6 00265 /** 00266 * read the parameters from the given ioHandler 00267 * @param handler the ioHandler to be used 00268 * @param complete if true (the default) the enclosing begin/end will 00269 * be also read, otherwise only the data block will be read. 00270 * @return true if write was successful 00271 */ 00272 bool read(ioHandler& handler, const bool complete) { 00273 // ...we need this workaround to cope with another really awful MSVC 00274 // bug. 00275 return readMS(handler,complete); 00276 } 00277 # endif 00278 00279 // ------------------------------------------------ 00280 // the parameters 00281 // ------------------------------------------------ 00282 00283 //TODO: comment the parameters of your functor 00284 // If you add more parameters manually, do not forget to do following: 00285 // 1. indicate in the default constructor the default values 00286 // 2. make sure that the copy member also copy your new parameters 00287 // 3. make sure that the read and write members also read and 00288 // write your parameters 00289 00290 /** 00291 * This boolean controls if the algorithm uses the derivative 00292 * values given within the parameters object (false), or if the functor 00293 * should calculate the optimal derivatives (true). 00294 * Default value: true 00295 */ 00296 bool useNaturalDerivatives; 00297 00298 /** 00299 * This parameter saves the derivative at the begin of the function. 00300 * If the spline should start horizontal the parameter 00301 * has to be zero. If the parameter useNaturalDerivatives 00302 * is true this value has no effect. 00303 * Default value: 0.0 00304 */ 00305 double derivativeAtFirstPoint; 00306 00307 /** 00308 * This parameter saves the derivative at the end of the function. 00309 * If the spline should end horizontal the parameter 00310 * has to be zero. If the parameter useNaturalDerivatives 00311 * is true this value has no effect. 00312 * Default value: 0.0 00313 */ 00314 double derivativeAtLastPoint; 00315 00316 /** 00317 * This is the list of the sampling points. 00318 * Every x-value must be unique in this tpointList<T> 00319 * and the list must consist of at least three points, or the 00320 * apply method will fail 00321 * Default value: empty list! 00322 */ 00323 tpointList<T> samplingPoints; 00324 }; 00325 00326 /** 00327 * default constructor 00328 */ 00329 cubicSpline(); 00330 00331 /** 00332 * copy constructor 00333 * @param other the object to be copied 00334 */ 00335 cubicSpline(const cubicSpline& other); 00336 00337 /** 00338 * destructor 00339 */ 00340 virtual ~cubicSpline(); 00341 00342 /** 00343 * returns the name of this type ("cubicSpline") 00344 */ 00345 virtual const char* getTypeName() const; 00346 00347 /** 00348 * operates on the given %parameter. 00349 * @param srcdest tpointList<double> with the source data in the 00350 * x part of the tpoints. The result for every x value is writen 00351 * in the y part of the same tpoint. 00352 * @return true if apply successful or false otherwise. 00353 */ 00354 bool apply(tpointList<T>& srcdest) const; 00355 00356 /** 00357 * operates on a copy of the given %parameters. 00358 * @param x double with the source data. 00359 * @param fx double where the result will be left. 00360 * @return true if apply successful or false otherwise. 00361 */ 00362 bool apply(const T& x,T& fx) const; 00363 00364 /** 00365 * copy data of "other" functor. 00366 * @param other the functor to be copied 00367 * @return a reference to this functor object 00368 */ 00369 cubicSpline& copy(const cubicSpline& other); 00370 00371 /** 00372 * returns a pointer to a clone of this functor. 00373 */ 00374 virtual functor* clone() const; 00375 00376 /** 00377 * returns used parameters 00378 */ 00379 const parameters& getParameters() const; 00380 00381 /** 00382 * sets the functor's parameters. 00383 */ 00384 virtual bool updateParameters(); 00385 00386 protected: 00387 /** 00388 * This vector saves the second derivatives at each point 00389 * of the sampling points. 00390 */ 00391 std::vector<double> secondDerivatives; 00392 00393 /** 00394 * This function calcualtes the second derivatives at each point of 00395 * the tpointList<double> &in. 00396 * @param in the point list with the source data 00397 * @param yp1 the first derivative an the first point of the tpointlist 00398 * @param ypn the first derivative an the last point of the tpointlist 00399 * @param natural if true constructs a natural spline 00400 */ 00401 void spline(const tpointList<T>& in, 00402 const double& yp1, 00403 const double& ypn, 00404 const bool& natural); 00405 00406 /** 00407 * This function evaluate the spline at one x value. 00408 * @param function list of points to be interpolated 00409 * @param x the value where the spline is evaluated 00410 * @param y the return value 00411 * @return true if successful, false otherwise 00412 */ 00413 bool splint(const tpointList<T> &function, 00414 const T& x, T& y) const; 00415 }; 00416 } 00417 00418 #endif