bpp-core  2.1.0
Functions.h
Go to the documentation of this file.
00001 //
00002 // File: Functions.h
00003 // Created by: Julien Dutheil
00004 // Created on: Sun Nov  9 23:11:00 2003
00005 //
00006 
00007 /*
00008 Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
00009 
00010 This software is a computer program whose purpose is to provide classes
00011 for numerical calculus.
00012 
00013 This software is governed by the CeCILL  license under French law and
00014 abiding by the rules of distribution of free software.  You can  use, 
00015 modify and/ or redistribute the software under the terms of the CeCILL
00016 license as circulated by CEA, CNRS and INRIA at the following URL
00017 "http://www.cecill.info". 
00018 
00019 As a counterpart to the access to the source code and  rights to copy,
00020 modify and redistribute granted by the license, users are provided only
00021 with a limited warranty  and the software's author,  the holder of the
00022 economic rights,  and the successive licensors  have only  limited
00023 liability. 
00024 
00025 In this respect, the user's attention is drawn to the risks associated
00026 with loading,  using,  modifying and/or developing or reproducing the
00027 software by the user in light of its specific status of free software,
00028 that may mean  that it is complicated to manipulate,  and  that  also
00029 therefore means  that it is reserved for developers  and  experienced
00030 professionals having in-depth computer knowledge. Users are therefore
00031 encouraged to load and test the software's suitability as regards their
00032 requirements in conditions enabling the security of their systems and/or 
00033 data to be ensured and,  more generally, to use and operate it in the 
00034 same conditions as regards security. 
00035 
00036 The fact that you are presently reading this means that you have had
00037 knowledge of the CeCILL license and that you accept its terms.
00038 */
00039 
00040 #ifndef _FUNCTIONS_H_
00041 #define _FUNCTIONS_H_
00042 
00043 #include "../ParameterList.h"
00044 #include "../Parametrizable.h"
00045 #include "../AbstractParametrizable.h"
00046 #include "../ParameterExceptions.h"
00047 
00048 // From Utils:
00049 #include "../../Clonable.h"
00050 #include "../../Exceptions.h"
00051 
00052 // From the STL:
00053 #include <cmath>
00054 
00055 namespace bpp
00056 {
00057 
00086 class Function:
00087   public virtual Parametrizable
00088 {    
00089   public:
00090     Function() {}
00091     virtual ~Function() {}
00092 
00093   public:
00094 
00100     virtual void setParameters(const ParameterList& parameters) throw (ParameterNotFoundException, ConstraintException, Exception) = 0;
00101 
00108     virtual double getValue() const throw (Exception) = 0;
00109     
00117     virtual double f(const ParameterList& parameters) throw (Exception)
00118     {
00119       setParameters(parameters);
00120       return getValue();
00121     }
00122 };
00123 
00129 class DerivableFirstOrder:
00130   public virtual Function
00131 {
00132   public:
00133     DerivableFirstOrder() {}
00134     virtual ~DerivableFirstOrder() {}
00135 
00136 #if defined(NO_VIRTUAL_COV)
00137     Clonable* clone() const = 0;
00138 #else
00139     DerivableFirstOrder* clone() const = 0;
00140 #endif
00141 
00142   public:
00143 
00149     virtual void enableFirstOrderDerivatives(bool yn) = 0;
00150     
00156     virtual bool enableFirstOrderDerivatives() const = 0;
00157 
00165     virtual double getFirstOrderDerivative(const std::string& variable) const throw (Exception) = 0;
00166     
00176     virtual double df(const std::string& variable, const ParameterList& parameters) throw (Exception)
00177     {
00178       setParameters(parameters);
00179       return getFirstOrderDerivative(variable);
00180     }
00181 };
00182 
00189 class DerivableSecondOrder:
00190   public virtual DerivableFirstOrder
00191 {
00192   public:
00193     DerivableSecondOrder() {}
00194     virtual ~DerivableSecondOrder() {}
00195 
00196 #if defined(NO_VIRTUAL_COV)
00197     Clonable* clone() const = 0;
00198 #else
00199     DerivableSecondOrder* clone() const = 0;
00200 #endif
00201 
00202   public:
00203 
00209     virtual void enableSecondOrderDerivatives(bool yn) = 0;
00210     
00216     virtual bool enableSecondOrderDerivatives() const = 0;
00217 
00225     virtual double getSecondOrderDerivative(const std::string& variable) const throw (Exception) = 0;
00226   
00236     virtual double d2f(const std::string& variable, const ParameterList& parameters) throw (Exception)
00237     {
00238       setParameters(parameters);
00239       return getSecondOrderDerivative(variable);
00240     }    
00241 
00251     virtual double getSecondOrderDerivative(const std::string& variable1, const std::string& variable2) const throw (Exception) = 0;  
00252     
00263     virtual double d2f(const std::string& variable1, const std::string& variable2, const ParameterList& parameters) throw (Exception)
00264     {
00265       setParameters(parameters);
00266       return getSecondOrderDerivative(variable1, variable2);
00267     }
00268 };
00269 
00274 class FunctionWrapper:
00275   public virtual Function
00276 {
00277   protected:
00278     Function* function_;
00279 
00280   public:
00281     FunctionWrapper(Function* function) : function_(function) {}
00282     FunctionWrapper(const FunctionWrapper& fw) : function_(fw.function_) {}
00283     FunctionWrapper& operator=(const FunctionWrapper& fw)
00284     {
00285       function_ = fw.function_;
00286       return *this;
00287     }
00288 
00289   public:
00290     bool hasParameter(const std::string& name) const
00291     {
00292       return function_->hasParameter(name);
00293     }
00294 
00295     void setParameters(const ParameterList & parameters)
00296       throw (ParameterNotFoundException, ConstraintException)
00297     {
00298       function_->setParameters(parameters);
00299     }
00300 
00301     const ParameterList& getParameters() const throw (Exception)
00302     {
00303       return function_->getParameters();  
00304     }
00305 
00306     const Parameter& getParameter(const std::string & name) const throw (ParameterNotFoundException)
00307     {
00308       return function_->getParameter(name);
00309     }
00310 
00311     double getValue() const throw (Exception)
00312     {
00313       return function_->getValue();
00314     }
00315     
00316     double f(const ParameterList& parameters) throw (Exception)
00317     {
00318       return function_->f(parameters);
00319     }
00320     
00321     double getParameterValue(const std::string& name) const throw (ParameterNotFoundException)
00322     {
00323       return function_->getParameterValue(name);
00324     }
00325       
00326     void setAllParametersValues(const ParameterList & parameters)
00327       throw (ParameterNotFoundException, ConstraintException)
00328     {
00329       function_->setAllParametersValues(parameters);
00330     }
00331     
00332     void setParameterValue(const std::string& name, double value)
00333       throw (ParameterNotFoundException, ConstraintException)
00334     {
00335       function_->setParameterValue(name, value);
00336     }
00337     
00338     void setParametersValues(const ParameterList& parameters)
00339       throw (ParameterNotFoundException, ConstraintException)
00340     {
00341       function_->setParametersValues(parameters);
00342     }
00343     
00344     bool matchParametersValues(const ParameterList& parameters)
00345       throw (ConstraintException)
00346     {
00347       return function_->matchParametersValues(parameters);
00348     }
00349 
00350     size_t getNumberOfParameters() const
00351     {
00352       return function_->getNumberOfParameters();
00353     }
00354 
00355     void setNamespace(const std::string& prefix)
00356     {
00357       function_->setNamespace(prefix);
00358     }
00359 
00360     std::string getNamespace() const
00361     {
00362       return function_->getNamespace();
00363     }
00364 
00365     std::string getParameterNameWithoutNamespace(const std::string& name) const
00366     {
00367       return function_->getParameterNameWithoutNamespace(name);
00368     }
00369 
00370 };
00371 
00372 
00373 
00378 class DerivableFirstOrderWrapper:
00379   public FunctionWrapper,
00380   public virtual DerivableFirstOrder
00381 {
00382   public:
00383     DerivableFirstOrderWrapper(DerivableFirstOrder* function) : FunctionWrapper(function) {}
00384 
00385   public:
00386     void enableFirstOrderDerivatives(bool yn) {
00387       dynamic_cast<DerivableFirstOrder*>(function_)->enableFirstOrderDerivatives(yn);
00388     }
00389     
00390     bool enableFirstOrderDerivatives() const {
00391       return dynamic_cast<DerivableFirstOrder*>(function_)->enableFirstOrderDerivatives();
00392     }
00393 
00394     double getFirstOrderDerivative(const std::string& variable) const throw (Exception) {
00395       return dynamic_cast<DerivableFirstOrder*>(function_)->getFirstOrderDerivative(variable);
00396     }
00397 
00398 };
00399 
00400 
00401 
00406 class DerivableSecondOrderWrapper:
00407   public DerivableFirstOrderWrapper,
00408   public virtual DerivableSecondOrder
00409 {
00410   public:
00411     DerivableSecondOrderWrapper(DerivableSecondOrder* function) : DerivableFirstOrderWrapper(function) {}
00412 
00413   public:
00414     void enableSecondOrderDerivatives(bool yn) {
00415       dynamic_cast<DerivableSecondOrder*>(function_)->enableSecondOrderDerivatives(yn);
00416     }
00417     
00418     bool enableSecondOrderDerivatives() const {
00419       return dynamic_cast<DerivableSecondOrder*>(function_)->enableSecondOrderDerivatives();
00420     }
00421 
00422     double getSecondOrderDerivative(const std::string& variable) const throw (Exception) {
00423       return dynamic_cast<DerivableSecondOrder*>(function_)->getSecondOrderDerivative(variable);
00424     }
00425 
00426     double getSecondOrderDerivative(const std::string& variable1, const std::string& variable2) const throw (Exception) {
00427       return dynamic_cast<DerivableSecondOrder*>(function_)->getSecondOrderDerivative(variable1, variable2);
00428     }
00429 
00430 };
00431 
00432 
00433 
00439 class InfinityFunctionWrapper:
00440   public FunctionWrapper
00441 {
00442   protected:
00443     mutable bool constraintMatch_;
00444     
00445   public:
00446     InfinityFunctionWrapper(Function* function) :
00447       FunctionWrapper(function),
00448       constraintMatch_(false) {}
00449     virtual ~InfinityFunctionWrapper() {}
00450 
00451 #if defined(NO_VIRTUAL_COV)
00452     Clonable* clone() const { return new InfinityFunctionWrapper(*this); }
00453 #else
00454     InfinityFunctionWrapper* clone() const { return new InfinityFunctionWrapper(*this); }
00455 #endif
00456 
00457   public:
00458 
00459     void setParameters(const ParameterList& parameters)
00460       throw (ParameterNotFoundException, ConstraintException)
00461     {
00462       try
00463       {
00464         function_->setParameters(parameters);
00465         constraintMatch_ = false;
00466       }
00467       catch(ConstraintException& ce)
00468       {
00469         constraintMatch_ = true;
00470       }
00471     }
00472 
00473     double getValue() const throw (Exception)
00474     {
00475       return constraintMatch_ ? -log(0.) :  function_->getValue();
00476     }
00477     
00478     double f(const ParameterList& parameters) throw (Exception)
00479     {
00480       setParameters(parameters);
00481       return getValue();
00482     }
00483           
00484     void setAllParametersValues(const ParameterList & parameters)
00485       throw (ParameterNotFoundException, ConstraintException)
00486     {
00487       try
00488       {
00489         function_->setAllParametersValues(parameters);
00490         constraintMatch_ = false;
00491       }
00492       catch(ConstraintException& ce)
00493       {
00494         constraintMatch_ = true;
00495       }
00496     }
00497     
00498     void setParameterValue(const std::string& name, double value)
00499       throw (ParameterNotFoundException, ConstraintException)
00500     {
00501       try
00502       {
00503         function_->setParameterValue(name, value);
00504         constraintMatch_ = false;
00505       }
00506       catch(ConstraintException& ce)
00507       {
00508         constraintMatch_ = true;
00509       }
00510     }
00511     
00512     void setParametersValues(const ParameterList& parameters)
00513       throw (ParameterNotFoundException, ConstraintException)
00514     {
00515       try
00516       {
00517         function_->setParametersValues(parameters);
00518         constraintMatch_ = false;
00519       }
00520       catch(ConstraintException& ce)
00521       {
00522         constraintMatch_ = true;
00523       }
00524     }
00525     
00526     bool matchParametersValues(const ParameterList& parameters)
00527       throw (ConstraintException)
00528     {
00529       try
00530       {
00531         bool test = function_->matchParametersValues(parameters);
00532         constraintMatch_ = false;
00533         return test;
00534       }
00535       catch (ConstraintException& ce)
00536       {
00537         constraintMatch_ = true;
00538         return false;
00539       }
00540     }
00541 
00542 };
00543 
00549 class InfinityDerivableFirstOrderWrapper :
00550   public virtual InfinityFunctionWrapper
00551 {
00552   public:
00553     InfinityDerivableFirstOrderWrapper(DerivableFirstOrder* function) : InfinityFunctionWrapper(function) {}
00554     virtual ~InfinityDerivableFirstOrderWrapper() {}
00555     
00556 #if defined(NO_VIRTUAL_COV)
00557     Clonable* clone() const { return new InfinityDerivableFirstOrderWrapper(*this); }
00558 #else
00559     InfinityDerivableFirstOrderWrapper* clone() const { return new InfinityDerivableFirstOrderWrapper(*this); }
00560 #endif
00561 
00562   public:
00563     
00564     double getFirstOrderDerivative(const std::string& variable) const throw (Exception)
00565     {
00566       return constraintMatch_ ? -log(0.) :  (dynamic_cast<DerivableFirstOrder *>(function_)->getFirstOrderDerivative(variable));    
00567     }
00568     
00569     double df(const std::string& variable, const ParameterList& parameters) throw (Exception)
00570     {
00571       setParameters(parameters);
00572       return getFirstOrderDerivative(variable);
00573     }
00574 };
00575 
00581 class InfinityDerivableSecondOrderWrapper :
00582   public virtual InfinityDerivableFirstOrderWrapper
00583 {
00584   public:
00585     InfinityDerivableSecondOrderWrapper(DerivableFirstOrder* function):
00586       InfinityFunctionWrapper(function),
00587       InfinityDerivableFirstOrderWrapper(function) {}
00588     virtual ~InfinityDerivableSecondOrderWrapper() {}
00589 
00590 #if defined(NO_VIRTUAL_COV)
00591     Clonable* clone() const { return new InfinityDerivableSecondOrderWrapper(*this); }
00592 #else
00593     InfinityDerivableSecondOrderWrapper* clone() const { return new InfinityDerivableSecondOrderWrapper(*this); }
00594 #endif
00595 
00596   public:
00597 
00598     double getSecondOrderDerivative(const std::string& variable) const throw (Exception)
00599     {
00600       return constraintMatch_ ? -log(0.) :  (dynamic_cast<DerivableSecondOrder *>(function_)->getSecondOrderDerivative(variable));          
00601     }
00602   
00603     double d2f(const std::string & variable, const ParameterList& parameters) throw (Exception)
00604     {
00605       setParameters(parameters);
00606       return getSecondOrderDerivative(variable);
00607     }    
00608 
00609     double getSecondOrderDerivative(const std::string& variable1, const std::string& variable2) const throw (Exception)
00610     {
00611       return constraintMatch_ ? -log(0.) :  (dynamic_cast<DerivableSecondOrder *>(function_)->getSecondOrderDerivative(variable1, variable2));      
00612     }
00613     
00614     double d2f(const std::string & variable1, const std::string& variable2, const ParameterList& parameters) throw (Exception)
00615     {
00616       setParameters(parameters);
00617       return getSecondOrderDerivative(variable1, variable2);
00618     }
00619 };
00620 
00621 
00627 class TestFunction :
00628   public virtual Function,
00629   public AbstractParametrizable
00630 {
00631   public:
00632     TestFunction(double x = 0, double y = 0) :
00633       AbstractParametrizable("")
00634     {
00635       addParameter_(new Parameter("x", x));
00636       addParameter_(new Parameter("y", y));
00637     }
00638 
00639     Clonable* clone() const { return new TestFunction(*this); }
00640 
00641     void setParameters(const ParameterList& parameters) throw (Exception) 
00642     {
00643       matchParametersValues(parameters);
00644     }
00645 
00646     double getValue() const throw (Exception)
00647     {
00648       double x = getParameter("x").getValue();
00649       double y = getParameter("y").getValue();
00650       return (x*x + y*y);
00651     }
00652 
00653     void fireParameterChanged(const ParameterList& parameters) {}
00654 };
00655 
00656 } //end of namespace bpp.
00657 
00658 #endif  //_FUNCTIONS_H_
00659 
 All Classes Namespaces Files Functions Variables Typedefs Friends