bpp-core3  3.0.0
TransformedParameter.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #ifndef BPP_NUMERIC_TRANSFORMEDPARAMETER_H
6 #define BPP_NUMERIC_TRANSFORMEDPARAMETER_H
7 
8 #include <cmath>
9 
10 #include "NumConstants.h"
11 #include "Parameter.h"
12 
13 namespace bpp
14 {
24  public Parameter
25 {
26 public:
27  TransformedParameter(const std::string& name, double value) :
28  Parameter(name, value) {}
29 
30  TransformedParameter* clone() const = 0;
31 
32 public:
39  virtual void setOriginalValue(double value) = 0;
40 
44  virtual double getOriginalValue() const = 0;
45 
51  virtual double getFirstOrderDerivative() const = 0;
52 
58  virtual double getSecondOrderDerivative() const = 0;
59 };
60 
83 {
84 private:
85  double scale_;
86  double bound_;
87  bool positive_;
88 
89 public:
99  RTransformedParameter(const std::string& name, double value, double bound = 0, bool positive = true, double scale = 1) :
100  TransformedParameter(name, 1.),
101  scale_(scale),
102  bound_(bound),
103  positive_(positive)
104  {
105  setOriginalValue(value);
106  }
107 
108  RTransformedParameter* clone() const { return new RTransformedParameter(*this); }
109 
110 public:
111  void setOriginalValue(double value)
112  {
113  if (positive_ ? value <= bound_ : value >= bound_) throw ConstraintException("RTransformedParameter::setValue", this, value);
114  if (positive_ & (value < 1 + bound_)) setValue(log(scale_ * (value - bound_)));
115  if (positive_ & (value >= 1 + bound_)) setValue(scale_ * (value - 1. - bound_));
116  if (!positive_ & (value > -1 + bound_)) setValue(log(-scale_ * (value - bound_)));
117  if (!positive_ & (value <= -1 + bound_)) setValue(-scale_ * (value - 1. - bound_));
118  }
119 
120  double getOriginalValue() const
121  {
122  double x = getValue();
123  if (positive_)
124  if (x < 0) return exp(x) / scale_ + bound_;
125  else return x / scale_ + 1. + bound_;
126  else if (x < 0) return -exp(-x) / scale_ + bound_;
127  else return -x / scale_ - 1. + bound_;
128  }
129 
130  double getFirstOrderDerivative() const
131  {
132  double x = getValue();
133  if (positive_)
134  if (x < 0) return exp(x) / scale_;
135  else return 1. / scale_;
136  else if (x < 0) return exp(-x) / scale_;
137  else return -1. / scale_;
138  }
139 
141  {
142  double x = getValue();
143  if (positive_)
144  if (x < 0) return exp(x) / scale_;
145  else return 0;
146  else if (x < 0) return -exp(-x) / scale_;
147  else return 0;
148  }
149 };
150 
166  public TransformedParameter
167 {
168 private:
169  double scale_;
170  double lowerBound_;
171  double upperBound_;
172  bool hyper_;
173  double tiny_;
174 
175 public:
186  IntervalTransformedParameter(const std::string& name, double value, double lowerBound = 0, double upperBound = 1, double scale = 1, bool hyper = true) :
187  TransformedParameter(name, hyper ?
188  scale * atanh(2. * (value - lowerBound) / (upperBound - lowerBound) - 1.) :
189  scale * tan(NumConstants::PI() * (value - lowerBound) / (upperBound - lowerBound) - NumConstants::PI() / 2.)),
190  scale_(scale),
191  lowerBound_(lowerBound),
192  upperBound_(upperBound),
193  hyper_(hyper),
194  tiny_(NumConstants::TINY())
195  {}
196 
198 
199 public:
200  void setOriginalValue(double value)
201  {
202  if (value <= lowerBound_ || value >= upperBound_) throw ConstraintException("IntervalTransformedParameter::setValue", this, value);
203  setValue(hyper_ ?
204  scale_ * atanh(2. * (value - lowerBound_) / (upperBound_ - lowerBound_) - 1.) :
205  scale_ * std::tan(NumConstants::PI() * (value - lowerBound_) / (upperBound_ - lowerBound_) - NumConstants::PI() / 2.));
206  }
207 
208  double getOriginalValue() const
209  {
210  double x = getValue();
211  double x2 = hyper_ ?
212  (tanh(x / scale_) + 1.) * (upperBound_ - lowerBound_) / 2. + lowerBound_ :
213  (atan(x / scale_) + NumConstants::PI() / 2.) * (upperBound_ - lowerBound_) / NumConstants::PI() + lowerBound_;
214  return x2;
215  }
216 
217 
218  double getFirstOrderDerivative() const
219  {
220  double x = getValue();
221  double x2 = hyper_ ?
222  1. / (std::pow(cosh(x / scale_), 2)) * (upperBound_ - lowerBound_) / (2. * scale_) :
223  (upperBound_ - lowerBound_) / (NumConstants::PI() * scale_ * (std::pow(x / scale_, 2) + 1.));
224  return x2;
225  }
227  {
228  double x = getValue();
229  double x2 = hyper_ ?
230  -1. / (std::pow(cosh(x / scale_), 2)) * tanh(x / scale_) * (upperBound_ - lowerBound_) / (scale_ * scale_) :
231  -2. * x * (upperBound_ - lowerBound_) / (NumConstants::PI() * std::pow(scale_, 3) * std::pow((std::pow(x / scale_, 2) + 1.), 2));
232  return x2;
233  }
234 };
235 
243  public TransformedParameter
244 {
245 public:
246  PlaceboTransformedParameter(const std::string& name, double value) :
247  TransformedParameter(name, value)
248  {}
249 
251 
252 public:
253  void setOriginalValue(double value)
254  {
255  setValue(value);
256  }
257 
258  double getOriginalValue() const
259  {
260  return getValue();
261  }
262 
263  double getFirstOrderDerivative() const { return 1.; }
264 
265  double getSecondOrderDerivative() const { return 0.; }
266 };
267 } // end of namespace bpp.
268 #endif // BPP_NUMERIC_TRANSFORMEDPARAMETER_H
this static class contains several useful constant values.
Definition: NumConstants.h:20
TransformedParameter(const std::string &name, double value)
virtual void setOriginalValue(double value)=0
Set the value of the parameter using the orignal coordinate system.
IntervalTransformedParameter * clone() const
Create a copy of this object and send a pointer to it.
virtual double getOriginalValue() const =0
void setOriginalValue(double value)
Set the value of the parameter using the orignal coordinate system.
This class is designed to facilitate the manipulation of parameters.
Definition: Parameter.h:97
virtual double getSecondOrderDerivative() const =0
TransformedParameter * clone() const =0
Create a copy of this object and send a pointer to it.
&#39;Placebo&#39; parameter transformation from ] b, +inf [ or ] -inf, b [ to ]-inf, + inf [...
PlaceboTransformedParameter(const std::string &name, double value)
virtual void setValue(double value)
Set the value of this parameter.
Definition: Parameter.cpp:55
PlaceboTransformedParameter * clone() const
Create a copy of this object and send a pointer to it.
virtual double getFirstOrderDerivative() const =0
Parameter transformation from ] b, +inf [ or ] -inf, b [ to ]-inf, + inf [.
RTransformedParameter(const std::string &name, double value, double bound=0, bool positive=true, double scale=1)
Build a new RTransformedParameter, with given bound and scale.
IntervalTransformedParameter(const std::string &name, double value, double lowerBound=0, double upperBound=1, double scale=1, bool hyper=true)
Build a new IntervalTransformedParameter, with given bounds and scale.
void setOriginalValue(double value)
Set the value of the parameter using the orignal coordinate system.
void setOriginalValue(double value)
Set the value of the parameter using the orignal coordinate system.
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.
static double PI()
Definition: NumConstants.h:61
The TransformedParameter abstract class.
RTransformedParameter * clone() const
Create a copy of this object and send a pointer to it.
Parameter transformation from ] a, b [ to ]-inf, + inf [.