bpp-core  2.1.0
Constraints.h
Go to the documentation of this file.
00001 //
00002 // File: Constraints.h
00003 // Created by: Julien Dutheil
00004 // Created on: Thu Dec 25 19:35:17 2003
00005 //
00006 
00007 /*
00008    Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
00009 
00010    This software is a computer program whose purpose is to provide classes
00011    for numerical calculus.
00012 
00013    This software is governed by the CeCILL  license under French law and
00014    abiding by the rules of distribution of free software.  You can  use,
00015    modify and/ or redistribute the software under the terms of the CeCILL
00016    license as circulated by CEA, CNRS and INRIA at the following URL
00017    "http://www.cecill.info".
00018 
00019    As a counterpart to the access to the source code and  rights to copy,
00020    modify and redistribute granted by the license, users are provided only
00021    with a limited warranty  and the software's author,  the holder of the
00022    economic rights,  and the successive licensors  have only  limited
00023    liability.
00024 
00025    In this respect, the user's attention is drawn to the risks associated
00026    with loading,  using,  modifying and/or developing or reproducing the
00027    software by the user in light of its specific status of free software,
00028    that may mean  that it is complicated to manipulate,  and  that  also
00029    therefore means  that it is reserved for developers  and  experienced
00030    professionals having in-depth computer knowledge. Users are therefore
00031    encouraged to load and test the software's suitability as regards their
00032    requirements in conditions enabling the security of their systems and/or
00033    data to be ensured and,  more generally, to use and operate it in the
00034    same conditions as regards security.
00035 
00036    The fact that you are presently reading this means that you have had
00037    knowledge of the CeCILL license and that you accept its terms.
00038  */
00039 
00040 #ifndef _CONSTRAINTS_H_
00041 #define _CONSTRAINTS_H_
00042 
00043 // From the STL:
00044 #include <string>
00045 #include <iostream>
00046 
00047 // From Utils:
00048 #include "../Clonable.h"
00049 #include "../Text/TextTools.h"
00050 
00051 #include "NumConstants.h"
00052 
00053 namespace bpp
00054 {
00060 class Constraint : public Clonable
00061 {
00062 public:
00063   Constraint() {}
00064   virtual ~Constraint() {}
00065 
00066   Constraint* clone() const = 0;
00067 
00068 public:
00075   virtual bool isCorrect(double value) const = 0;
00076 
00083   virtual bool includes(double min, double max) const = 0;
00084 
00091   virtual double getLimit(double value) const = 0;
00092 
00102   virtual double getAcceptedLimit(double value) const = 0;
00103 
00109   virtual std::string getDescription() const = 0;
00110 
00117   virtual Constraint* operator&(const Constraint& c) const = 0;
00118 };
00119 
00127 class IntervalConstraint : public Constraint
00128 {
00129 protected:
00134   double lowerBound_, upperBound_;
00135 
00140   bool inclLowerBound_, inclUpperBound_;
00146   double precision_;
00147   
00148 
00149 public:
00150   IntervalConstraint() :  lowerBound_(NumConstants::MINF()),
00151                 upperBound_(NumConstants::PINF()),
00152                 inclLowerBound_(true),
00153                 inclUpperBound_(true),
00154                 precision_(NumConstants::TINY()) {}
00155 
00156   IntervalConstraint(double lowerBound, double upperBound, bool inclLower, bool inclUpper, double precision = NumConstants::TINY()) :
00157     lowerBound_(lowerBound),
00158     upperBound_(upperBound),
00159     inclLowerBound_(inclLower),
00160     inclUpperBound_(inclUpper),
00161     precision_(precision) {}
00162  
00173   IntervalConstraint(bool isPositive, double bound, bool incl, double precision = NumConstants::TINY()) :
00174     lowerBound_(isPositive ? bound : NumConstants::MINF()),
00175     upperBound_(isPositive ? NumConstants::PINF() : bound),
00176     inclLowerBound_(isPositive ? incl : false),
00177     inclUpperBound_(isPositive ? false : incl),
00178     precision_(precision) {}
00179  
00180   virtual ~IntervalConstraint() {}
00181 
00182   IntervalConstraint* clone() const { return new IntervalConstraint(*this); }
00183 
00184 public:
00185   void setLowerBound(double lowerBound, bool strict) { lowerBound_ = lowerBound; inclLowerBound_ = !strict; }
00186   void setUpperBound(double upperBound, bool strict) { upperBound_ = upperBound; inclUpperBound_ = !strict; }
00187 
00188   double getLowerBound() const { return lowerBound_; }
00189   double getUpperBound() const { return upperBound_; }
00190 
00191   bool strictLowerBound() const { return !inclLowerBound_; }
00192   bool strictUpperBound() const { return !inclUpperBound_; }
00193 
00194   bool finiteLowerBound() const { return lowerBound_ > NumConstants::MINF(); }
00195   bool finiteUpperBound() const { return upperBound_ < NumConstants::PINF(); }
00196 
00197   bool includes(double min, double max) const
00198   {
00199     return (inclLowerBound_ ? min >= getLowerBound() : min > getLowerBound()) &&
00200            (inclUpperBound_ ? max <= getUpperBound() : max < getUpperBound());
00201   }
00202 
00203   virtual bool isCorrect(double value) const
00204   {
00205     return (inclLowerBound_ ? value >= getLowerBound() : value > getLowerBound()) &&
00206            (inclUpperBound_ ? value <= getUpperBound() : value < getUpperBound());
00207   }
00208 
00209   bool operator<(double value) const
00210   {
00211     return inclUpperBound_ ? upperBound_ < value : upperBound_ <= value;
00212   }
00213 
00214   bool operator>(double value) const
00215   {
00216     return inclLowerBound_ ? lowerBound_ > value : lowerBound_ >= value;
00217   }
00218 
00219   bool operator<=(double value) const
00220   {
00221     return upperBound_ <= value;
00222   }
00223 
00224   bool operator>=(double value) const
00225   {
00226     return lowerBound_ >= value;
00227   }
00228 
00229   double getLimit(double value) const
00230   {
00231     return isCorrect(value) ? value :
00232            (*this >= value ? lowerBound_ : upperBound_);
00233   }
00234 
00235   double getAcceptedLimit(double value) const
00236   {
00237     return isCorrect(value) ? value :
00238            (*this >= value ?
00239             strictLowerBound() ? lowerBound_ + precision_ : lowerBound_ :
00240             strictUpperBound() ? upperBound_ - precision_ : upperBound_);
00241   }
00242 
00243   double getPrecision() const
00244   {
00245     return precision_;
00246   }
00247   
00248   std::string getDescription() const
00249   {
00250     return (inclLowerBound_ ? "[ " : "]")
00251            + (finiteLowerBound() ? TextTools::toString(lowerBound_) : "-inf")
00252            + ", "
00253            + (finiteUpperBound() ? TextTools::toString(upperBound_) : "+inf")
00254            + (inclUpperBound_ ? "] " : "[");
00255   }
00256 
00264   Constraint* operator&(const Constraint& c) const
00265   {
00266     double lowerBound, upperBound;
00267     bool inclLowerBound, inclUpperBound;
00268 
00269     const IntervalConstraint* pi = dynamic_cast<const IntervalConstraint*>(&c);
00270 
00271     if (pi)
00272     {
00273       if (lowerBound_ <= pi->lowerBound_)
00274       {
00275         lowerBound = pi->lowerBound_;
00276         inclLowerBound = pi->inclLowerBound_;
00277       }
00278       else
00279       {
00280         lowerBound = lowerBound_;
00281         inclLowerBound = inclLowerBound_;
00282       }
00283 
00284       if (upperBound_ >= pi->upperBound_)
00285       {
00286         upperBound = pi->upperBound_;
00287         inclUpperBound = pi->inclUpperBound_;
00288       }
00289       else
00290       {
00291         upperBound = upperBound_;
00292         inclUpperBound = inclUpperBound_;
00293       }
00294       return new IntervalConstraint(lowerBound, upperBound, inclLowerBound, inclUpperBound, (precision_>pi->getPrecision())?precision_:pi->getPrecision());
00295     }
00296     else
00297       return 0;
00298   }
00299 
00308   IntervalConstraint& operator&=(const Constraint& c)
00309   {
00310     const IntervalConstraint* pi = dynamic_cast<const IntervalConstraint*>(&c);
00311 
00312     if (pi)
00313     {
00314       if (lowerBound_ <= pi->lowerBound_)
00315       {
00316         lowerBound_ = pi->lowerBound_;
00317         inclLowerBound_ = pi->inclLowerBound_;
00318       }
00319       else
00320       {
00321         lowerBound_ = lowerBound_;
00322         inclLowerBound_ = inclLowerBound_;
00323       }
00324 
00325       if (upperBound_ >= pi->upperBound_)
00326       {
00327         upperBound_ = pi->upperBound_;
00328         inclUpperBound_ = pi->inclUpperBound_;
00329       }
00330       else
00331       {
00332         upperBound_ = upperBound_;
00333         inclUpperBound_ = inclUpperBound_;
00334       }
00335       if (pi->getPrecision()>precision_)
00336         precision_=pi->getPrecision();
00337     }
00338 
00339     return *this;
00340   }
00341 
00347   bool operator==(const IntervalConstraint& i) const
00348   {
00349     return lowerBound_ == i.lowerBound_
00350       && inclLowerBound_ == i.inclLowerBound_
00351       && upperBound_ == i.upperBound_
00352       && inclUpperBound_ == i.inclUpperBound_;
00353   }
00354 
00360   bool operator!=(const IntervalConstraint& i) const
00361   {
00362     return lowerBound_ != i.lowerBound_
00363       || inclLowerBound_ != i.inclLowerBound_
00364       || upperBound_ != i.upperBound_
00365       || inclUpperBound_ != i.inclUpperBound_;
00366   }
00367 
00373   bool operator<=(const IntervalConstraint& i) const
00374   {
00375     return lowerBound_ >= i.lowerBound_
00376            && upperBound_ <= i.upperBound_;
00377   }
00378 };
00379 
00380 
00381 } // end of namespace bpp.
00382 
00383 #endif  // _CONSTRAINTS_H_
00384 
 All Classes Namespaces Files Functions Variables Typedefs Friends