bpp-core3  3.0.0
ReparametrizationFunctionWrapper.cpp
Go to the documentation of this file.
1 //
2 // File: ReparametrizationFunctionWrapper.cpp
3 // Authors:
4 // Julien Dutheil
5 // Created: 2009-01-30 09:30:00
6 //
7 
8 /*
9  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
10 
11  This software is a computer program whose purpose is to provide classes
12  for numerical calculus.
13 
14  This software is governed by the CeCILL license under French law and
15  abiding by the rules of distribution of free software. You can use,
16  modify and/ or redistribute the software under the terms of the CeCILL
17  license as circulated by CEA, CNRS and INRIA at the following URL
18  "http://www.cecill.info".
19 
20  As a counterpart to the access to the source code and rights to copy,
21  modify and redistribute granted by the license, users are provided only
22  with a limited warranty and the software's author, the holder of the
23  economic rights, and the successive licensors have only limited
24  liability.
25 
26  In this respect, the user's attention is drawn to the risks associated
27  with loading, using, modifying and/or developing or reproducing the
28  software by the user in light of its specific status of free software,
29  that may mean that it is complicated to manipulate, and that also
30  therefore means that it is reserved for developers and experienced
31  professionals having in-depth computer knowledge. Users are therefore
32  encouraged to load and test the software's suitability as regards their
33  requirements in conditions enabling the security of their systems and/or
34  data to be ensured and, more generally, to use and operate it in the
35  same conditions as regards security.
36 
37  The fact that you are presently reading this means that you have had
38  knowledge of the CeCILL license and that you accept its terms.
39 */
40 
41 #include <typeinfo>
42 
43 #include "../../App/ApplicationTools.h"
45 
46 using namespace bpp;
47 using namespace std;
48 
50 {
51  for (size_t i = 0; i < functionParameters_.size(); i++)
52  {
53  Parameter& p = functionParameters_[i];
54  std::shared_ptr<Constraint> constraint = p.getConstraint();
55  const string name = p.getName();
56  double value = p.getValue();
57  if (!constraint)
58  {
59  if (verbose)
60  ApplicationTools::displayMessage("Parameter " + name + " does not need to be transformed.");
61  addParameter_(new PlaceboTransformedParameter(name, value));
62  }
63  else
64  {
65  IntervalConstraint* interval = dynamic_cast<IntervalConstraint*>(constraint.get());
66  if (interval)
67  {
68  bool isInfinite = (!interval->finiteLowerBound()) || (!interval->finiteUpperBound());
69  if (!isInfinite)
70  {
71  if (!interval->strictLowerBound() && !interval->strictUpperBound())
72  {
73  // Case 1: [a,b]
74  // This solves an issue if the original value is at the bound.
75  double correctedValue = value;
76  if (abs(value - interval->getLowerBound()) < NumConstants::TINY())
77  correctedValue = interval->getLowerBound() + NumConstants::TINY();
78  if (abs(value - interval->getUpperBound()) < NumConstants::TINY())
79  correctedValue = interval->getUpperBound() - NumConstants::TINY();
80  IntervalTransformedParameter* pp = new IntervalTransformedParameter(name, correctedValue, interval->getLowerBound(), interval->getUpperBound());
81  addParameter_(pp);
82  if (verbose)
83  ApplicationTools::displayMessage("Parameter " + name + " was tanh transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
84  }
85  else if (interval->strictLowerBound() && interval->strictUpperBound())
86  {
87  // Case 2: ]a,b[
88  // We have to correct the bound in order to prevent numerical issues.
89  // It can happens that the original bound is matched because of rounding errors.
91  addParameter_(pp);
92  if (verbose)
93  ApplicationTools::displayMessage("Parameter " + name + " was tanh transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
94  }
95  else if (!interval->strictLowerBound() && interval->strictUpperBound())
96  {
97  // Case 3: [a,b[
98  // This solves an issue if the original value is at the bound.
99  double correctedValue = value;
100  if (abs(value - interval->getLowerBound()) < NumConstants::TINY())
101  correctedValue = interval->getLowerBound() + NumConstants::TINY();
102  IntervalTransformedParameter* pp = new IntervalTransformedParameter(name, correctedValue, interval->getLowerBound(), interval->getUpperBound() - NumConstants::TINY());
103  addParameter_(pp);
104  if (verbose)
105  ApplicationTools::displayMessage("Parameter " + name + " was tanh transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
106  }
107  else if (interval->strictLowerBound() && !interval->strictUpperBound())
108  {
109  // Case 4: ]a,b]
110  // This solve an issue if the original value is at the bound.
111  double correctedValue = value;
112  if (abs(value - interval->getUpperBound()) < NumConstants::TINY())
113  correctedValue = interval->getUpperBound() - NumConstants::TINY();
114  IntervalTransformedParameter* pp = new IntervalTransformedParameter(name, correctedValue, interval->getLowerBound() + NumConstants::TINY(), interval->getUpperBound());
115  addParameter_(pp);
116  if (verbose)
117  ApplicationTools::displayMessage("Parameter " + name + " was tanh transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
118  }
119  }
120  else
121  {
122  if (interval->strictLowerBound() && !interval->finiteUpperBound())
123  {
124  // Case 5: ]a, +inf[
125  RTransformedParameter* pp = new RTransformedParameter(name, value, interval->getLowerBound() + NumConstants::TINY(), true);
126  addParameter_(pp);
127  if (verbose)
128  ApplicationTools::displayMessage("Parameter " + name + " was log transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
129  }
130  else if (!interval->strictLowerBound() && !interval->finiteUpperBound())
131  {
132  // Case 6: [a, +inf[
133  // This solve an issue if the original value is at the bound.
134  double correctedValue = value;
135  if (abs(value - interval->getLowerBound()) < NumConstants::TINY())
136  correctedValue = interval->getLowerBound() + NumConstants::TINY();
137  RTransformedParameter* pp = new RTransformedParameter(name, correctedValue, interval->getLowerBound(), true);
138  addParameter_(pp);
139  if (verbose)
140  ApplicationTools::displayMessage("Parameter " + name + " was log transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
141  }
142  else if (!interval->finiteLowerBound() && interval->strictUpperBound())
143  {
144  // Case 7: ]-inf, a[
145  RTransformedParameter* pp = new RTransformedParameter(name, value, interval->getUpperBound() - NumConstants::TINY(), false);
146  addParameter_(pp);
147  if (verbose)
148  ApplicationTools::displayMessage("Parameter " + name + " was log transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
149  }
150  else if (!interval->finiteLowerBound() && !interval->strictUpperBound())
151  {
152  // Case 8: ]-inf, a]
153  // This solve an issue if the original value is at the bound.
154  double correctedValue = value;
155  if (abs(value - interval->getUpperBound()) < NumConstants::TINY())
156  correctedValue = interval->getUpperBound() - NumConstants::TINY();
157  RTransformedParameter* pp = new RTransformedParameter(name, correctedValue, interval->getUpperBound(), false);
158  addParameter_(pp);
159  if (verbose)
160  ApplicationTools::displayMessage("Parameter " + name + " was log transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
161  }
162  }
163  }
164  else
165  {
166  // Nothing found
167  if (verbose)
168  {
169  ApplicationTools::displayWarning("No transformation found for this constraint '" + constraint->getDescription() + "'! Parameter " + p.getName());
170  }
171  addParameter_(new PlaceboTransformedParameter(name, value));
172  }
173  }
174  }
175 }
176 
178 {
179  // Recompute function parameters:
180  // We could update only the parameter that actually changed,
181  // but that would implied a quick sort on parameter names (nlog(n))
182  // whereas using a loop over the set is in o(n). It should hence be
183  // more efficient in most cases.
184  for (size_t i = 0; i < getNumberOfParameters(); ++i)
185  {
186  double x = dynamic_cast<TransformedParameter&>(getParameter_(i)).getOriginalValue();
187  try
188  {
189  functionParameters_[i].setValue(x);
190  }
191  catch (ConstraintException& ce)
192  {
193  (*ApplicationTools::error << "Oups, value " << x << " led to a constraint exception. The transformed value was " << getParameter_(i).getValue()).endLine();
194  throw ce;
195  }
196  }
197 }
static void displayMessage(const std::string &text)
Print a message.
static std::shared_ptr< OutputStream > error
The output stream where errors have to be displayed.
static void displayWarning(const std::string &text)
Print a warning message.
Exception thrown when a value do not match a given constraint.
An interval, either bounded or not, which can also have infinite bounds.
Definition: Constraints.h:139
double getLowerBound() const
Definition: Constraints.h:215
bool strictLowerBound() const
Definition: Constraints.h:218
bool finiteLowerBound() const
Definition: Constraints.h:221
bool strictUpperBound() const
Definition: Constraints.h:219
bool finiteUpperBound() const
Definition: Constraints.h:222
double getUpperBound() const
Definition: Constraints.h:216
Parameter transformation from ] a, b [ to ]-inf, + inf [.
static double TINY()
Definition: NumConstants.h:82
The parameter list object.
Definition: ParameterList.h:65
This class is designed to facilitate the manipulation of parameters.
Definition: Parameter.h:135
virtual void setValue(double value)
Set the value of this parameter.
Definition: Parameter.cpp:110
virtual const std::shared_ptr< Constraint > getConstraint() const
Return the constraint associated to this parameter if there is one.
Definition: Parameter.h:233
virtual double getValue() const
Get the value of this parameter.
Definition: Parameter.h:218
virtual const std::string & getName() const
Get the name of this parameter.
Definition: Parameter.h:211
'Placebo' parameter transformation from ] b, +inf [ or ] -inf, b [ to ]-inf, + inf [.
Parameter transformation from ] b, +inf [ or ] -inf, b [ to ]-inf, + inf [.
void fireParameterChanged(const ParameterList &parameters)
Notify the class when one or several parameters have changed.
The TransformedParameter abstract class.
std::string toString(T t)
General template method to convert to a string.
Definition: TextTools.h:153