bpp-core  2.2.0
ReparametrizationFunctionWrapper.cpp
Go to the documentation of this file.
1 //
2 // File: ReparametrizationFunctionWrapper.h
3 // Created by: Julien Dutheil
4 // Created on: Fri Jan 30 09:30 2009
5 //
6 
7 /*
8  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
9 
10  This software is a computer program whose purpose is to provide classes
11  for numerical calculus.
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 
41 #include "../../App/ApplicationTools.h"
42 #include <typeinfo>
43 using namespace bpp;
44 using namespace std;
45 
47 {
48  for (size_t i = 0; i < functionParameters_.size(); i++)
49  {
50  Parameter& p = functionParameters_[i];
51  Constraint* constraint = p.getConstraint();
52  const string name = p.getName();
53  double value = p.getValue();
54  if (!constraint)
55  {
56  if (verbose)
57  ApplicationTools::displayMessage("Parameter " + name + " does not need to be transformed.");
58  addParameter_(new PlaceboTransformedParameter(name, value));
59  }
60  else
61  {
62  IntervalConstraint* interval = dynamic_cast<IntervalConstraint*>(constraint);
63  if (interval) {
64  bool isInfinite = (!interval->finiteLowerBound()) || (!interval->finiteUpperBound());
65  if (!isInfinite)
66  {
67  if (!interval->strictLowerBound() && !interval->strictUpperBound())
68  {
69  // Case 1: [a,b]
70  // This solves an issue if the original value is at the bound.
71  double correctedValue = value;
72  if (abs(value - interval->getLowerBound()) < NumConstants::TINY())
73  correctedValue = interval->getLowerBound() + NumConstants::TINY();
74  if (abs(value - interval->getUpperBound()) < NumConstants::TINY())
75  correctedValue = interval->getUpperBound() - NumConstants::TINY();
76  IntervalTransformedParameter* pp = new IntervalTransformedParameter(name, correctedValue, interval->getLowerBound(), interval->getUpperBound());
77  addParameter_(pp);
78  if (verbose)
79  ApplicationTools::displayMessage("Parameter " + name + " was tanh transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
80  }
81  else if (interval->strictLowerBound() && interval->strictUpperBound())
82  {
83  // Case 2: ]a,b[
84  // We have to correct the bound in order to prevent numerical issues.
85  // It can happens that the original bound is matched because of rounding errors.
87  addParameter_(pp);
88  if (verbose)
89  ApplicationTools::displayMessage("Parameter " + name + " was tanh transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
90  }
91  else if (!interval->strictLowerBound() && interval->strictUpperBound())
92  {
93  // Case 3: [a,b[
94  // This solves an issue if the original value is at the bound.
95  double correctedValue = value;
96  if (abs(value - interval->getLowerBound()) < NumConstants::TINY())
97  correctedValue = interval->getLowerBound() + NumConstants::TINY();
98  IntervalTransformedParameter* pp = new IntervalTransformedParameter(name, correctedValue, interval->getLowerBound(), interval->getUpperBound() - NumConstants::TINY());
99  addParameter_(pp);
100  if (verbose)
101  ApplicationTools::displayMessage("Parameter " + name + " was tanh transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
102  }
103  else if (interval->strictLowerBound() && !interval->strictUpperBound())
104  {
105  // Case 4: ]a,b]
106  // This solve an issue if the original value is at the bound.
107  double correctedValue = value;
108  if (abs(value - interval->getUpperBound()) < NumConstants::TINY())
109  correctedValue = interval->getUpperBound() - NumConstants::TINY();
110  IntervalTransformedParameter* pp = new IntervalTransformedParameter(name, correctedValue, interval->getLowerBound() + NumConstants::TINY(), interval->getUpperBound());
111  addParameter_(pp);
112  if (verbose)
113  ApplicationTools::displayMessage("Parameter " + name + " was tanh transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
114  }
115  }
116  else
117  {
118  if (interval->strictLowerBound() && !interval->finiteUpperBound())
119  {
120  // Case 5: ]a, +inf[
121  RTransformedParameter* pp = new RTransformedParameter(name, value, interval->getLowerBound() + NumConstants::TINY(), true);
122  addParameter_(pp);
123  if (verbose)
124  ApplicationTools::displayMessage("Parameter " + name + " was log transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
125  }
126  else if (!interval->strictLowerBound() && !interval->finiteUpperBound())
127  {
128  // Case 6: [a, +inf[
129  // This solve an issue if the original value is at the bound.
130  double correctedValue = value;
131  if (abs(value - interval->getLowerBound()) < NumConstants::TINY())
132  correctedValue = interval->getLowerBound() + NumConstants::TINY();
133  RTransformedParameter* pp = new RTransformedParameter(name, correctedValue, interval->getLowerBound(), true);
134  addParameter_(pp);
135  if (verbose)
136  ApplicationTools::displayMessage("Parameter " + name + " was log transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
137  }
138  else if (!interval->finiteLowerBound() && interval->strictUpperBound())
139  {
140  // Case 7: ]-inf, a[
141  RTransformedParameter* pp = new RTransformedParameter(name, value, interval->getUpperBound() - NumConstants::TINY(), false);
142  addParameter_(pp);
143  if (verbose)
144  ApplicationTools::displayMessage("Parameter " + name + " was log transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
145  }
146  else if (!interval->finiteLowerBound() && !interval->strictUpperBound())
147  {
148  // Case 8: ]-inf, a]
149  // This solve an issue if the original value is at the bound.
150  double correctedValue = value;
151  if (abs(value - interval->getUpperBound()) < NumConstants::TINY())
152  correctedValue = interval->getUpperBound() - NumConstants::TINY();
153  RTransformedParameter* pp = new RTransformedParameter(name, correctedValue, interval->getUpperBound(), false);
154  addParameter_(pp);
155  if (verbose)
156  ApplicationTools::displayMessage("Parameter " + name + " was log transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
157  }
158  }
159  }
160  else
161  {
162  // Nothing found
163  if (verbose)
164  {
165  ApplicationTools::displayWarning("No transformation found for this constraint '" + constraint->getDescription() + "'! Parameter " + p.getName());
166  }
167  addParameter_(new PlaceboTransformedParameter(name, value));
168  }
169  }
170  }
171 }
172 
174 {
175  // Recompute function parameters:
176  // We could update only the parameter that actually changed,
177  // but that would implied a quick sort on parameter names (nlog(n))
178  // whereas using a loop over the set is in o(n). It should hence be
179  // more efficient in most cases.
180  for (size_t i = 0; i < getNumberOfParameters(); ++i)
181  {
182  double x = dynamic_cast<TransformedParameter&>(getParameter_(i)).getOriginalValue();
183  try
184  {
185  functionParameters_[i].setValue(x);
186  }
187  catch (ConstraintException& ce)
188  {
189  (*ApplicationTools::error << "Oups, value " << x << " led to a constraint exception. The transformed value was " << getParameter_(i).getValue()).endLine();
190  throw ce;
191  }
192  }
193 }
194 
static void displayWarning(const std::string &text)
Print a warning message.
double getLowerBound() const
Definition: Constraints.h:213
virtual const Constraint * getConstraint() const
Return the constraint associated to this parameter if there is one.
Definition: Parameter.h:255
bool strictLowerBound() const
Definition: Constraints.h:216
An interval, either bounded or not, which can also have infinite bounds.
Definition: Constraints.h:135
This class allows to perform a correspondence analysis.
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:135
static std::string toString(T t)
General template method to convert to a string.
Definition: TextTools.h:189
The parameter list object.
Definition: ParameterList.h:61
&#39;Placebo&#39; parameter transformation from ] b, +inf [ or ] -inf, b [ to ]-inf, + inf [...
bool finiteLowerBound() const
Definition: Constraints.h:219
virtual void setValue(double value)
Set the value of this parameter.
Definition: Parameter.cpp:123
bool strictUpperBound() const
Definition: Constraints.h:217
static double TINY()
Definition: NumConstants.h:81
bool finiteUpperBound() const
Definition: Constraints.h:220
virtual std::string getDescription() const =0
Give a short description on the type of constraint.
Parameter transformation from ] b, +inf [ or ] -inf, b [ to ]-inf, + inf [.
The constraint interface.
Definition: Constraints.h:62
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:234
static OutputStream * error
The output stream where errors have to be displayed.
virtual double getValue() const
Get the value of this parameter.
Definition: Parameter.h:241
Exception thrown when a value do not match a given constraint.
double getUpperBound() const
Definition: Constraints.h:214
The TransformedParameter abstract class.
Parameter transformation from ] a, b [ to ]-inf, + inf [.