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