bpp-phyl  2.2.0
OptimizationTools.cpp
Go to the documentation of this file.
1 //
2 // File: OptimizationTools.cpp
3 // Created by: Julien Dutheil
4 // Created on: Sun Dec 14 09:43:32 2003
5 //
6 
7 /*
8  Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
9 
10  This software is a computer program whose purpose is to provide classes
11  for phylogenetic data analysis.
12 
13  This software is governed by the CeCILL license under French law and
14  abiding by the rules of distribution of free software. You can use,
15  modify and/ or redistribute the software under the terms of the CeCILL
16  license as circulated by CEA, CNRS and INRIA at the following URL
17  "http://www.cecill.info".
18 
19  As a counterpart to the access to the source code and rights to copy,
20  modify and redistribute granted by the license, users are provided only
21  with a limited warranty and the software's author, the holder of the
22  economic rights, and the successive licensors have only limited
23  liability.
24 
25  In this respect, the user's attention is drawn to the risks associated
26  with loading, using, modifying and/or developing or reproducing the
27  software by the user in light of its specific status of free software,
28  that may mean that it is complicated to manipulate, and that also
29  therefore means that it is reserved for developers and experienced
30  professionals having in-depth computer knowledge. Users are therefore
31  encouraged to load and test the software's suitability as regards their
32  requirements in conditions enabling the security of their systems and/or
33  data to be ensured and, more generally, to use and operate it in the
34  same conditions as regards security.
35 
36  The fact that you are presently reading this means that you have had
37  knowledge of the CeCILL license and that you accept its terms.
38  */
39 
40 #include "OptimizationTools.h"
43 #include "NNISearchable.h"
44 #include "NNITopologySearch.h"
45 #include "Io/Newick.h"
46 
47 #include <Bpp/App/ApplicationTools.h>
48 #include <Bpp/Numeric/ParameterList.h>
49 #include <Bpp/Numeric/Function/BfgsMultiDimensions.h>
50 #include <Bpp/Numeric/Function/ReparametrizationFunctionWrapper.h>
51 #include <Bpp/Numeric/Function/ThreePointsNumericalDerivative.h>
52 #include <Bpp/Numeric/Function/ConjugateGradientMultiDimensions.h>
53 #include <Bpp/Numeric/Function/TwoPointsNumericalDerivative.h>
54 #include <Bpp/Numeric/Function/DownhillSimplexMethod.h>
55 
56 // From bpp-seq:
57 #include <Bpp/Seq/Io/Fasta.h>
58 
59 using namespace bpp;
60 using namespace std;
61 
62 /******************************************************************************/
63 
65 
67 
68 /******************************************************************************/
69 
70 std::string OptimizationTools::OPTIMIZATION_NEWTON = "newton";
71 std::string OptimizationTools::OPTIMIZATION_GRADIENT = "gradient";
72 std::string OptimizationTools::OPTIMIZATION_BRENT = "Brent";
73 std::string OptimizationTools::OPTIMIZATION_BFGS = "BFGS";
74 
75 /******************************************************************************/
76 
78  tl_(tl),
79  brLen_(),
80  lambda_()
81 {
82  // We work only on the branch lengths:
84  if (brLen_.hasParameter("RootPosition"))
85  brLen_.deleteParameter("RootPosition");
86  lambda_.addParameter(Parameter("scale factor", 0));
87 }
88 
90 
91 void OptimizationTools::ScaleFunction::setParameters(const ParameterList& lambda)
92 throw (ParameterNotFoundException, ConstraintException)
93 {
94  if (lambda.size() != 1)
95  throw Exception("OptimizationTools::ScaleFunction::f(). This is a one parameter function!");
96  lambda_.setParametersValues(lambda);
97 }
98 
100 throw (ParameterException)
101 {
102  // Scale the tree:
103  ParameterList brLen = brLen_;
104  double s = exp(lambda_[0].getValue());
105  for (unsigned int i = 0; i < brLen.size(); i++)
106  {
107  try
108  {
109  brLen[i].setValue(brLen[i].getValue() * s);
110  }
111  catch (ConstraintException& cex)
112  {
113  // Do nothing. Branch value is already at bound...
114  }
115  }
116  return tl_->f(brLen);
117 }
118 
119 /******************************************************************************/
120 
122  TreeLikelihood* tl,
123  double tolerance,
124  unsigned int tlEvalMax,
125  OutputStream* messageHandler,
126  OutputStream* profiler,
127  unsigned int verbose)
128 throw (Exception)
129 {
130  ScaleFunction sf(tl);
131  BrentOneDimension bod(&sf);
132  bod.setMessageHandler(messageHandler);
133  bod.setProfiler(profiler);
134  ParameterList singleParameter;
135  singleParameter.addParameter(Parameter("scale factor", 0));
136  bod.setInitialInterval(-0.5, 0.5);
137  bod.init(singleParameter);
138  ParametersStopCondition PS(&bod, tolerance);
139  bod.setStopCondition(PS);
140  bod.setMaximumNumberOfEvaluations(tlEvalMax);
141  bod.optimize();
142  ApplicationTools::displayTaskDone();
143  if (verbose > 0)
144  ApplicationTools::displayResult("Tree scaled by", exp(sf.getParameters()[0].getValue()));
145  return bod.getNumberOfEvaluations();
146 }
147 
148 /******************************************************************************/
149 
152  const ParameterList& parameters,
153  OptimizationListener* listener,
154  unsigned int nstep,
155  double tolerance,
156  unsigned int tlEvalMax,
157  OutputStream* messageHandler,
158  OutputStream* profiler,
159  bool reparametrization,
160  unsigned int verbose,
161  const std::string& optMethodDeriv,
162  const std::string& optMethodModel)
163 throw (Exception)
164 {
165  DerivableSecondOrder* f = tl;
166  ParameterList pl = parameters;
167 
168  // Shall we reparametrize the function to remove constraints?
169  auto_ptr<DerivableSecondOrder> frep;
170  if (reparametrization)
171  {
172  frep.reset(new ReparametrizationDerivableSecondOrderWrapper(f, parameters));
173  f = frep.get();
174 
175  // Reset parameters to remove constraints:
176  pl = f->getParameters().subList(parameters.getParameterNames());
177  }
178 
179  // ///////////////
180  // Build optimizer:
181 
182  // Branch lengths
183 
184  MetaOptimizerInfos* desc = new MetaOptimizerInfos();
185  MetaOptimizer* poptimizer = 0;
186  AbstractNumericalDerivative* fnum = new ThreePointsNumericalDerivative(f);
187 
188  if (optMethodDeriv == OPTIMIZATION_GRADIENT)
189  desc->addOptimizer("Branch length parameters", new ConjugateGradientMultiDimensions(f), tl->getBranchLengthsParameters().getParameterNames(), 2, MetaOptimizerInfos::IT_TYPE_FULL);
190  else if (optMethodDeriv == OPTIMIZATION_NEWTON)
191  desc->addOptimizer("Branch length parameters", new PseudoNewtonOptimizer(f), tl->getBranchLengthsParameters().getParameterNames(), 2, MetaOptimizerInfos::IT_TYPE_FULL);
192  else if (optMethodDeriv == OPTIMIZATION_BFGS)
193  desc->addOptimizer("Branch length parameters", new BfgsMultiDimensions(f), tl->getBranchLengthsParameters().getParameterNames(), 2, MetaOptimizerInfos::IT_TYPE_FULL);
194  else
195  throw Exception("OptimizationTools::optimizeNumericalParameters. Unknown optimization method: " + optMethodDeriv);
196 
197  // Other parameters
198 
199  if (optMethodModel == OPTIMIZATION_BRENT)
200  {
201  ParameterList plsm = parameters.getCommonParametersWith(tl->getSubstitutionModelParameters());
202  desc->addOptimizer("Substitution model parameter", new SimpleMultiDimensions(f), plsm.getParameterNames(), 0, MetaOptimizerInfos::IT_TYPE_STEP);
203 
204 
205  ParameterList plrd = parameters.getCommonParametersWith(tl->getRateDistributionParameters());
206  desc->addOptimizer("Rate distribution parameter", new SimpleMultiDimensions(f), plrd.getParameterNames(), 0, MetaOptimizerInfos::IT_TYPE_STEP);
207  poptimizer = new MetaOptimizer(f, desc, nstep);
208  }
209  else if (optMethodModel == OPTIMIZATION_BFGS)
210  {
211  vector<string> vNameDer;
212 
213  ParameterList plsm = parameters.getCommonParametersWith(tl->getSubstitutionModelParameters());
214  vNameDer = plsm.getParameterNames();
215 
216  ParameterList plrd = parameters.getCommonParametersWith(tl->getRateDistributionParameters());
217 
218  vector<string> vNameDer2 = plrd.getParameterNames();
219 
220  vNameDer.insert(vNameDer.begin(), vNameDer2.begin(), vNameDer2.end());
221  fnum->setParametersToDerivate(vNameDer);
222 
223  desc->addOptimizer("Rate & model distribution parameters", new BfgsMultiDimensions(fnum), vNameDer, 1, MetaOptimizerInfos::IT_TYPE_FULL);
224  poptimizer = new MetaOptimizer(fnum, desc, nstep);
225  }
226  else
227  throw Exception("OptimizationTools::optimizeNumericalParameters. Unknown optimization method: " + optMethodModel);
228 
229  poptimizer->setVerbose(verbose);
230  poptimizer->setProfiler(profiler);
231  poptimizer->setMessageHandler(messageHandler);
232  poptimizer->setMaximumNumberOfEvaluations(tlEvalMax);
233  poptimizer->getStopCondition()->setTolerance(tolerance);
234 
235  // Optimize TreeLikelihood function:
236  poptimizer->setConstraintPolicy(AutoParameter::CONSTRAINTS_AUTO);
237  NaNListener* nanListener = new NaNListener(poptimizer, tl);
238  poptimizer->addOptimizationListener(nanListener);
239  if (listener)
240  poptimizer->addOptimizationListener(listener);
241  poptimizer->init(pl);
242  poptimizer->optimize();
243 
244  if (verbose > 0)
245  ApplicationTools::displayMessage("\n");
246 
247  // We're done.
248  unsigned int nb = poptimizer->getNumberOfEvaluations();
249  delete poptimizer;
250  return nb;
251 }
252 
253 /******************************************************************************/
254 
257  const ParameterList& parameters,
258  OptimizationListener* listener,
259  double tolerance,
260  unsigned int tlEvalMax,
261  OutputStream* messageHandler,
262  OutputStream* profiler,
263  bool reparametrization,
264  bool useClock,
265  unsigned int verbose,
266  const std::string& optMethodDeriv)
267 throw (Exception)
268 {
269  DerivableSecondOrder* f = tl;
270  ParameterList pl = parameters;
271  // Shall we use a molecular clock constraint on branch lengths?
272  auto_ptr<GlobalClockTreeLikelihoodFunctionWrapper> fclock;
273  if (useClock)
274  {
275  fclock.reset(new GlobalClockTreeLikelihoodFunctionWrapper(tl));
276  f = fclock.get();
277  if (verbose > 0)
278  ApplicationTools::displayResult("Log-likelihood after adding clock", -tl->getLogLikelihood());
279 
280  // Reset parameters to use new branch lengths. WARNING! 'old' branch parameters do not exist anymore and have been replaced by heights
281  pl = fclock->getParameters().getCommonParametersWith(parameters);
282  pl.addParameters(fclock->getHeightParameters());
283  }
284  // Shall we reparametrize the function to remove constraints?
285  auto_ptr<DerivableSecondOrder> frep;
286  if (reparametrization)
287  {
288  frep.reset(new ReparametrizationDerivableSecondOrderWrapper(f, pl));
289  f = frep.get();
290 
291  // Reset parameters to remove constraints:
292  pl = f->getParameters().subList(pl.getParameterNames());
293  }
294 
295  auto_ptr<AbstractNumericalDerivative> fnum;
296  // Build optimizer:
297  auto_ptr<Optimizer> optimizer;
298  if (optMethodDeriv == OPTIMIZATION_GRADIENT)
299  {
300  fnum.reset(new TwoPointsNumericalDerivative(f));
301  fnum->setInterval(0.0000001);
302  optimizer.reset(new ConjugateGradientMultiDimensions(fnum.get()));
303  }
304  else if (optMethodDeriv == OPTIMIZATION_NEWTON)
305  {
306  fnum.reset(new ThreePointsNumericalDerivative(f));
307  fnum->setInterval(0.0001);
308  optimizer.reset(new PseudoNewtonOptimizer(fnum.get()));
309  }
310  else if (optMethodDeriv == OPTIMIZATION_BFGS)
311  {
312  fnum.reset(new TwoPointsNumericalDerivative(f));
313  fnum->setInterval(0.0001);
314  optimizer.reset(new BfgsMultiDimensions(fnum.get()));
315  }
316  else
317  throw Exception("OptimizationTools::optimizeNumericalParameters2. Unknown optimization method: " + optMethodDeriv);
318 
319  // Numerical derivatives:
320  ParameterList tmp = tl->getNonDerivableParameters();
321  if (useClock)
322  tmp.addParameters(fclock->getHeightParameters());
323  fnum->setParametersToDerivate(tmp.getParameterNames());
324  optimizer->setVerbose(verbose);
325  optimizer->setProfiler(profiler);
326  optimizer->setMessageHandler(messageHandler);
327  optimizer->setMaximumNumberOfEvaluations(tlEvalMax);
328  optimizer->getStopCondition()->setTolerance(tolerance);
329 
330  // Optimize TreeLikelihood function:
331  optimizer->setConstraintPolicy(AutoParameter::CONSTRAINTS_AUTO);
332  NaNListener* nanListener = new NaNListener(optimizer.get(), tl);
333  optimizer->addOptimizationListener(nanListener);
334  if (listener)
335  optimizer->addOptimizationListener(listener);
336  optimizer->init(pl);
337  optimizer->optimize();
338 
339  if (verbose > 0)
340  ApplicationTools::displayMessage("\n");
341 
342  // We're done.
343  return optimizer->getNumberOfEvaluations();
344 }
345 
346 /******************************************************************************/
347 
350  const ParameterList& parameters,
351  OptimizationListener* listener,
352  double tolerance,
353  unsigned int tlEvalMax,
354  OutputStream* messageHandler,
355  OutputStream* profiler,
356  unsigned int verbose,
357  const std::string& optMethodDeriv)
358 throw (Exception)
359 {
360  // Build optimizer:
361  Optimizer* optimizer = 0;
362  if (optMethodDeriv == OPTIMIZATION_GRADIENT)
363  {
364  tl->enableFirstOrderDerivatives(true);
365  tl->enableSecondOrderDerivatives(false);
366  optimizer = new ConjugateGradientMultiDimensions(tl);
367  }
368  else if (optMethodDeriv == OPTIMIZATION_NEWTON)
369  {
370  tl->enableFirstOrderDerivatives(true);
371  tl->enableSecondOrderDerivatives(true);
372  optimizer = new PseudoNewtonOptimizer(tl);
373  }
374  else if (optMethodDeriv == OPTIMIZATION_BFGS)
375  {
376  tl->enableFirstOrderDerivatives(true);
377  tl->enableSecondOrderDerivatives(false);
378  optimizer = new BfgsMultiDimensions(tl);
379  }
380  else
381  throw Exception("OptimizationTools::optimizeBranchLengthsParameters. Unknown optimization method: " + optMethodDeriv);
382  optimizer->setVerbose(verbose);
383  optimizer->setProfiler(profiler);
384  optimizer->setMessageHandler(messageHandler);
385  optimizer->setMaximumNumberOfEvaluations(tlEvalMax);
386  optimizer->getStopCondition()->setTolerance(tolerance);
387 
388  // Optimize TreeLikelihood function:
389  ParameterList pl = parameters.getCommonParametersWith(tl->getBranchLengthsParameters());
390  optimizer->setConstraintPolicy(AutoParameter::CONSTRAINTS_AUTO);
391  if (listener)
392  optimizer->addOptimizationListener(listener);
393  optimizer->init(pl);
394  optimizer->optimize();
395  if (verbose > 0)
396  ApplicationTools::displayMessage("\n");
397 
398  // We're done.
399  unsigned int n = optimizer->getNumberOfEvaluations();
400  delete optimizer;
401  return n;
402 }
403 
404 /******************************************************************************/
405 
408  const ParameterList& parameters,
409  OptimizationListener* listener,
410  unsigned int nstep,
411  double tolerance,
412  unsigned int tlEvalMax,
413  OutputStream* messageHandler,
414  OutputStream* profiler,
415  unsigned int verbose,
416  const std::string& optMethodDeriv)
417 throw (Exception)
418 {
419  AbstractNumericalDerivative* fun = 0;
420 
421  // Build optimizer:
422  MetaOptimizerInfos* desc = new MetaOptimizerInfos();
423  if (optMethodDeriv == OPTIMIZATION_GRADIENT)
424  {
425  fun = new TwoPointsNumericalDerivative(cl);
426  fun->setInterval(0.0000001);
427  desc->addOptimizer("Branch length parameters", new ConjugateGradientMultiDimensions(fun), cl->getBranchLengthsParameters().getParameterNames(), 2, MetaOptimizerInfos::IT_TYPE_FULL);
428  }
429  else if (optMethodDeriv == OPTIMIZATION_NEWTON)
430  {
431  fun = new ThreePointsNumericalDerivative(cl);
432  fun->setInterval(0.0001);
433  desc->addOptimizer("Branch length parameters", new PseudoNewtonOptimizer(fun), cl->getBranchLengthsParameters().getParameterNames(), 2, MetaOptimizerInfos::IT_TYPE_FULL);
434  }
435  else
436  throw Exception("OptimizationTools::optimizeNumericalParametersWithGlobalClock. Unknown optimization method: " + optMethodDeriv);
437 
438  // Numerical derivatives:
439  ParameterList tmp = parameters.getCommonParametersWith(cl->getBranchLengthsParameters());
440  fun->setParametersToDerivate(tmp.getParameterNames());
441 
442  ParameterList plsm = parameters.getCommonParametersWith(cl->getSubstitutionModelParameters());
443  if (plsm.size() < 10)
444  desc->addOptimizer("Substitution model parameter", new SimpleMultiDimensions(cl), plsm.getParameterNames(), 0, MetaOptimizerInfos::IT_TYPE_STEP);
445  else
446  desc->addOptimizer("Substitution model parameters", new DownhillSimplexMethod(cl), plsm.getParameterNames(), 0, MetaOptimizerInfos::IT_TYPE_FULL);
447 
448  ParameterList plrd = parameters.getCommonParametersWith(cl->getRateDistributionParameters());
449  if (plrd.size() < 10)
450  desc->addOptimizer("Rate distribution parameter", new SimpleMultiDimensions(cl), plrd.getParameterNames(), 0, MetaOptimizerInfos::IT_TYPE_STEP);
451  else
452  desc->addOptimizer("Rate dsitribution parameters", new DownhillSimplexMethod(cl), plrd.getParameterNames(), 0, MetaOptimizerInfos::IT_TYPE_FULL);
453 
454  MetaOptimizer optimizer(fun, desc, nstep);
455  optimizer.setVerbose(verbose);
456  optimizer.setProfiler(profiler);
457  optimizer.setMessageHandler(messageHandler);
458  optimizer.setMaximumNumberOfEvaluations(tlEvalMax);
459  optimizer.getStopCondition()->setTolerance(tolerance);
460 
461  // Optimize TreeLikelihood function:
462  optimizer.setConstraintPolicy(AutoParameter::CONSTRAINTS_AUTO);
463  if (listener)
464  optimizer.addOptimizationListener(listener);
465  optimizer.init(parameters);
466  optimizer.optimize();
467  if (verbose > 0)
468  ApplicationTools::displayMessage("\n");
469 
470  // We're done.
471  return optimizer.getNumberOfEvaluations();
472 }
473 
474 /******************************************************************************/
475 
478  const ParameterList& parameters,
479  OptimizationListener* listener,
480  double tolerance,
481  unsigned int tlEvalMax,
482  OutputStream* messageHandler,
483  OutputStream* profiler,
484  unsigned int verbose,
485  const std::string& optMethodDeriv)
486 throw (Exception)
487 {
488  AbstractNumericalDerivative* fun = 0;
489 
490  // Build optimizer:
491  Optimizer* optimizer = 0;
492  if (optMethodDeriv == OPTIMIZATION_GRADIENT)
493  {
494  fun = new TwoPointsNumericalDerivative(cl);
495  fun->setInterval(0.0000001);
496  optimizer = new ConjugateGradientMultiDimensions(fun);
497  }
498  else if (optMethodDeriv == OPTIMIZATION_NEWTON)
499  {
500  fun = new ThreePointsNumericalDerivative(cl);
501  fun->setInterval(0.0001);
502  optimizer = new PseudoNewtonOptimizer(fun);
503  }
504  else
505  throw Exception("OptimizationTools::optimizeBranchLengthsParameters. Unknown optimization method: " + optMethodDeriv);
506 
507  // Numerical derivatives:
508  ParameterList tmp = parameters.getCommonParametersWith(cl->getParameters());
509  fun->setParametersToDerivate(tmp.getParameterNames());
510 
511  optimizer->setVerbose(verbose);
512  optimizer->setProfiler(profiler);
513  optimizer->setMessageHandler(messageHandler);
514  optimizer->setMaximumNumberOfEvaluations(tlEvalMax);
515  optimizer->getStopCondition()->setTolerance(tolerance);
516 
517  // Optimize TreeLikelihood function:
518  optimizer->setConstraintPolicy(AutoParameter::CONSTRAINTS_AUTO);
519  if (listener)
520  optimizer->addOptimizationListener(listener);
521  optimizer->init(parameters);
522  optimizer->optimize();
523  if (verbose > 0)
524  ApplicationTools::displayMessage("\n");
525 
526  // We're done.
527  unsigned int n = optimizer->getNumberOfEvaluations();
528  delete optimizer;
529 
530  // We're done.
531  return n;
532 }
533 
534 /******************************************************************************/
535 
537 {
538  optimizeCounter_++;
539  if (optimizeCounter_ == optimizeNumerical_)
540  {
541  DiscreteRatesAcrossSitesTreeLikelihood* likelihood = dynamic_cast<DiscreteRatesAcrossSitesTreeLikelihood*>(topoSearch_->getSearchableObject());
542  parameters_.matchParametersValues(likelihood->getParameters());
543  OptimizationTools::optimizeNumericalParameters(likelihood, parameters_, 0, nStep_, tolerance_, 1000000, messenger_, profiler_, reparametrization_, verbose_, optMethod_);
544  optimizeCounter_ = 0;
545  }
546 }
547 
548 /******************************************************************************/
549 
551 {
552  optimizeCounter_++;
553  if (optimizeCounter_ == optimizeNumerical_)
554  {
555  DiscreteRatesAcrossSitesTreeLikelihood* likelihood = dynamic_cast<DiscreteRatesAcrossSitesTreeLikelihood*>(topoSearch_->getSearchableObject());
556  parameters_.matchParametersValues(likelihood->getParameters());
557  OptimizationTools::optimizeNumericalParameters2(likelihood, parameters_, 0, tolerance_, 1000000, messenger_, profiler_, reparametrization_, false, verbose_, optMethod_);
558  optimizeCounter_ = 0;
559  }
560 }
561 
562 // ******************************************************************************/
563 
566  const ParameterList& parameters,
567  bool optimizeNumFirst,
568  double tolBefore,
569  double tolDuring,
570  unsigned int tlEvalMax,
571  unsigned int numStep,
572  OutputStream* messageHandler,
573  OutputStream* profiler,
574  bool reparametrization,
575  unsigned int verbose,
576  const std::string& optMethodDeriv,
577  unsigned int nStep,
578  const std::string& nniMethod)
579 throw (Exception)
580 {
581  // Roughly optimize parameter
582  if (optimizeNumFirst)
583  {
584  OptimizationTools::optimizeNumericalParameters(tl, parameters, NULL, nStep, tolBefore, 1000000, messageHandler, profiler, reparametrization, verbose, optMethodDeriv);
585  }
586  // Begin topo search:
587  NNITopologySearch topoSearch(*tl, nniMethod, verbose > 2 ? verbose - 2 : 0);
588  NNITopologyListener* topoListener = new NNITopologyListener(&topoSearch, parameters, tolDuring, messageHandler, profiler, verbose, optMethodDeriv, nStep, reparametrization);
589  topoListener->setNumericalOptimizationCounter(numStep);
590  topoSearch.addTopologyListener(topoListener);
591  topoSearch.search();
592  return dynamic_cast<NNIHomogeneousTreeLikelihood*>(topoSearch.getSearchableObject());
593 }
594 
595 /******************************************************************************/
596 
599  const ParameterList& parameters,
600  bool optimizeNumFirst,
601  double tolBefore,
602  double tolDuring,
603  unsigned int tlEvalMax,
604  unsigned int numStep,
605  OutputStream* messageHandler,
606  OutputStream* profiler,
607  bool reparametrization,
608  unsigned int verbose,
609  const std::string& optMethodDeriv,
610  const std::string& nniMethod)
611 throw (Exception)
612 {
613  // Roughly optimize parameter
614  if (optimizeNumFirst)
615  {
616  OptimizationTools::optimizeNumericalParameters2(tl, parameters, NULL, tolBefore, 1000000, messageHandler, profiler, reparametrization, false, verbose, optMethodDeriv);
617  }
618  // Begin topo search:
619  NNITopologySearch topoSearch(*tl, nniMethod, verbose > 2 ? verbose - 2 : 0);
620  NNITopologyListener2* topoListener = new NNITopologyListener2(&topoSearch, parameters, tolDuring, messageHandler, profiler, verbose, optMethodDeriv, reparametrization);
621  topoListener->setNumericalOptimizationCounter(numStep);
622  topoSearch.addTopologyListener(topoListener);
623  topoSearch.search();
624  return dynamic_cast<NNIHomogeneousTreeLikelihood*>(topoSearch.getSearchableObject());
625 }
626 
627 /******************************************************************************/
628 
631  unsigned int verbose)
632 {
633  NNISearchable* topo = dynamic_cast<NNISearchable*>(tp);
634  NNITopologySearch topoSearch(*topo, NNITopologySearch::PHYML, verbose);
635  topoSearch.search();
636  return dynamic_cast<DRTreeParsimonyScore*>(topoSearch.getSearchableObject());
637 }
638 
639 /******************************************************************************/
640 
641 std::string OptimizationTools::DISTANCEMETHOD_INIT = "init";
642 std::string OptimizationTools::DISTANCEMETHOD_PAIRWISE = "pairwise";
643 std::string OptimizationTools::DISTANCEMETHOD_ITERATIONS = "iterations";
644 
645 /******************************************************************************/
646 
648  DistanceEstimation& estimationMethod,
649  const ParameterList& parametersToIgnore,
650  const std::string& param,
651  unsigned int verbose) throw (Exception)
652 {
653  if (param != DISTANCEMETHOD_PAIRWISE && param != DISTANCEMETHOD_INIT)
654  throw Exception("OptimizationTools::estimateDistanceMatrix. Invalid option param=" + param + ".");
655  estimationMethod.resetAdditionalParameters();
656  estimationMethod.setVerbose(verbose);
657  if (param == DISTANCEMETHOD_PAIRWISE)
658  {
659  ParameterList tmp = estimationMethod.getSubstitutionModel().getIndependentParameters();
660  tmp.addParameters(estimationMethod.getRateDistribution().getIndependentParameters());
661  tmp.deleteParameters(parametersToIgnore.getParameterNames());
662  estimationMethod.setAdditionalParameters(tmp);
663  }
664  // Compute matrice:
665  if (verbose > 0)
666  ApplicationTools::displayTask("Estimating distance matrix", true);
667  estimationMethod.computeMatrix();
668  auto_ptr<DistanceMatrix> matrix(estimationMethod.getMatrix());
669  if (verbose > 0)
670  ApplicationTools::displayTaskDone();
671 
672  return matrix.release();
673 }
674 
675 /******************************************************************************/
676 
678  DistanceEstimation& estimationMethod,
679  AgglomerativeDistanceMethod& reconstructionMethod,
680  const ParameterList& parametersToIgnore,
681  bool optimizeBrLen,
682  const std::string& param,
683  double tolerance,
684  unsigned int tlEvalMax,
685  OutputStream* profiler,
686  OutputStream* messenger,
687  unsigned int verbose) throw (Exception)
688 {
689  estimationMethod.resetAdditionalParameters();
690  estimationMethod.setVerbose(verbose);
691  if (param == DISTANCEMETHOD_PAIRWISE)
692  {
693  ParameterList tmp = estimationMethod.getSubstitutionModel().getIndependentParameters();
694  tmp.addParameters(estimationMethod.getRateDistribution().getIndependentParameters());
695  tmp.deleteParameters(parametersToIgnore.getParameterNames());
696  estimationMethod.setAdditionalParameters(tmp);
697  }
698  TreeTemplate<Node>* tree = NULL;
699  TreeTemplate<Node>* previousTree = NULL;
700  bool test = true;
701  while (test)
702  {
703  // Compute matrice:
704  if (verbose > 0)
705  ApplicationTools::displayTask("Estimating distance matrix", true);
706  estimationMethod.computeMatrix();
707  DistanceMatrix* matrix = estimationMethod.getMatrix();
708  if (verbose > 0)
709  ApplicationTools::displayTaskDone();
710 
711  // Compute tree:
712  if (verbose > 0)
713  ApplicationTools::displayTask("Building tree");
714  reconstructionMethod.setDistanceMatrix(*matrix);
715  reconstructionMethod.computeTree();
716  previousTree = tree;
717  delete matrix;
718  tree = dynamic_cast<TreeTemplate<Node>*>(reconstructionMethod.getTree());
719  if (verbose > 0)
720  ApplicationTools::displayTaskDone();
721  if (previousTree && verbose > 0)
722  {
723  int rf = TreeTools::robinsonFouldsDistance(*previousTree, *tree, false);
724  ApplicationTools::displayResult("Topo. distance with previous iteration", TextTools::toString(rf));
725  test = (rf == 0);
726  delete previousTree;
727  }
728  if (param != DISTANCEMETHOD_ITERATIONS)
729  break; // Ends here.
730 
731  // Now, re-estimate parameters:
732  auto_ptr<SubstitutionModel> model(estimationMethod.getSubstitutionModel().clone());
733  auto_ptr<DiscreteDistribution> rdist(estimationMethod.getRateDistribution().clone());
735  *estimationMethod.getData(),
736  model.get(),
737  rdist.get(),
738  true, verbose > 1);
739  tl.initialize();
740  ParameterList parameters = tl.getParameters();
741  if (!optimizeBrLen)
742  {
743  vector<string> vs = tl.getBranchLengthsParameters().getParameterNames();
744  parameters.deleteParameters(vs);
745  }
746  parameters.deleteParameters(parametersToIgnore.getParameterNames());
747  optimizeNumericalParameters(&tl, parameters, NULL, 0, tolerance, tlEvalMax, messenger, profiler, verbose > 0 ? verbose - 1 : 0);
748  if (verbose > 0)
749  {
750  ParameterList tmp = tl.getSubstitutionModelParameters();
751  for (unsigned int i = 0; i < tmp.size(); i++)
752  {
753  ApplicationTools::displayResult(tmp[i].getName(), TextTools::toString(tmp[i].getValue()));
754  }
755  tmp = tl.getRateDistributionParameters();
756  for (unsigned int i = 0; i < tmp.size(); i++)
757  {
758  ApplicationTools::displayResult(tmp[i].getName(), TextTools::toString(tmp[i].getValue()));
759  }
760  }
761  }
762  return tree;
763 }
764 
765 /******************************************************************************/
766 
static NNIHomogeneousTreeLikelihood * optimizeTreeNNI(NNIHomogeneousTreeLikelihood *tl, const ParameterList &parameters, bool optimizeNumFirst=true, double tolBefore=100, double tolDuring=100, unsigned int tlEvalMax=1000000, unsigned int numStep=1, OutputStream *messageHandler=ApplicationTools::message, OutputStream *profiler=ApplicationTools::message, bool reparametrization=false, unsigned int verbose=1, const std::string &optMethod=OptimizationTools::OPTIMIZATION_NEWTON, unsigned int nStep=1, const std::string &nniMethod=NNITopologySearch::PHYML)
Optimize all parameters from a TreeLikelihood object, including tree topology using Nearest Neighbor ...
void setNumericalOptimizationCounter(unsigned int c)
static unsigned int optimizeBranchLengthsParameters(DiscreteRatesAcrossSitesTreeLikelihood *tl, const ParameterList &parameters, OptimizationListener *listener=0, double tolerance=0.000001, unsigned int tlEvalMax=1000000, OutputStream *messageHandler=ApplicationTools::message, OutputStream *profiler=ApplicationTools::message, unsigned int verbose=1, const std::string &optMethodDeriv=OPTIMIZATION_NEWTON)
Optimize branch lengths parameters of a TreeLikelihood function.
static unsigned int optimizeNumericalParametersWithGlobalClock2(DiscreteRatesAcrossSitesClockTreeLikelihood *cl, const ParameterList &parameters, OptimizationListener *listener=0, double tolerance=0.000001, unsigned int tlEvalMax=1000000, OutputStream *messageHandler=ApplicationTools::message, OutputStream *profiler=ApplicationTools::message, unsigned int verbose=1, const std::string &optMethodDeriv=OPTIMIZATION_GRADIENT)
Optimize numerical parameters assuming a global clock (branch heights, substitution model & rate dist...
static DistanceMatrix * estimateDistanceMatrix(DistanceEstimation &estimationMethod, const ParameterList &parametersToIgnore, const std::string &param=DISTANCEMETHOD_INIT, unsigned int verbose=0)
Estimate a distance matrix using maximum likelihood.
static std::string DISTANCEMETHOD_PAIRWISE
Listener used internally by the optimizeTreeNNI2 method.
void search()
Performs the search.
virtual ParameterList getBranchLengthsParameters() const =0
Get the branch lengths parameters.
void setParameters(const ParameterList &lambda)
The TreeLikelihood interface.
A listener which capture NaN function values and throw an exception in case this happens.
Double recursive implementation of interface TreeParsimonyScore.
static std::string DISTANCEMETHOD_INIT
STL namespace.
Interface for Nearest Neighbor Interchanges algorithms.
Definition: NNISearchable.h:96
The phylogenetic tree class.
static TreeTemplate< Node > * buildDistanceTree(DistanceEstimation &estimationMethod, AgglomerativeDistanceMethod &reconstructionMethod, const ParameterList &parametersToIgnore, bool optimizeBrLen=false, const std::string &param=DISTANCEMETHOD_INIT, double tolerance=0.000001, unsigned int tlEvalMax=1000000, OutputStream *profiler=0, OutputStream *messenger=0, unsigned int verbose=0)
Build a tree using a distance method.
static std::string OPTIMIZATION_GRADIENT
This class adds support for NNI topology estimation to the DRHomogeneousTreeLikelihood class...
static std::string DISTANCEMETHOD_ITERATIONS
Interface for agglomerative distance methods.
void addTopologyListener(TopologyListener *listener)
Add a listener to the list.
static unsigned int optimizeNumericalParameters(DiscreteRatesAcrossSitesTreeLikelihood *tl, const ParameterList &parameters, OptimizationListener *listener=0, unsigned int nstep=1, double tolerance=0.000001, unsigned int tlEvalMax=1000000, OutputStream *messageHandler=ApplicationTools::message, OutputStream *profiler=ApplicationTools::message, bool reparametrization=false, unsigned int verbose=1, const std::string &optMethodDeriv=OPTIMIZATION_NEWTON, const std::string &optMethodModel=OPTIMIZATION_BRENT)
Optimize numerical parameters (branch length, substitution model & rate distribution) of a TreeLikeli...
Interface for rate across sites (RAS) implementation.
This class implements the likelihood computation for a tree using the double-recursive algorithm...
static std::string OPTIMIZATION_BRENT
static unsigned int optimizeNumericalParameters2(DiscreteRatesAcrossSitesTreeLikelihood *tl, const ParameterList &parameters, OptimizationListener *listener=0, double tolerance=0.000001, unsigned int tlEvalMax=1000000, OutputStream *messageHandler=ApplicationTools::message, OutputStream *profiler=ApplicationTools::message, bool reparametrization=false, bool useClock=false, unsigned int verbose=1, const std::string &optMethodDeriv=OPTIMIZATION_NEWTON)
Optimize numerical parameters (branch length, substitution model & rate distribution) of a TreeLikeli...
void setNumericalOptimizationCounter(unsigned int c)
Interface for likelihood computation with a global clock and rate across sites variation.
This Optimizer implements Newton&#39;s algorithm for finding a minimum of a function. This is in fact a m...
Class for notifying new toplogy change events.
NNISearchable * getSearchableObject()
void topologyChangeSuccessful(const TopologyChangeEvent &event)
Tell that a topology change is definitive.
static const std::string PHYML
const ParameterList & getParameters() const
static NNIHomogeneousTreeLikelihood * optimizeTreeNNI2(NNIHomogeneousTreeLikelihood *tl, const ParameterList &parameters, bool optimizeNumFirst=true, double tolBefore=100, double tolDuring=100, unsigned int tlEvalMax=1000000, unsigned int numStep=1, OutputStream *messageHandler=ApplicationTools::message, OutputStream *profiler=ApplicationTools::message, bool reparametrization=false, unsigned int verbose=1, const std::string &optMethod=OptimizationTools::OPTIMIZATION_NEWTON, const std::string &nniMethod=NNITopologySearch::PHYML)
Optimize all parameters from a TreeLikelihood object, including tree topology using Nearest Neighbor ...
void topologyChangeSuccessful(const TopologyChangeEvent &event)
Tell that a topology change is definitive.
Estimate a distance matrix from sequence data, according to a given model.
static std::string OPTIMIZATION_BFGS
static unsigned int optimizeTreeScale(TreeLikelihood *tl, double tolerance=0.000001, unsigned int tlEvalMax=1000000, OutputStream *messageHandler=ApplicationTools::message, OutputStream *profiler=ApplicationTools::message, unsigned int verbose=1)
Optimize the scale of a TreeLikelihood.
Listener used internally by the optimizeTreeNNI method.
static std::string OPTIMIZATION_NEWTON
static unsigned int optimizeNumericalParametersWithGlobalClock(DiscreteRatesAcrossSitesClockTreeLikelihood *cl, const ParameterList &parameters, OptimizationListener *listener=0, unsigned int nstep=1, double tolerance=0.000001, unsigned int tlEvalMax=1000000, OutputStream *messageHandler=ApplicationTools::message, OutputStream *profiler=ApplicationTools::message, unsigned int verbose=1, const std::string &optMethodDeriv=OPTIMIZATION_GRADIENT)
Optimize numerical parameters assuming a global clock (branch heights, substitution model & rate dist...
NNI topology search method.
static int robinsonFouldsDistance(const Tree &tr1, const Tree &tr2, bool checkNames=true, int *missing_in_tr2=NULL, int *missing_in_tr1=NULL)
Calculates the Robinson-Foulds topological distance between two trees.
Definition: TreeTools.cpp:892