00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef _eoRealBounds_h
00028 #define _eoRealBounds_h
00029
00030 #include <stdexcept>
00031 #include <utils/eoRNG.h>
00032
00075 class eoRealBounds : public eoPersistent
00076 {
00077 public:
00078 virtual ~eoRealBounds(){}
00079
00082 virtual bool isBounded(void) const = 0;
00083
00087 virtual bool hasNoBoundAtAll(void) const = 0;
00088
00091 virtual bool isMinBounded(void) const = 0;
00092
00095 virtual bool isMaxBounded(void) const = 0;
00096
00099 virtual bool isInBounds(double) const = 0;
00100
00103 virtual void foldsInBounds(double &) const = 0;
00104
00107 virtual void truncate(double &) const = 0;
00108
00112 virtual double minimum() const = 0 ;
00116 virtual double maximum() const = 0 ;
00120 virtual double range() const = 0;
00121
00125 virtual double uniform(eoRng & _rng = eo::rng) const = 0;
00126
00128 virtual eoRealBounds * dup() const = 0;
00129 };
00130
00133 class eoRealNoBounds : public eoRealBounds
00134 {
00135 public:
00136 virtual ~eoRealNoBounds(){}
00137
00138 virtual bool isBounded(void) const {return false;}
00139 virtual bool hasNoBoundAtAll(void) const {return true;}
00140 virtual bool isMinBounded(void) const {return false;}
00141 virtual bool isMaxBounded(void) const {return false;}
00142 virtual void foldsInBounds(double &) const {return;}
00143 virtual void truncate(double &) const {return;}
00144 virtual bool isInBounds(double) const {return true;}
00145
00146 virtual double minimum() const
00147 {
00148 throw std::logic_error("Trying to get minimum of unbounded eoRealBounds");
00149 }
00150 virtual double maximum() const
00151 {
00152 throw std::logic_error("Trying to get maximum of unbounded eoRealBounds");
00153 }
00154 virtual double range() const
00155 {
00156 throw std::logic_error("Trying to get range of unbounded eoRealBounds");
00157 }
00158
00159 virtual double uniform(eoRng & _rng = eo::rng) const
00160 {
00161 throw std::logic_error("Trying to generate uniform values in unbounded eoRealBounds");
00162 }
00163
00164
00171 virtual void readFrom(std::istream& _is)
00172 {
00173 throw std::runtime_error("Should not use eoRealBounds::readFrom");
00174 }
00175
00180 virtual void printOn(std::ostream& _os) const
00181 {
00182 _os << "[-inf,+inf]";
00183 }
00184
00186 virtual eoRealBounds * dup() const
00187 {
00188 return new eoRealNoBounds(*this);
00189 }
00190
00191 };
00192
00193
00194 extern eoRealNoBounds eoDummyRealNoBounds;
00195
00199 class eoRealInterval : public eoRealBounds
00200 {
00201 public :
00202 virtual ~eoRealInterval(){}
00203
00207 eoRealInterval(double _min=0, double _max=1) :
00208 repMinimum(_min), repMaximum(_max), repRange(_max-_min)
00209 {
00210 if (repRange<=0)
00211 throw std::logic_error("Void range in eoRealBounds");
00212 }
00213
00214
00215 virtual double minimum() const { return repMinimum; }
00216 virtual double maximum() const { return repMaximum; }
00217 virtual double range() const { return repRange; }
00218
00219
00220 virtual bool isBounded(void) const {return true;}
00221 virtual bool hasNoBoundAtAll(void) const {return false;}
00222 virtual bool isMinBounded(void) const {return true;}
00223 virtual bool isMaxBounded(void) const {return true;}
00224
00225 virtual double uniform(eoRng & _rng = eo::rng) const
00226 {
00227 return repMinimum + _rng.uniform(repRange);
00228 }
00229
00230
00231 virtual bool isInBounds(double _r) const
00232 {
00233 if (_r < repMinimum)
00234 return false;
00235 if (_r > repMaximum)
00236 return false;
00237 return true;
00238 }
00239
00240
00241 virtual void foldsInBounds(double & _r) const
00242 {
00243 long iloc;
00244 double dlargloc = 2 * range() ;
00245
00246 if (fabs(_r) > 1.0E9)
00247 {
00248 _r = uniform();
00249 return;
00250 }
00251
00252 if ( (_r > maximum()) )
00253 {
00254 iloc = (long) ( (_r-minimum()) / dlargloc ) ;
00255 _r -= dlargloc * iloc ;
00256 if ( _r > maximum() )
00257 _r = 2*maximum() - _r ;
00258 }
00259
00260 if (_r < minimum())
00261 {
00262 iloc = (long) ( (maximum()-_r) / dlargloc ) ;
00263 _r += dlargloc * iloc ;
00264 if (_r < minimum())
00265 _r = 2*minimum() - _r ;
00266 }
00267 }
00268
00269
00270 virtual void truncate(double & _r) const
00271 {
00272 if (_r < repMinimum)
00273 _r = repMinimum;
00274 else if (_r > repMaximum)
00275 _r = repMaximum;
00276 return;
00277 }
00278
00279
00286 virtual void readFrom(std::istream& _is)
00287 {
00288 throw std::runtime_error("Should not use eoRealInterval::readFrom");
00289 }
00290
00295 virtual void printOn(std::ostream& _os) const
00296 {
00297 _os << "[" << repMinimum << "," << repMaximum << "]";
00298 }
00299
00301 virtual eoRealBounds * dup() const
00302 {
00303 return new eoRealInterval(*this);
00304 }
00305
00306 private :
00307 double repMinimum;
00308 double repMaximum;
00309 double repRange;
00310 };
00311
00315 class eoRealBelowBound : public eoRealBounds
00316 {
00317 public :
00318 virtual ~eoRealBelowBound(){}
00322 eoRealBelowBound(double _min=0) :
00323 repMinimum(_min)
00324 {}
00325
00326
00327 virtual double minimum() const { return repMinimum; }
00328
00329 virtual double maximum() const
00330 {
00331 throw std::logic_error("Trying to get maximum of eoRealBelowBound");
00332 }
00333 virtual double range() const
00334 {
00335 throw std::logic_error("Trying to get range of eoRealBelowBound");
00336 }
00337
00338
00339 virtual double uniform(eoRng & _rng = eo::rng) const
00340 {
00341 throw std::logic_error("Trying to generate uniform values in eoRealBelowBound");
00342 }
00343
00344
00345 virtual bool isBounded(void) const {return false;}
00346 virtual bool hasNoBoundAtAll(void) const {return false;}
00347 virtual bool isMinBounded(void) const {return true;}
00348 virtual bool isMaxBounded(void) const {return false;}
00349
00350
00351 virtual bool isInBounds(double _r) const
00352 {
00353 if (_r < repMinimum)
00354 return false;
00355 return true;
00356 }
00357
00358
00359 virtual void foldsInBounds(double & _r) const
00360 {
00361
00362 if (_r < repMinimum)
00363 _r = 2*repMinimum - _r;
00364 return ;
00365 }
00366
00367
00368 virtual void truncate(double & _r) const
00369 {
00370 if (_r < repMinimum)
00371 _r = repMinimum;
00372 return;
00373 }
00374
00375
00382 virtual void readFrom(std::istream& _is)
00383 {
00384 throw std::runtime_error("Should not use eoRealBelowBound::readFrom");
00385 }
00386
00391 virtual void printOn(std::ostream& _os) const
00392 {
00393 _os << "[" << repMinimum << ",+inf]";
00394 }
00395
00397 virtual eoRealBounds * dup() const
00398 {
00399 return new eoRealBelowBound(*this);
00400 }
00401
00402 private :
00403 double repMinimum;
00404 };
00405
00409 class eoRealAboveBound : public eoRealBounds
00410 {
00411 public :
00412 virtual ~eoRealAboveBound(){}
00413
00417 eoRealAboveBound(double _max=0) :
00418 repMaximum(_max)
00419 {}
00420
00421
00422 virtual double maximum() const { return repMaximum; }
00423
00424 virtual double minimum() const
00425 {
00426 throw std::logic_error("Trying to get minimum of eoRealAboveBound");
00427 }
00428 virtual double range() const
00429 {
00430 throw std::logic_error("Trying to get range of eoRealAboveBound");
00431 }
00432
00433
00434 virtual double uniform(eoRng & _rng = eo::rng) const
00435 {
00436 throw std::logic_error("Trying to generate uniform values in eoRealAboveBound");
00437 }
00438
00439
00440 virtual bool isBounded(void) const {return false;}
00441 virtual bool hasNoBoundAtAll(void) const {return false;}
00442 virtual bool isMinBounded(void) const {return false;}
00443 virtual bool isMaxBounded(void) const {return true;}
00444
00445
00446 virtual bool isInBounds(double _r) const
00447 {
00448 if (_r > repMaximum)
00449 return false;
00450 return true;
00451 }
00452
00453
00454 virtual void foldsInBounds(double & _r) const
00455 {
00456
00457 if (_r > repMaximum)
00458 _r = 2*repMaximum - _r;
00459 return ;
00460 }
00461
00462
00463 virtual void truncate(double & _r) const
00464 {
00465 if (_r > repMaximum)
00466 _r = repMaximum;
00467 return;
00468 }
00469
00470
00477 virtual void readFrom(std::istream& _is)
00478 {
00479 throw std::runtime_error("Should not use eoRealAboveBound::readFrom");
00480 }
00481
00486 virtual void printOn(std::ostream& _os) const
00487 {
00488 _os << "[-inf," << repMaximum << "]";
00489 }
00490
00492 virtual eoRealBounds * dup() const
00493 {
00494 return new eoRealAboveBound(*this);
00495 }
00496
00497 private :
00498 double repMaximum;
00499 };
00500
00502
00506 class eoGeneralRealBounds : public eoRealBounds
00507 {
00508 public:
00510 eoGeneralRealBounds(std::string _s = "[-infinity,+infinity]")
00511 {
00512 repBound = getBoundsFromString(_s);
00513 }
00514
00516 eoGeneralRealBounds(const eoGeneralRealBounds & _b):eoRealBounds(_b)
00517 {
00518
00519
00520
00521 bool minBounded = _b.isMinBounded();
00522 bool maxBounded = _b.isMaxBounded();
00523 double minimum, maximum;
00524 const eoRealBounds & bb = _b.theBounds();
00525 if (minBounded) minimum = bb.minimum();
00526 if (maxBounded) maximum = bb.maximum();
00527
00528 if (minBounded && maxBounded)
00529 repBound = new eoRealInterval(minimum, maximum);
00530 else if (!minBounded && !maxBounded)
00531 repBound = new eoRealNoBounds;
00532 else if (!minBounded && maxBounded)
00533 repBound = new eoRealAboveBound(maximum);
00534 else if (minBounded && !maxBounded)
00535 repBound = new eoRealBelowBound(minimum);
00536 }
00537
00538 eoGeneralRealBounds& operator=(const eoGeneralRealBounds& _b)
00539 {
00540
00541
00542
00543 bool minBounded = _b.isMinBounded();
00544 bool maxBounded = _b.isMaxBounded();
00545 double minimum, maximum;
00546 const eoRealBounds & bb = _b.theBounds();
00547 if (minBounded) minimum = bb.minimum();
00548 if (maxBounded) maximum = bb.maximum();
00549
00550
00551 if (repBound)
00552 delete repBound;
00553
00554 if (minBounded && maxBounded)
00555 repBound = new eoRealInterval(minimum, maximum);
00556 else if (!minBounded && !maxBounded)
00557 repBound = new eoRealNoBounds;
00558 else if (!minBounded && maxBounded)
00559 repBound = new eoRealAboveBound(maximum);
00560 else if (minBounded && !maxBounded)
00561 repBound = new eoRealBelowBound(minimum);
00562 return (*this);
00563 }
00564
00565
00567 ~eoGeneralRealBounds()
00568 {
00569 delete repBound;
00570 }
00571
00573
00575 virtual bool isBounded(void) const {return repBound->isBounded();}
00576
00580 virtual bool hasNoBoundAtAll(void) const {return repBound->hasNoBoundAtAll();}
00581
00584 virtual bool isMinBounded(void) const {return repBound->isMinBounded();}
00585
00588 virtual bool isMaxBounded(void) const {return repBound->isMaxBounded();}
00589
00592 virtual bool isInBounds(double _x) const {return repBound->isInBounds(_x);}
00593
00596 virtual void foldsInBounds(double & _x) const {return repBound->foldsInBounds(_x);}
00597
00600 virtual void truncate(double & _x) const {return repBound->truncate(_x);}
00601
00605 virtual double minimum() const {return repBound->minimum();}
00609 virtual double maximum() const {return repBound->maximum();}
00613 virtual double range() const {return repBound->range();}
00614
00618 virtual double uniform(eoRng & _rng = eo::rng) const {return repBound->uniform();}
00619
00621 virtual eoRealBounds * dup() const {return repBound->dup();}
00622
00624 const eoRealBounds & theBounds() const { return *repBound;}
00625
00629 virtual void printOn(std::ostream& _os) const
00630 {
00631 repBound->printOn(_os);
00632 }
00633
00635 virtual void readFrom(std::istream& _is)
00636 {
00637 std::string s;
00638 _is >> s;
00639 if (repBound)
00640 delete repBound;
00641 repBound = getBoundsFromString(s);
00642 }
00643
00644 private:
00645
00646 eoRealBounds * getBoundsFromString(std::string);
00647
00648 eoRealBounds * repBound;
00649 };
00650
00651
00652 #endif