|
bpp-core
2.1.0
|
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