bpp-core3  3.0.0
Constraints.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_CONSTRAINTS_H
6 #define BPP_NUMERIC_CONSTRAINTS_H
7 
8 
9 // From the STL:
10 #include <string>
11 #include <iostream>
12 #include <typeinfo>
13 
14 // From Utils:
15 #include "../Clonable.h"
16 #include "../Text/TextTools.h"
17 #include "../Exceptions.h"
18 
19 #include "NumConstants.h"
20 
21 namespace bpp
22 {
29  public virtual Clonable
30 {
31 public:
33  virtual ~ConstraintInterface() {}
34 
35  ConstraintInterface* clone() const = 0;
36 
37 public:
44  virtual bool isCorrect(double value) const = 0;
45 
52  virtual bool includes(double min, double max) const = 0;
53 
60  virtual double getLimit(double value) const = 0;
61 
71  virtual double getAcceptedLimit(double value) const = 0;
72 
78  virtual std::string getDescription() const = 0;
79 
86  virtual ConstraintInterface* operator&(const ConstraintInterface& c) const = 0;
87 
91  virtual bool isEmpty() const = 0;
92 };
93 
102  public virtual ConstraintInterface
103 {
104 protected:
108  double lowerBound_, upperBound_;
109 
113  bool inclLowerBound_, inclUpperBound_;
114 
118  double precision_;
119 
120 public:
122  lowerBound_(NumConstants::MINF()),
123  upperBound_(NumConstants::PINF()),
124  inclLowerBound_(true),
125  inclUpperBound_(true),
126  precision_(NumConstants::TINY()) {}
127 
128  IntervalConstraint(double lowerBound, double upperBound, bool inclLower, bool inclUpper, double precision = NumConstants::TINY()) :
129  lowerBound_(lowerBound),
130  upperBound_(upperBound),
131  inclLowerBound_(inclLower),
132  inclUpperBound_(inclUpper),
133  precision_(precision) {}
134 
145  IntervalConstraint(bool isPositive, double bound, bool incl, double precision = NumConstants::TINY()) :
146  lowerBound_(isPositive ? bound : NumConstants::MINF()),
147  upperBound_(isPositive ? NumConstants::PINF() : bound),
148  inclLowerBound_(isPositive ? incl : false),
149  inclUpperBound_(isPositive ? false : incl),
150  precision_(precision) {}
151 
156  IntervalConstraint(std::string& desc) :
157  lowerBound_(NumConstants::MINF()),
158  upperBound_(NumConstants::PINF()),
159  inclLowerBound_(true),
160  inclUpperBound_(true),
161  precision_(NumConstants::TINY())
162  {
163  readDescription(desc);
164  }
165 
166  virtual ~IntervalConstraint() {}
167 
168  IntervalConstraint* clone() const override { return new IntervalConstraint(*this); }
169 
170 public:
171  void setLowerBound(double lowerBound, bool strict) { lowerBound_ = lowerBound; inclLowerBound_ = !strict; }
172  void setUpperBound(double upperBound, bool strict) { upperBound_ = upperBound; inclUpperBound_ = !strict; }
173 
174  double getLowerBound() const { return lowerBound_; }
175  double getUpperBound() const { return upperBound_; }
176 
177  bool strictLowerBound() const { return !inclLowerBound_; }
178  bool strictUpperBound() const { return !inclUpperBound_; }
179 
180  bool finiteLowerBound() const { return lowerBound_ > NumConstants::MINF(); }
181  bool finiteUpperBound() const { return upperBound_ < NumConstants::PINF(); }
182 
183  bool includes(double min, double max) const override
184  {
185  return (inclLowerBound_ ? min >= getLowerBound() : min > getLowerBound()) &&
186  (inclUpperBound_ ? max <= getUpperBound() : max < getUpperBound());
187  }
188 
189  virtual bool isCorrect(double value) const override
190  {
191  return (inclLowerBound_ ? value >= getLowerBound() : value > getLowerBound()) &&
192  (inclUpperBound_ ? value <= getUpperBound() : value < getUpperBound());
193  }
194 
195  bool operator<(double value) const
196  {
197  return inclUpperBound_ ? upperBound_ < value : upperBound_ <= value;
198  }
199 
200  bool operator>(double value) const
201  {
202  return inclLowerBound_ ? lowerBound_ > value : lowerBound_ >= value;
203  }
204 
205  bool operator<=(double value) const
206  {
207  return upperBound_ <= value;
208  }
209 
210  bool operator>=(double value) const
211  {
212  return lowerBound_ >= value;
213  }
214 
215  double getLimit(double value) const override
216  {
217  return isCorrect(value) ? value :
218  (*this >= value ? lowerBound_ : upperBound_);
219  }
220 
221  double getAcceptedLimit(double value) const override
222  {
223  return isCorrect(value) ? value :
224  (*this >= value ?
225  strictLowerBound() ? lowerBound_ + precision_ : lowerBound_ :
226  strictUpperBound() ? upperBound_ - precision_ : upperBound_);
227  }
228 
229  double getPrecision() const
230  {
231  return precision_;
232  }
233 
234  std::string getDescription() const override
235  {
236  return (inclLowerBound_ ? "[ " : "]")
237  + (finiteLowerBound() ? TextTools::toString(lowerBound_) : "-inf")
238  + "; "
239  + (finiteUpperBound() ? TextTools::toString(upperBound_) : "+inf")
240  + (inclUpperBound_ ? "] " : "[");
241  }
242 
250  void readDescription(std::string& desc)
251  {
252  size_t pdp = desc.find(";");
253  size_t dc = desc.find_first_of("[]", 1);
254 
255  if (dc == std::string::npos || pdp == std::string::npos ||
256  (desc[0] != ']' && desc[0] != '[') || (pdp >= dc))
257  throw Exception("Constraints::readDescription. Wrong description:" + desc);
258 
259  std::string deb = desc.substr(1, pdp - 1);
260  std::string fin = desc.substr(pdp + 1, dc - pdp - 1);
261 
262  inclLowerBound_ = (desc[0] == '[');
263  inclUpperBound_ = (desc[dc] == ']');
264 
265  lowerBound_ = (deb == "-inf") ? NumConstants::MINF() : TextTools::toDouble(deb);
266  upperBound_ = ((fin == "+inf") || (fin == "inf")) ? NumConstants::PINF() : TextTools::toDouble(fin);
267  }
268 
277  {
278  double lowerBound, upperBound;
279  bool inclLowerBound, inclUpperBound;
280 
281  const IntervalConstraint* pi = dynamic_cast<const IntervalConstraint*>(&c);
282 
283  if (pi)
284  {
285  if (lowerBound_ <= pi->lowerBound_)
286  {
287  lowerBound = pi->lowerBound_;
288  inclLowerBound = pi->inclLowerBound_;
289  }
290  else
291  {
292  lowerBound = lowerBound_;
293  inclLowerBound = inclLowerBound_;
294  }
295 
296  if (upperBound_ >= pi->upperBound_)
297  {
298  upperBound = pi->upperBound_;
299  inclUpperBound = pi->inclUpperBound_;
300  }
301  else
302  {
303  upperBound = upperBound_;
304  inclUpperBound = inclUpperBound_;
305  }
306  return new IntervalConstraint(lowerBound, upperBound, inclLowerBound, inclUpperBound, (precision_ > pi->getPrecision()) ? precision_ : pi->getPrecision());
307  }
308  else
309  return 0;
310  }
311 
320  {
321  try
322  {
323  const IntervalConstraint& pi = dynamic_cast<const IntervalConstraint&>(c);
324 
325  if (lowerBound_ <= pi.lowerBound_)
326  {
327  lowerBound_ = pi.lowerBound_;
328  inclLowerBound_ = pi.inclLowerBound_;
329  }
330 
331  if (upperBound_ >= pi.upperBound_)
332  {
333  upperBound_ = pi.upperBound_;
334  inclUpperBound_ = pi.inclUpperBound_;
335  }
336  if (pi.getPrecision() > precision_)
337  precision_ = pi.getPrecision();
338  }
339  catch (std::bad_cast&) {}
340 
341  return *this;
342  }
343 
349  bool operator==(const IntervalConstraint& i) const
350  {
351  return lowerBound_ == i.lowerBound_
352  && inclLowerBound_ == i.inclLowerBound_
353  && upperBound_ == i.upperBound_
354  && inclUpperBound_ == i.inclUpperBound_;
355  }
356 
362  bool operator!=(const IntervalConstraint& i) const
363  {
364  return lowerBound_ != i.lowerBound_
365  || inclLowerBound_ != i.inclLowerBound_
366  || upperBound_ != i.upperBound_
367  || inclUpperBound_ != i.inclUpperBound_;
368  }
369 
375  bool operator<=(const IntervalConstraint& i) const
376  {
377  return lowerBound_ >= i.lowerBound_
378  && upperBound_ <= i.upperBound_;
379  }
380 
384  bool isEmpty() const override
385  {
386  return (lowerBound_ > upperBound_) ||
387  ((lowerBound_ > upperBound_) &&
388  inclUpperBound_ && inclLowerBound_);
389  }
390 };
391 } // end of namespace bpp.
392 #endif // BPP_NUMERIC_CONSTRAINTS_H
virtual bool includes(double min, double max) const =0
Tell if all the values in a given interval are correct.
virtual ConstraintInterface * operator &(const ConstraintInterface &c) const =0
Intersect this Constraint with another one.
double getLimit(double value) const override
Give the nearest limit for a bad value.
Definition: Constraints.h:215
virtual double getLimit(double value) const =0
Give the nearest limit for a bad value.
double getLowerBound() const
Definition: Constraints.h:174
bool operator!=(const IntervalConstraint &i) const
Tells if this interval is different from another one.
Definition: Constraints.h:362
bool strictLowerBound() const
Definition: Constraints.h:177
double toDouble(const std::string &s, char dec, char scientificNotation)
Convert from string to double.
Definition: TextTools.cpp:217
this static class contains several useful constant values.
Definition: NumConstants.h:20
An interval, either bounded or not, which can also have infinite bounds.
Definition: Constraints.h:101
void setLowerBound(double lowerBound, bool strict)
Definition: Constraints.h:171
The constraint interface.
Definition: Constraints.h:28
bool includes(double min, double max) const override
Tell if all the values in a given interval are correct.
Definition: Constraints.h:183
bool operator==(const IntervalConstraint &i) const
Tells if this interval equals another one.
Definition: Constraints.h:349
bool inclLowerBound_
Boolean flags are true if the boundaries are included.
Definition: Constraints.h:113
IntervalConstraint(bool isPositive, double bound, bool incl, double precision=NumConstants::TINY())
Create an interval with an infinite lower/upper bound.
Definition: Constraints.h:145
static double PINF()
Definition: NumConstants.h:56
double precision_
the accepted precision on the boundary (default: 1e-12)
Definition: Constraints.h:118
IntervalConstraint(double lowerBound, double upperBound, bool inclLower, bool inclUpper, double precision=NumConstants::TINY())
Definition: Constraints.h:128
virtual bool isCorrect(double value) const =0
Tell if a given value is correct.
bool finiteLowerBound() const
Definition: Constraints.h:180
bool operator<=(const IntervalConstraint &i) const
Tells if this interval is included or equal in another one.
Definition: Constraints.h:375
ConstraintInterface * clone() const =0
Create a copy of this object and send a pointer to it.
bool strictUpperBound() const
Definition: Constraints.h:178
virtual ~IntervalConstraint()
Definition: Constraints.h:166
static double TINY()
Definition: NumConstants.h:46
bool finiteUpperBound() const
Definition: Constraints.h:181
void operator &=(std::vector< T > &v1, const C &c)
Definition: VectorTools.h:260
bool operator<=(double value) const
Definition: Constraints.h:205
std::string getDescription() const override
Give a short description on the type of constraint.
Definition: Constraints.h:234
virtual std::string getDescription() const =0
Give a short description on the type of constraint.
virtual ~ConstraintInterface()
Definition: Constraints.h:33
IntervalConstraint * clone() const override
Create a copy of this object and send a pointer to it.
Definition: Constraints.h:168
virtual double getAcceptedLimit(double value) const =0
Give the nearest accepted limit for a bad value.
double lowerBound_
The boundaries of the interval.
Definition: Constraints.h:108
bool isEmpty() const override
Tells if this interval is empty.
Definition: Constraints.h:384
virtual bool isEmpty() const =0
Tells if this constraints defines an empty set.
bool operator>=(double value) const
Definition: Constraints.h:210
double getAcceptedLimit(double value) const override
Give the nearest accepted limit for a bad value.
Definition: Constraints.h:221
Exception base class. Overload exception constructor (to control the exceptions mechanism). Destructor is already virtual (from std::exception)
Definition: Exceptions.h:20
The Clonable interface (allow an object to be cloned).
Definition: Clonable.h:63
IntervalConstraint(std::string &desc)
Create an interval from a string description, using readDescription method.
Definition: Constraints.h:156
void setUpperBound(double upperBound, bool strict)
Definition: Constraints.h:172
double getUpperBound() const
Definition: Constraints.h:175
bool operator<(double value) const
Definition: Constraints.h:195
std::string toString(T t)
General template method to convert to a string.
Definition: TextTools.h:115
bool operator>(double value) const
Definition: Constraints.h:200
void readDescription(std::string &desc)
Sets the bounds of the interval from a string.
Definition: Constraints.h:250
double getPrecision() const
Definition: Constraints.h:229
virtual bool isCorrect(double value) const override
Tell if a given value is correct.
Definition: Constraints.h:189
static double MINF()
Definition: NumConstants.h:57