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 _eoIntBounds_h
00028 #define _eoIntBounds_h
00029
00030 #include <stdexcept>
00031 #include <utils/eoRNG.h>
00032
00075 class eoIntBounds : public eoPersistent
00076 {
00077 public:
00078 virtual ~eoIntBounds(){}
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 foldsInBounds(long int & i) const
00108 {
00109 double r = double(i);
00110 foldsInBounds(r);
00111 i = (long int)(r);
00112 }
00113
00116 virtual void truncate(double &) const = 0;
00117
00120 virtual void truncate(long int & i) const
00121 {
00122 double r = double(i);
00123 truncate(r);
00124 i = (long int)(r);
00125 }
00126
00130 virtual long int minimum() const = 0 ;
00134 virtual long int maximum() const = 0 ;
00138 virtual long int range() const = 0;
00139
00144 virtual double uniform(eoRng & _rng = eo::rng) const = 0;
00145 virtual long int random(eoRng & _rng = eo::rng) const = 0;
00146
00148 virtual eoIntBounds * dup() const = 0;
00149 };
00150
00153 class eoIntNoBounds : public eoIntBounds
00154 {
00155 public:
00156 virtual ~eoIntNoBounds(){}
00157
00158 virtual bool isBounded(void) const {return false;}
00159 virtual bool hasNoBoundAtAll(void) const {return true;}
00160 virtual bool isMinBounded(void) const {return false;}
00161 virtual bool isMaxBounded(void) const {return false;}
00162 virtual void foldsInBounds(double &) const {return;}
00163 virtual void truncate(double &) const {return;}
00164 virtual bool isInBounds(double) const {return true;}
00165
00166 virtual long int minimum() const
00167 {
00168 throw std::logic_error("Trying to get minimum of unbounded eoIntBounds");
00169 }
00170 virtual long int maximum() const
00171 {
00172 throw std::logic_error("Trying to get maximum of unbounded eoIntBounds");
00173 }
00174 virtual long int range() const
00175 {
00176 throw std::logic_error("Trying to get range of unbounded eoIntBounds");
00177 }
00178
00179 virtual double uniform(eoRng & _rng = eo::rng) const
00180 {
00181 throw std::logic_error("Trying to generate uniform values in unbounded eoIntBounds");
00182 }
00183 virtual long int random(eoRng & _rng = eo::rng) const
00184 {
00185 throw std::logic_error("Trying to generate uniform values in unbounded eoIntBounds");
00186 }
00187
00188
00195 virtual void readFrom(std::istream& _is)
00196 {
00197 throw std::runtime_error("Should not use eoIntBounds::readFrom");
00198 }
00199
00204 virtual void printOn(std::ostream& _os) const
00205 {
00206 _os << "[-inf,+inf]";
00207 }
00208
00210 virtual eoIntBounds * dup() const
00211 {
00212 return new eoIntNoBounds(*this);
00213 }
00214
00215 };
00216
00217
00218 extern eoIntNoBounds eoDummyIntNoBounds;
00219
00223 class eoIntInterval : public eoIntBounds
00224 {
00225 public :
00226 virtual ~eoIntInterval(){}
00227
00231 eoIntInterval(long int _min=0, long int _max=1) :
00232 repMinimum(_min), repMaximum(_max), repRange(_max-_min)
00233 {
00234 if (repRange<=0)
00235 throw std::logic_error("Void range in eoIntBounds");
00236 }
00237
00238
00239 virtual long int minimum() const { return repMinimum; }
00240 virtual long int maximum() const { return repMaximum; }
00241 virtual long int range() const { return repRange; }
00242
00243
00244 virtual bool isBounded(void) const {return true;}
00245 virtual bool hasNoBoundAtAll(void) const {return false;}
00246 virtual bool isMinBounded(void) const {return true;}
00247 virtual bool isMaxBounded(void) const {return true;}
00248
00249 virtual double uniform(eoRng & _rng = eo::rng) const
00250 {
00251 return repMinimum + _rng.uniform(repRange);
00252 }
00253
00254 virtual long int random(eoRng & _rng = eo::rng) const
00255 {
00256 return repMinimum + _rng.random(repRange);
00257 }
00258
00259
00260 virtual bool isInBounds(double _r) const
00261 {
00262 if (_r < repMinimum)
00263 return false;
00264 if (_r > repMaximum)
00265 return false;
00266 return true;
00267 }
00268
00269
00270 virtual void foldsInBounds(double & _r) const
00271 {
00272 long iloc;
00273 double dlargloc = 2 * range() ;
00274
00275 if (fabs(_r) > 1.0E9)
00276 {
00277 _r = uniform();
00278 return;
00279 }
00280
00281 if ( (_r > maximum()) )
00282 {
00283 iloc = (long) ( (_r-minimum()) / dlargloc ) ;
00284 _r -= dlargloc * iloc ;
00285 if ( _r > maximum() )
00286 _r = 2*maximum() - _r ;
00287 }
00288
00289 if (_r < minimum())
00290 {
00291 iloc = (long) ( (maximum()-_r) / dlargloc ) ;
00292 _r += dlargloc * iloc ;
00293 if (_r < minimum())
00294 _r = 2*minimum() - _r ;
00295 }
00296 }
00297
00298
00299 virtual void truncate(double & _r) const
00300 {
00301 if (_r < repMinimum)
00302 _r = repMinimum;
00303 else if (_r > repMaximum)
00304 _r = repMaximum;
00305 return;
00306 }
00307
00308
00315 virtual void readFrom(std::istream& _is)
00316 {
00317 throw std::runtime_error("Should not use eoIntInterval::readFrom");
00318 }
00319
00324 virtual void printOn(std::ostream& _os) const
00325 {
00326 _os << "[" << repMinimum << "," << repMaximum << "]";
00327 }
00328
00330 virtual eoIntBounds * dup() const
00331 {
00332 return new eoIntInterval(*this);
00333 }
00334
00335 private :
00336 long int repMinimum;
00337 long int repMaximum;
00338 long int repRange;
00339 };
00340
00344 class eoIntBelowBound : public eoIntBounds
00345 {
00346 public :
00347 virtual ~eoIntBelowBound(){}
00351 eoIntBelowBound(long int _min=0) :
00352 repMinimum(_min)
00353 {}
00354
00355
00356 virtual long int minimum() const { return repMinimum; }
00357
00358 virtual long int maximum() const
00359 {
00360 throw std::logic_error("Trying to get maximum of eoIntBelowBound");
00361 }
00362 virtual long int range() const
00363 {
00364 throw std::logic_error("Trying to get range of eoIntBelowBound");
00365 }
00366
00367 virtual double uniform(eoRng & _rng = eo::rng) const
00368 {
00369 throw std::logic_error("Trying to generate uniform values in eoIntBelowBound");
00370 }
00371 virtual long int random(eoRng & _rng = eo::rng) const
00372 {
00373 throw std::logic_error("Trying to generate uniform values in eoIntBelowBound");
00374 }
00375
00376
00377 virtual bool isBounded(void) const {return false;}
00378 virtual bool hasNoBoundAtAll(void) const {return false;}
00379 virtual bool isMinBounded(void) const {return true;}
00380 virtual bool isMaxBounded(void) const {return false;}
00381
00382
00383 virtual bool isInBounds(double _r) const
00384 {
00385 if (_r < repMinimum)
00386 return false;
00387 return true;
00388 }
00389
00390
00391 virtual void foldsInBounds(double & _r) const
00392 {
00393
00394 if (_r < repMinimum)
00395 _r = 2*repMinimum - _r;
00396 return ;
00397 }
00398
00399
00400 virtual void truncate(double & _r) const
00401 {
00402 if (_r < repMinimum)
00403 _r = repMinimum;
00404 return;
00405 }
00406
00407
00414 virtual void readFrom(std::istream& _is)
00415 {
00416 throw std::runtime_error("Should not use eoIntBelowBound::readFrom");
00417 }
00418
00423 virtual void printOn(std::ostream& _os) const
00424 {
00425 _os << "[" << repMinimum << ",+inf]";
00426 }
00427
00429 virtual eoIntBounds * dup() const
00430 {
00431 return new eoIntBelowBound(*this);
00432 }
00433
00434 private :
00435 long int repMinimum;
00436 };
00437
00441 class eoIntAboveBound : public eoIntBounds
00442 {
00443 public :
00444 virtual ~eoIntAboveBound(){}
00445
00449 eoIntAboveBound(long int _max=0) :
00450 repMaximum(_max)
00451 {}
00452
00453
00454 virtual long int maximum() const { return repMaximum; }
00455
00456 virtual long int minimum() const
00457 {
00458 throw std::logic_error("Trying to get minimum of eoIntAboveBound");
00459 }
00460 virtual long int range() const
00461 {
00462 throw std::logic_error("Trying to get range of eoIntAboveBound");
00463 }
00464
00465 virtual double uniform(eoRng & _rng = eo::rng) const
00466 {
00467 throw std::logic_error("Trying to generate uniform values in eoIntAboveBound");
00468 }
00469 virtual long int random(eoRng & _rng = eo::rng) const
00470 {
00471 throw std::logic_error("Trying to generate uniform values in eoIntAboveBound");
00472 }
00473
00474
00475 virtual bool isBounded(void) const {return false;}
00476 virtual bool hasNoBoundAtAll(void) const {return false;}
00477 virtual bool isMinBounded(void) const {return false;}
00478 virtual bool isMaxBounded(void) const {return true;}
00479
00480
00481 virtual bool isInBounds(double _r) const
00482 {
00483 if (_r > repMaximum)
00484 return false;
00485 return true;
00486 }
00487
00488
00489 virtual void foldsInBounds(double & _r) const
00490 {
00491
00492 if (_r > repMaximum)
00493 _r = 2*repMaximum - _r;
00494 return ;
00495 }
00496
00497
00498 virtual void truncate(double & _r) const
00499 {
00500 if (_r > repMaximum)
00501 _r = repMaximum;
00502 return;
00503 }
00504
00505
00512 virtual void readFrom(std::istream& _is)
00513 {
00514 throw std::runtime_error("Should not use eoIntAboveBound::readFrom");
00515 }
00516
00521 virtual void printOn(std::ostream& _os) const
00522 {
00523 _os << "[-inf," << repMaximum << "]";
00524 }
00525
00527 virtual eoIntBounds * dup() const
00528 {
00529 return new eoIntAboveBound(*this);
00530 }
00531
00532 private :
00533 long int repMaximum;
00534 };
00535
00537
00541 class eoGeneralIntBounds : public eoIntBounds
00542 {
00543 public:
00545 eoGeneralIntBounds(std::string _s = "[-infinity,+infinity]")
00546 {
00547 repBound = getBoundsFromString(_s);
00548 }
00549
00551 eoGeneralIntBounds(const eoGeneralIntBounds & _b) : eoIntBounds(_b)
00552 {
00553
00554
00555
00556 bool minBounded = _b.isMinBounded();
00557 bool maxBounded = _b.isMaxBounded();
00558 long int minimum, maximum;
00559 const eoIntBounds & bb = _b.theBounds();
00560 if (minBounded) minimum = bb.minimum();
00561 if (maxBounded) maximum = bb.maximum();
00562
00563 if (minBounded && maxBounded)
00564 repBound = new eoIntInterval(minimum, maximum);
00565 else if (!minBounded && !maxBounded)
00566 repBound = new eoIntNoBounds;
00567 else if (!minBounded && maxBounded)
00568 repBound = new eoIntAboveBound(maximum);
00569 else if (minBounded && !maxBounded)
00570 repBound = new eoIntBelowBound(minimum);
00571 }
00572
00573 eoGeneralIntBounds& operator=(const eoGeneralIntBounds& _b)
00574 {
00575
00576
00577
00578 bool minBounded = _b.isMinBounded();
00579 bool maxBounded = _b.isMaxBounded();
00580 long int minimum, maximum;
00581 const eoIntBounds & bb = _b.theBounds();
00582 if (minBounded) minimum = bb.minimum();
00583 if (maxBounded) maximum = bb.maximum();
00584
00585
00586 if (repBound)
00587 delete repBound;
00588
00589 if (minBounded && maxBounded)
00590 repBound = new eoIntInterval(minimum, maximum);
00591 else if (!minBounded && !maxBounded)
00592 repBound = new eoIntNoBounds;
00593 else if (!minBounded && maxBounded)
00594 repBound = new eoIntAboveBound(maximum);
00595 else if (minBounded && !maxBounded)
00596 repBound = new eoIntBelowBound(minimum);
00597 return (*this);
00598 }
00599
00600
00602 ~eoGeneralIntBounds()
00603 {
00604 delete repBound;
00605 }
00606
00608
00610 virtual bool isBounded(void) const {return repBound->isBounded();}
00611
00615 virtual bool hasNoBoundAtAll(void) const {return repBound->hasNoBoundAtAll();}
00616
00619 virtual bool isMinBounded(void) const {return repBound->isMinBounded();}
00620
00623 virtual bool isMaxBounded(void) const {return repBound->isMaxBounded();}
00624
00627 virtual bool isInBounds(double _x) const {return repBound->isInBounds(_x);}
00628
00631 virtual void foldsInBounds(double & _x) const {return repBound->foldsInBounds(_x);}
00632
00635 virtual void truncate(double & _x) const {return repBound->truncate(_x);}
00636
00640 virtual long int minimum() const {return repBound->minimum();}
00644 virtual long int maximum() const {return repBound->maximum();}
00648 virtual long int range() const {return repBound->range();}
00649
00653 virtual double uniform(eoRng & _rng = eo::rng) const {return repBound->uniform();}
00654
00658 virtual long int random(eoRng & _rng = eo::rng) const {return repBound->random();}
00659
00661 virtual eoIntBounds * dup() const {return repBound->dup();}
00662
00664 const eoIntBounds & theBounds() const { return *repBound;}
00665
00669 virtual void printOn(std::ostream& _os) const
00670 {
00671 repBound->printOn(_os);
00672 }
00673
00675 virtual void readFrom(std::istream& _is)
00676 {
00677 std::string s;
00678 _is >> s;
00679 if (repBound)
00680 delete repBound;
00681 repBound = getBoundsFromString(s);
00682 }
00683
00684 private:
00685
00686 eoIntBounds * getBoundsFromString(std::string);
00687
00688 eoIntBounds * repBound;
00689 };
00690
00691
00692 #endif