|
bpp-core
2.1.0
|
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