bpp-core3  3.0.0
FivePointsNumericalDerivative.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
6 
7 using namespace bpp;
8 using namespace std;
9 
11 {
12  if (computeD1_ && variables_.size() > 0)
13  {
14  if (function1_)
15  function1_->enableFirstOrderDerivatives(false);
16  if (function2_)
17  function2_->enableSecondOrderDerivatives(false);
18  function_->setParameters(parameters);
19  f3_ = function_->getValue();
20  string lastVar;
21  bool functionChanged = false;
22  ParameterList p;
23  bool start = true;
24  for (size_t i = 0; i < variables_.size(); ++i)
25  {
26  string var = variables_[i];
27  if (!parameters.hasParameter(var))
28  continue;
29  if (!start)
30  {
31  vector<string> vars(2);
32  vars[0] = var;
33  vars[1] = lastVar;
34  p = parameters.createSubList(vars);
35  }
36  else
37  {
38  p = parameters.createSubList(var);
39  start = false;
40  }
41  lastVar = var;
42  functionChanged = true;
43  double value = function_->getParameterValue(var);
44  double h = (1. + std::abs(value)) * h_;
45  // Compute four other points:
46  try
47  {
48  p[0].setValue(value - 2 * h);
49  function_->setParameters(p);
50  f1_ = function_->getValue();
51  try
52  {
53  p[0].setValue(value + 2 * h);
54  function_->setParameters(p);
55  f5_ = function_->getValue();
56  // No limit raised, use central approximation:
57  p[0].setValue(value - h);
58  function_->setParameters(p);
59  f2_ = function_->getValue();
60  p[0].setValue(value + h);
61  function_->setParameters(p);
62  f4_ = function_->getValue();
63  der1_[i] = (f1_ - 8. * f2_ + 8. * f4_ - f5_) / (12. * h);
64  der2_[i] = (-f1_ + 16. * f2_ - 30. * f3_ + 16. * f4_ - f5_) / (12. * h * h);
65  }
66  catch (ConstraintException& ce)
67  {
68  // Right limit raised, use backward approximation:
69  p[0].setValue(value - h);
70  function_->setParameters(p);
71  f2_ = function_->getValue();
72  p[0].setValue(value - 2 * h);
73  function_->setParameters(p);
74  f1_ = function_->getValue();
75  der1_[i] = (f3_ - f2_) / h;
76  der2_[i] = (f3_ - 2. * f2_ + f1_) / (h * h);
77  }
78  }
79  catch (ConstraintException& ce)
80  {
81  // Left limit raised, use forward approximation:
82  p[0].setValue(value + h);
83  function_->setParameters(p);
84  f4_ = function_->getValue();
85  p[0].setValue(value + 2 * h);
86  function_->setParameters(p);
87  f5_ = function_->getValue();
88  der1_[i] = (f4_ - f3_) / h;
89  der2_[i] = (f5_ - 2. * f4_ + f3_) / (h * h);
90  }
91  }
92  // Reset last parameter and compute analytical derivatives if any.
93  if (function1_)
94  function1_->enableFirstOrderDerivatives(computeD1_);
95  if (function2_)
96  function2_->enableSecondOrderDerivatives(computeD2_);
97  if (functionChanged)
98  function_->setParameters(parameters.createSubList(lastVar));
99  }
100  else
101  {
102  // Reset initial value and compute analytical derivatives if any.
103  if (function1_)
104  function1_->enableFirstOrderDerivatives(computeD1_);
105  if (function2_)
106  function2_->enableSecondOrderDerivatives(computeD2_);
107  function_->setParameters(parameters);
108  // Just in case derivatives are not computed:
109  f3_ = function_->getValue();
110  }
111 }
virtual ParameterList createSubList(const std::vector< std::string > &names) const
Get given parameters as a sublist.
virtual double getParameterValue(const std::string &name) const
Get the value of the parameter with name name.
STL namespace.
The parameter list object.
Definition: ParameterList.h:27
void updateDerivatives(const ParameterList &parameters) override
Compute derivatives.
virtual bool hasParameter(const std::string &name) const
virtual void setParameters(const ParameterList &params)
Update the parameters from params.
Exception thrown when a value do not match a given constraint.