bpp-core3  3.0.0
ReparametrizationFunctionWrapper.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #include <typeinfo>
6 
7 #include "../../App/ApplicationTools.h"
9 
10 using namespace bpp;
11 using namespace std;
12 
14 {
15  for (size_t i = 0; i < functionParameters_.size(); i++)
16  {
17  Parameter& p = functionParameters_[i];
18  auto constraint = p.getConstraint();
19  const string name = p.getName();
20  double value = p.getValue();
21  if (!constraint)
22  {
23  if (verbose)
24  ApplicationTools::displayMessage("Parameter " + name + " does not need to be transformed.");
25  addParameter_(new PlaceboTransformedParameter(name, value));
26  }
27  else
28  {
29  auto interval = dynamic_pointer_cast<IntervalConstraint>(constraint);
30  if (interval)
31  {
32  bool isInfinite = (!interval->finiteLowerBound()) || (!interval->finiteUpperBound());
33  if (!isInfinite)
34  {
35  if (!interval->strictLowerBound() && !interval->strictUpperBound())
36  {
37  // Case 1: [a,b]
38  // This solves an issue if the original value is at the bound.
39  double correctedValue = value;
40  if (abs(value - interval->getLowerBound()) < NumConstants::TINY())
41  correctedValue = interval->getLowerBound() + NumConstants::TINY();
42  if (abs(value - interval->getUpperBound()) < NumConstants::TINY())
43  correctedValue = interval->getUpperBound() - NumConstants::TINY();
44  IntervalTransformedParameter* pp = new IntervalTransformedParameter(name, correctedValue, interval->getLowerBound(), interval->getUpperBound());
45  addParameter_(pp);
46  if (verbose)
47  ApplicationTools::displayMessage("Parameter " + name + " was tanh transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
48  }
49  else if (interval->strictLowerBound() && interval->strictUpperBound())
50  {
51  // Case 2: ]a,b[
52  // We have to correct the bound in order to prevent numerical issues.
53  // It can happens that the original bound is matched because of rounding errors.
54  IntervalTransformedParameter* pp = new IntervalTransformedParameter(name, value, interval->getLowerBound() + NumConstants::TINY(), interval->getUpperBound() - NumConstants::TINY());
55  addParameter_(pp);
56  if (verbose)
57  ApplicationTools::displayMessage("Parameter " + name + " was tanh transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
58  }
59  else if (!interval->strictLowerBound() && interval->strictUpperBound())
60  {
61  // Case 3: [a,b[
62  // This solves an issue if the original value is at the bound.
63  double correctedValue = value;
64  if (abs(value - interval->getLowerBound()) < NumConstants::TINY())
65  correctedValue = interval->getLowerBound() + NumConstants::TINY();
66  IntervalTransformedParameter* pp = new IntervalTransformedParameter(name, correctedValue, interval->getLowerBound(), interval->getUpperBound() - NumConstants::TINY());
67  addParameter_(pp);
68  if (verbose)
69  ApplicationTools::displayMessage("Parameter " + name + " was tanh transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
70  }
71  else if (interval->strictLowerBound() && !interval->strictUpperBound())
72  {
73  // Case 4: ]a,b]
74  // This solve an issue if the original value is at the bound.
75  double correctedValue = value;
76  if (abs(value - interval->getUpperBound()) < NumConstants::TINY())
77  correctedValue = interval->getUpperBound() - NumConstants::TINY();
78  IntervalTransformedParameter* pp = new IntervalTransformedParameter(name, correctedValue, interval->getLowerBound() + NumConstants::TINY(), interval->getUpperBound());
79  addParameter_(pp);
80  if (verbose)
81  ApplicationTools::displayMessage("Parameter " + name + " was tanh transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
82  }
83  }
84  else
85  {
86  if (interval->strictLowerBound() && !interval->finiteUpperBound())
87  {
88  // Case 5: ]a, +inf[
89  RTransformedParameter* pp = new RTransformedParameter(name, value, interval->getLowerBound() + NumConstants::TINY(), true);
90  addParameter_(pp);
91  if (verbose)
92  ApplicationTools::displayMessage("Parameter " + name + " was log transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
93  }
94  else if (!interval->strictLowerBound() && !interval->finiteUpperBound())
95  {
96  // Case 6: [a, +inf[
97  // This solve an issue if the original value is at the bound.
98  double correctedValue = value;
99  if (abs(value - interval->getLowerBound()) < NumConstants::TINY())
100  correctedValue = interval->getLowerBound() + NumConstants::TINY();
101  RTransformedParameter* pp = new RTransformedParameter(name, correctedValue, interval->getLowerBound(), true);
102  addParameter_(pp);
103  if (verbose)
104  ApplicationTools::displayMessage("Parameter " + name + " was log transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
105  }
106  else if (!interval->finiteLowerBound() && interval->strictUpperBound())
107  {
108  // Case 7: ]-inf, a[
109  RTransformedParameter* pp = new RTransformedParameter(name, value, interval->getUpperBound() - NumConstants::TINY(), false);
110  addParameter_(pp);
111  if (verbose)
112  ApplicationTools::displayMessage("Parameter " + name + " was log transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
113  }
114  else if (!interval->finiteLowerBound() && !interval->strictUpperBound())
115  {
116  // Case 8: ]-inf, a]
117  // This solve an issue if the original value is at the bound.
118  double correctedValue = value;
119  if (abs(value - interval->getUpperBound()) < NumConstants::TINY())
120  correctedValue = interval->getUpperBound() - NumConstants::TINY();
121  RTransformedParameter* pp = new RTransformedParameter(name, correctedValue, interval->getUpperBound(), false);
122  addParameter_(pp);
123  if (verbose)
124  ApplicationTools::displayMessage("Parameter " + name + " was log transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
125  }
126  }
127  }
128  else
129  {
130  // Nothing found
131  if (verbose)
132  {
133  ApplicationTools::displayWarning("No transformation found for this constraint '" + constraint->getDescription() + "'! Parameter " + p.getName());
134  }
135  addParameter_(new PlaceboTransformedParameter(name, value));
136  }
137  }
138  }
139 }
140 
142 {
143  // Recompute function parameters:
144  // We could update only the parameter that actually changed,
145  // but that would implied a quick sort on parameter names (nlog(n))
146  // whereas using a loop over the set is in o(n). It should hence be
147  // more efficient in most cases.
148  for (size_t i = 0; i < getNumberOfParameters(); ++i)
149  {
150  double x = dynamic_cast<TransformedParameter&>(getParameter_(i)).getOriginalValue();
151  try
152  {
153  functionParameters_[i].setValue(x);
154  }
155  catch (ConstraintException& ce)
156  {
157  (*ApplicationTools::error << "Oups, value " << x << " led to a constraint exception. The transformed value was " << getParameter_(i).getValue()).endLine();
158  throw ce;
159  }
160  }
161 }
static void displayWarning(const std::string &text)
Print a warning message.
double getLowerBound() const
Definition: Constraints.h:174
An interval, either bounded or not, which can also have infinite bounds.
Definition: Constraints.h:101
void fireParameterChanged(const ParameterList &parameters)
Notify the class when one or several parameters have changed.
STL namespace.
This class is designed to facilitate the manipulation of parameters.
Definition: Parameter.h:97
The parameter list object.
Definition: ParameterList.h:27
&#39;Placebo&#39; parameter transformation from ] b, +inf [ or ] -inf, b [ to ]-inf, + inf [...
virtual std::shared_ptr< const ConstraintInterface > getConstraint() const
Return the constraint associated to this parameter if there is one.
Definition: Parameter.h:196
virtual void setValue(double value)
Set the value of this parameter.
Definition: Parameter.cpp:55
static double TINY()
Definition: NumConstants.h:46
Parameter transformation from ] b, +inf [ or ] -inf, b [ to ]-inf, + inf [.
static std::shared_ptr< OutputStream > error
The output stream where errors have to be displayed.
static void displayMessage(const std::string &text)
Print a message.
virtual const std::string & getName() const
Get the name of this parameter.
Definition: Parameter.h:174
virtual double getValue() const
Get the value of this parameter.
Definition: Parameter.h:181
Exception thrown when a value do not match a given constraint.
std::string toString(T t)
General template method to convert to a string.
Definition: TextTools.h:115
The TransformedParameter abstract class.
Parameter transformation from ] a, b [ to ]-inf, + inf [.