bpp-core  2.1.0
MetaOptimizer.cpp
Go to the documentation of this file.
00001 //
00002 // File: MetaOptimizer.cpp
00003 // Created by: Julien Dutheil
00004 // Created on: Fri Oct 12 16:05 2007
00005 // From file: NewtonBrentMetaOptimizer.cpp
00006 // Created on: Tue Nov 17 17:22 2004
00007 // 
00008 //
00009 
00010 /*
00011 Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
00012 
00013 This software is a computer program whose purpose is to provide classes
00014 for phylogenetic data analysis.
00015 
00016 This software is governed by the CeCILL  license under French law and
00017 abiding by the rules of distribution of free software.  You can  use, 
00018 modify and/ or redistribute the software under the terms of the CeCILL
00019 license as circulated by CEA, CNRS and INRIA at the following URL
00020 "http://www.cecill.info". 
00021 
00022 As a counterpart to the access to the source code and  rights to copy,
00023 modify and redistribute granted by the license, users are provided only
00024 with a limited warranty  and the software's author,  the holder of the
00025 economic rights,  and the successive licensors  have only  limited
00026 liability. 
00027 
00028 In this respect, the user's attention is drawn to the risks associated
00029 with loading,  using,  modifying and/or developing or reproducing the
00030 software by the user in light of its specific status of free software,
00031 that may mean  that it is complicated to manipulate,  and  that  also
00032 therefore means  that it is reserved for developers  and  experienced
00033 professionals having in-depth computer knowledge. Users are therefore
00034 encouraged to load and test the software's suitability as regards their
00035 requirements in conditions enabling the security of their systems and/or 
00036 data to be ensured and,  more generally, to use and operate it in the 
00037 same conditions as regards security. 
00038 
00039 The fact that you are presently reading this means that you have had
00040 knowledge of the CeCILL license and that you accept its terms.
00041 */
00042 
00043 /**************************************************************************/
00044 
00045 #include "MetaOptimizer.h"
00046 #include "../../App/ApplicationTools.h"
00047 
00048 using namespace bpp;
00049 using namespace std;
00050 
00051 /**************************************************************************/
00052 
00053 string MetaOptimizerInfos::IT_TYPE_STEP = "step";
00054 string MetaOptimizerInfos::IT_TYPE_FULL = "full";
00055 
00056 /**************************************************************************/
00057 
00058 MetaOptimizer::MetaOptimizer(
00059     Function* function,
00060     MetaOptimizerInfos* desc,
00061     unsigned int n):
00062   AbstractOptimizer(function),
00063   optDesc_(desc), optParameters_(desc->getNumberOfOptimizers()),
00064   nbParameters_(desc->getNumberOfOptimizers()), n_(n),
00065   precisionStep_(-1.), stepCount_(0), initialValue_(-1.)
00066 {
00067   setDefaultStopCondition_(new FunctionStopCondition(this));
00068   setStopCondition(*getDefaultStopCondition());
00069   precisionStep_ = log10(getStopCondition()->getTolerance()) / n_;
00070   setOptimizationProgressCharacter("");
00071 }
00072 
00073 /**************************************************************************/
00074 
00075 MetaOptimizer::MetaOptimizer(
00076     const MetaOptimizer& opt):
00077   AbstractOptimizer(opt),
00078   optDesc_(dynamic_cast<MetaOptimizerInfos *>(opt.optDesc_->clone())),
00079   optParameters_(opt.optParameters_),
00080   nbParameters_(opt.nbParameters_),
00081   n_(opt.n_),
00082   precisionStep_(opt.precisionStep_),
00083   stepCount_(opt.stepCount_),
00084   initialValue_(opt.initialValue_)
00085 {}
00086 
00087 /**************************************************************************/
00088 
00089 MetaOptimizer& MetaOptimizer::operator=(
00090     const MetaOptimizer& opt)
00091 {
00092   AbstractOptimizer::operator=(opt);
00093   optDesc_       = dynamic_cast<MetaOptimizerInfos *>(opt.optDesc_->clone());
00094   optParameters_ = opt.optParameters_;
00095   nbParameters_  = opt.nbParameters_;
00096   n_             = opt.n_;
00097   precisionStep_ = opt.precisionStep_;
00098   stepCount_     = opt.stepCount_;
00099   initialValue_  = opt.initialValue_;
00100   return *this;
00101 }
00102 
00103 /**************************************************************************/
00104 
00105 MetaOptimizer::~MetaOptimizer()
00106 {
00107   // Delete all optimizers:
00108   delete optDesc_;
00109 }
00110 
00111 /**************************************************************************/
00112 
00113 void MetaOptimizer::doInit(const ParameterList& parameters)
00114   throw (Exception)
00115 {
00116   optParameters_.resize(optDesc_->getNumberOfOptimizers());
00117   for (unsigned int i = 0; i < optDesc_->getNumberOfOptimizers(); i++)
00118   {
00119     optParameters_[i].reset();
00120     for (size_t j = 0; j < optDesc_->getParameterNames(i).size(); j++)
00121     {
00122       string pname = optDesc_->getParameterNames(i)[j];
00123       if (parameters.hasParameter(pname))
00124       {
00125         optParameters_[i].addParameter(parameters.getParameter(pname));
00126       }
00127     }
00128     nbParameters_[i] = optParameters_[i].size();
00129   }
00130 
00131   // Initialize optimizers:
00132   for (unsigned int i = 0; i < optDesc_->getNumberOfOptimizers(); i++)
00133   {
00134     if (nbParameters_[i] > 0)
00135     {
00136       Optimizer * opt = optDesc_->getOptimizer(i);
00137       dynamic_cast<AbstractOptimizer*>(opt)->updateParameters(updateParameters());
00138       opt->setProfiler(getProfiler());
00139       opt->setMessageHandler(getMessageHandler());
00140       opt->setConstraintPolicy(getConstraintPolicy());
00141       opt->setVerbose(getVerbose() > 0 ? getVerbose() - 1 : 0);
00142     }
00143   }
00144   
00145   // Actualize parameters:
00146   getParameters_().matchParametersValues(getFunction()->getParameters());
00147   
00148   getFunction()->setParameters(getParameters());
00149   initialValue_ = getFunction()->getValue();
00150   // Reset counter:
00151   stepCount_ = 1;
00152   // Recompute step if precision has changed:
00153   precisionStep_ = (log10(getStopCondition()->getTolerance()) - log10(initialValue_)) / n_;
00154 }
00155 
00156 /**************************************************************************/
00157 
00158 double MetaOptimizer::doStep() throw (Exception)
00159 {
00160   stepCount_++;
00161   
00162   int tolTest = 0;
00163   double tol = getStopCondition()->getTolerance();
00164   if (stepCount_ <= n_)
00165   {
00166     tol = initialValue_ * pow(10, stepCount_ * precisionStep_);
00167   }
00168   
00169   for (unsigned int i = 0; i < optDesc_->getNumberOfOptimizers(); i++)
00170   {
00171     if (nbParameters_[i] > 0)
00172     {
00173       if (getVerbose() > 1 && ApplicationTools::message)
00174       {
00175         (ApplicationTools::message->endLine() << optDesc_->getName(i)).endLine();
00176         ApplicationTools::message->flush();
00177       }
00178       if (optDesc_->requiresFirstOrderDerivatives(i))
00179         dynamic_cast<DerivableFirstOrder*>(getFunction())->enableFirstOrderDerivatives(true);
00180       if (optDesc_->requiresSecondOrderDerivatives(i))  
00181         dynamic_cast<DerivableSecondOrder*>(getFunction())->enableSecondOrderDerivatives(true);
00182 
00183       optParameters_[i].matchParametersValues(getParameters());
00184       Optimizer * opt = optDesc_->getOptimizer(i);
00185       opt->getStopCondition()->setTolerance(tol);
00186       opt->init(optParameters_[i]);
00187       if (optDesc_->getIterationType(i) == MetaOptimizerInfos::IT_TYPE_STEP)
00188         opt->step();
00189       else if (optDesc_->getIterationType(i) == MetaOptimizerInfos::IT_TYPE_FULL)
00190         opt->optimize();
00191       else throw Exception("MetaOptimizer::step. Unknown iteration type specified.");
00192       nbEval_ += opt->getNumberOfEvaluations();
00193       if (optDesc_->requiresFirstOrderDerivatives(i))
00194         dynamic_cast<DerivableFirstOrder*>(getFunction())->enableFirstOrderDerivatives(false);
00195       if (optDesc_->requiresSecondOrderDerivatives(i))  
00196         dynamic_cast<DerivableSecondOrder*>(getFunction())->enableSecondOrderDerivatives(false);
00197       if (getVerbose() > 1) cout << endl;
00198       getParameters_().matchParametersValues(opt->getParameters());
00199     }
00200     tolTest += nbParameters_[i] > 0 ? 1 : 0;
00201   }
00202   tolIsReached_ = (tolTest == 1);
00203    
00204   return getFunction()->getValue();
00205 }
00206 
00207 /**************************************************************************/
00208 
 All Classes Namespaces Files Functions Variables Typedefs Friends