LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiCubicSpline.h

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

Generated on Sat Apr 10 15:25:19 2010 for LTI-Lib by Doxygen 1.6.1