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

ltiFunctionGenerator.h

00001 /*
00002  * Copyright (C) 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-Lib: Image Processing and Computer Vision Library
00026  * file .......: ltiMathFunction.h
00027  * authors ....: Lars Libuda
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 2.11.2004
00030  * revisions ..: $Id: ltiFunctionGenerator.h,v 1.4 2006/02/08 12:22:40 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_FUNCTION_GENERATOR_H_
00034 #define _LTI_FUNCTION_GENERATOR_H_
00035 
00036 #include "ltiMathFunction.h"
00037 #include "ltiMath.h"
00038 #include <string>
00039 
00040 namespace lti {
00041   /**
00042    *  functionGenerator parses input strings representing mathematical functions
00043    *  of the type \f$f(x)\f$ and \f$f(x,y)\f$. These strings are converted into a tree
00044    *  structure which allows the retrieval of the functions' result for passed arguments.
00045    *  The calculation is performed in the apply-methods.
00046    *  The string is set in the parameters of this class like in this example:
00047    *  \code
00048    *  #include "ltiFunctionGenerator.h"
00049    *
00050    *  lti::functionGenerator             function;
00051    *  lti::functionGenerator::parameters params;
00052    *  params.function = "(x-1)*cos(y)/x^2+1.234";
00053    *  if (!function.setParameters(params)) {
00054    *    // something went wrong during parsing, get the error message
00055    *    std::cout << function.getStatusString();
00056    *  }
00057    *  else {
00058    *    // calculate the result for two arguments
00059    *    double result;
00060    *    if (!function.apply(2.5,3.1,result)) {
00061    *      std::cout << "Function is not defined for given arguments";
00062    *    }
00063    *  }
00064    *  \endcode
00065    *
00066    *  Conventions for string input:
00067    *  -# The string is case insensitive
00068    *  -# Numerical constants consists of decimal digits (0-9) and the period (.)
00069    *  -# Two numerical constants are defined as literals: 'pi' and 'e'
00070    *  -# The names for the variables holding the arguments are 'x' and 'y' by default.
00071    *     These names can be changed in the parameters.
00072    *  -# Parenthesis are allowed in any desired depth
00073    *  -# Allowed operators: '+','-','*','/','^'
00074    *  -# Allowed functions: 
00075    *         - sin()    -> sine 
00076    *         - cos()    -> cosine 
00077    *         - tan()    -> tangent
00078    *         - cot()    -> cotangent
00079    *         - sec()    -> secant
00080    *         - csc()    -> cosecant
00081    *         - arcsin() -> arc sine 
00082    *         - arccos() -> arc cosine 
00083    *         - arctan() -> arc tangent
00084    *         - arccot() -> arc cotangent
00085    *         - sinh()   -> hyperbolic sine
00086    *         - cosh()   -> hyperbolic cosine
00087    *         - tanh()   -> hyperbolic tangent
00088    *         - coth()   -> hyperbolic cotangent
00089    *         - arsinh() -> hyperbolic area sine
00090    *         - arcosh() -> hyperbolic area cosine 
00091    *         - artanh() -> hyperbolic area tangent
00092    *         - arcoth() -> hyperbolic area cotangent
00093    *         - ln()     -> logarithm base e
00094    *         - lg()     -> logarithm base 10
00095    *         - ld()     -> logarithm base 2
00096    *         - sqrt()   -> Square root
00097    *         - abs()    -> absolute value
00098    *         - sgn()    -> sign function
00099    *         - int()    -> greatest integer smaller the argument (Gaussian parenthesis)
00100    */
00101   class functionGenerator : public mathFunction {
00102   public:
00103     /**
00104      * The parameters for the class functionGenerator
00105      */
00106     class parameters : public mathFunction::parameters {
00107     public:
00108       /**
00109        * Default constructor
00110        */
00111       parameters();
00112 
00113       /**
00114        * Copy constructor
00115        * @param other the parameters object to be copied
00116        */
00117       parameters(const parameters& other);
00118 
00119       /**
00120        * Destructor
00121        */
00122       ~parameters();
00123 
00124       /**
00125        * Returns name of this type
00126        */
00127       const char* getTypeName() const;
00128 
00129       /**
00130        * Copy the contents of a parameters object
00131        * @param other the parameters object to be copied
00132        * @return a reference to this parameters object
00133        */
00134       parameters& copy(const parameters& other);
00135 
00136       /**
00137        * Copy the contents of a parameters object
00138        * @param other the parameters object to be copied
00139        * @return a reference to this parameters object
00140        */
00141       parameters& operator=(const parameters& other);
00142 
00143 
00144       /**
00145        * Returns a pointer to a clone of the parameters
00146        */
00147       virtual functor::parameters* clone() const;
00148 
00149       /**
00150        * Write the parameters in the given ioHandler
00151        * @param handler the ioHandler to be used
00152        * @param complete if true (the default) the enclosing begin/end will
00153        *        be also written, otherwise only the data block will be written.
00154        * @return true if write was successful
00155        */
00156       virtual bool write(ioHandler& handler,const bool complete=true) const;
00157 
00158       /**
00159        * Read the parameters from the given ioHandler
00160        * @param handler the ioHandler to be used
00161        * @param complete if true (the default) the enclosing begin/end will
00162        *        be also written, otherwise only the data block will be written.
00163        * @return true if write was successful
00164        */
00165       virtual bool read(ioHandler& handler,const bool complete=true);
00166 
00167 #     ifdef _LTI_MSC_6
00168       /**
00169        * This function is required by MSVC only, as a workaround for a
00170        * very awful bug, which exists since MSVC V.4.0, and still by
00171        * V.6.0 with all bugfixes (so called "service packs") remains
00172        * there...  This method is also public due to another bug, so please
00173        * NEVER EVER call this method directly: use read() instead
00174        */
00175       bool readMS(ioHandler& handler,const bool complete=true);
00176 
00177       /**
00178        * This function is required by MSVC only, as a workaround for a
00179        * very awful bug, which exists since MSVC V.4.0, and still by
00180        * V.6.0 with all bugfixes (so called "service packs") remains
00181        * there...  This method is also public due to another bug, so please
00182        * NEVER EVER call this method directly: use write() instead
00183        */
00184       bool writeMS(ioHandler& handler,const bool complete=true) const;
00185 #     endif
00186 
00187       // ------------------------------------------------
00188       // the parameters
00189       // ------------------------------------------------
00190       /**
00191        * string containing the function to evaluate
00192        */
00193       std::string function;
00194       /**
00195        * Name of the first argument. Default is 'x'.
00196        * Do not change if it is not necessary. If a name is chosen which
00197        * is already reserved for function names, operators,or literals the
00198        * behaviour is unpredictable.
00199        */
00200       std::string nameVarX;
00201       /**
00202        * Name of the second argument. Default is 'y'.
00203        * Do not change if it is not necessary. If a name is chosen which
00204        * is already reserved for function names, operators,or literals the
00205        * behaviour is unpredictable.
00206        */
00207       std::string nameVarY;
00208     };
00209 
00210     /**
00211      * Default constructor
00212      */
00213     functionGenerator();
00214 
00215     /**
00216      * Construct a functor using the given parameters
00217      */
00218     functionGenerator(const parameters& par);
00219 
00220     /**
00221      * Copy constructor
00222      * @param other the object to be copied
00223      */
00224     functionGenerator(const functionGenerator& other);
00225 
00226     /**
00227      * Destructor
00228      */
00229     virtual ~functionGenerator();
00230 
00231     /**
00232      * Returns the name of this type ("functionGenerator")
00233      */
00234     virtual const char* getTypeName() const;
00235 
00236     /**
00237      * Updates the internal state after parameter change. Here, the function string
00238      * is parsed and the tree is build.
00239      * @return true, if the tree was successfully build.
00240      */
00241     virtual bool updateParameters();
00242    
00243     /**
00244      * operates on a copy of the given %parameters.
00245      * @param x first argument
00246      * @param y second argument
00247      * @param result result of evaluation. 1.0 in case of errors
00248      * @return true if the function is defined for the given arguments
00249      */
00250     bool apply(const double& x,const double& y,double& result) const;
00251 
00252     /**
00253      * operates on a copy of the given %parameters.
00254      * @param x argument
00255      * @param result result of evaluation. 1.0 in case of errors
00256      * @return true if the function is defined for the given argument
00257      */
00258     bool apply(const double& x,double& result) const;
00259 
00260     /**
00261      * Copy data of "other" functor.
00262      * @param other the functor to be copied
00263      * @return a reference to this functor object
00264      */
00265     functionGenerator& copy(const functionGenerator& other);
00266 
00267     /**
00268      * Alias for copy member
00269      * @param other the functor to be copied
00270      * @return a reference to this functor object
00271      */
00272     functionGenerator& operator=(const functionGenerator& other);
00273 
00274     /**
00275      * Returns a pointer to a clone of this functor.
00276      */
00277     virtual functor* clone() const;
00278 
00279     /**
00280      * Returns used parameters
00281      */
00282     const parameters& getParameters() const;
00283 
00284 # ifdef _LTI_MSC_6
00285   public:
00286 # else            
00287   private:
00288 # endif      
00289     class node {
00290       protected:
00291         node *pRight, *pLeft;
00292         static bool bMathError;
00293 
00294       public:
00295         node(node *pl = NULL, node *pr = NULL);
00296 
00297         virtual ~node();
00298 
00299         node *getRightChild() {
00300           return pRight;
00301         }
00302 
00303         node *getLeftChild() {
00304           return pLeft;
00305         }
00306 
00307         void setLeftChild(node *p = NULL) {
00308           pLeft = p;
00309         }
00310 
00311         void setRightChild(node *p = NULL) {
00312           pRight = p;
00313         }
00314 
00315         int isLeaf() {
00316           return (pLeft == NULL && pRight == NULL);
00317         }
00318 
00319         virtual double calculate(const double& x, const double& y) = 0;
00320 
00321         static bool error();
00322 
00323     };
00324 
00325     class nodeAdd : public node {
00326       public:
00327         nodeAdd(node *l,node *r) : node(l,r) {
00328         }
00329 
00330         virtual double calculate(const double& x, const double& y) {
00331           return getLeftChild()->calculate(x,y) + getRightChild()->calculate(x,y);
00332         }
00333     };
00334 
00335     class nodeSub : public node {
00336       public:
00337         nodeSub(node *l,node *r) : node(l,r) {
00338         }
00339 
00340         virtual double calculate(const double& x, const double& y) {
00341           return getLeftChild()->calculate(x,y) - getRightChild()->calculate(x,y);
00342         }
00343     };
00344 
00345     class nodeMul : public node {
00346       public:
00347         nodeMul(node *l,node *r) : node(l,r) {
00348         }
00349 
00350         virtual double calculate(const double& x, const double& y) {
00351           return getLeftChild()->calculate(x,y) * getRightChild()->calculate(x,y);
00352         }
00353     };
00354 
00355     class nodeDiv : public node {
00356       public:
00357         nodeDiv(node *l,node *r);
00358         virtual double calculate(const double& x, const double& y);
00359     };
00360 
00361     class nodePow : public node {
00362       public:
00363         nodePow(node *l, node *r);
00364         virtual double calculate(const double& x, const double& y);
00365     };
00366 
00367     class nodeConst : public node {
00368       private:
00369         double dValue;
00370 
00371       public:
00372         nodeConst(double dConst) : node(NULL,NULL),dValue(dConst) {
00373         }
00374 
00375         virtual double calculate(const double& x, const double& y) {
00376           return dValue;
00377         }
00378     };
00379 
00380     class nodeVarX : public node {
00381       public:
00382         nodeVarX() : node(NULL,NULL) {
00383         }
00384 
00385         virtual double calculate(const double& x, const double& y) {
00386           return x;
00387         }
00388     };
00389 
00390     class nodeVarY : public node {
00391       public:
00392         nodeVarY() : node(NULL,NULL) {
00393         }
00394 
00395         virtual double calculate(const double& x, const double& y) {
00396           return y;
00397         }
00398     };
00399 
00400     class nodeFunc : public node {
00401 # ifdef _LTI_MSC_6
00402       public:
00403 # else            
00404       private:
00405 # endif      
00406         typedef double (*tMathFunc) (double);
00407 
00408         static tMathFunc pFuncs[]; 
00409         int iFunc;
00410 
00411       public:
00412         nodeFunc(node *pNode, int iFuncNr);
00413         virtual double calculate(const double& x, const double& y);
00414         static double Pow(double x,double y);
00415 
00416       private:
00417         static double Sin(double x);
00418         static double Cos(double x);
00419         static double Tan(double x);
00420         static double Cot(double x);
00421         static double Sec(double x);
00422         static double Cosec(double x);
00423         static double Arcsin(double x);
00424         static double Arccos(double x);
00425         static double Arctan(double x);
00426         static double Arccot(double x);
00427         static double Sinh(double x);
00428         static double Cosh(double x);
00429         static double Tanh(double x);
00430         static double Coth(double x);
00431         static double Arsinh(double x);
00432         static double Arcosh(double x);
00433         static double Artanh(double x);
00434         static double Arcoth(double x);
00435         static double Ln(double x);
00436         static double Lg(double x);
00437         static double Ld(double x);
00438         static double Sqrt(double x);
00439         static double Abs(double x);
00440         static double Sgn(double x);
00441         static double Intfunc(double x);
00442     };
00443 
00444   private:
00445     /**
00446      * these methods and attributes are used during parsing
00447      */
00448     char* strLower(char* s);
00449     int   skipBrackets(char* s,int& i);
00450     char* deleteBrackets(char* s);
00451     char* skipWhiteSpace(char* s);
00452     node* compile1(char* s);
00453     node* compile2(char* s);
00454     node* compile3(char* s);
00455     node* compile4(char* s);
00456 
00457     const static char* szFuncs[];
00458     const static double pi;      
00459     const static double e;       
00460 
00461     int   iError;
00462     char* szErrorPos;     
00463     bool  bHasTwoVars;    
00464     node* pRootNode;      
00465   };
00466 }
00467 
00468 #endif

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