EvolvingObjects
|
00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- 00002 00003 //----------------------------------------------------------------------------- 00004 // eoIntBounds.h 00005 // (c) Marc Schoenauer 2001, Maarten Keijzer 2000, GeNeura Team, 1998 00006 /* 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Lesser General Public 00009 License as published by the Free Software Foundation; either 00010 version 2 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public 00018 License along with this library; if not, write to the Free Software 00019 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 00021 Contact: todos@geneura.ugr.es, http://geneura.ugr.es 00022 Marc.Schoenauer@polytechnique.fr 00023 mak@dhi.dk 00024 */ 00025 //----------------------------------------------------------------------------- 00026 00027 #ifndef _eoIntBounds_h 00028 #define _eoIntBounds_h 00029 00030 #include <stdexcept> // std::exceptions! 00031 #include <utils/eoRNG.h> 00032 00070 class eoIntBounds : public eoPersistent 00071 { 00072 public: 00073 virtual ~eoIntBounds(){} 00074 00077 virtual bool isBounded(void) const = 0; 00078 00082 virtual bool hasNoBoundAtAll(void) const = 0; 00083 00086 virtual bool isMinBounded(void) const = 0; 00087 00090 virtual bool isMaxBounded(void) const = 0; 00091 00094 virtual bool isInBounds(double) const = 0; 00095 00098 virtual void foldsInBounds(double &) const = 0; 00099 00102 virtual void foldsInBounds(long int & i) const 00103 { 00104 double r = double(i); 00105 foldsInBounds(r); 00106 i = (long int)(r); 00107 } 00108 00111 virtual void truncate(double &) const = 0; 00112 00115 virtual void truncate(long int & i) const 00116 { 00117 double r = double(i); 00118 truncate(r); 00119 i = (long int)(r); 00120 } 00121 00125 virtual long int minimum() const = 0 ; 00129 virtual long int maximum() const = 0 ; 00133 virtual long int range() const = 0; 00134 00139 virtual double uniform(eoRng & _rng = eo::rng) const = 0; 00140 virtual long int random(eoRng & _rng = eo::rng) const = 0; 00141 00143 virtual eoIntBounds * dup() const = 0; 00144 }; 00145 00151 class eoIntNoBounds : public eoIntBounds 00152 { 00153 public: 00154 virtual ~eoIntNoBounds(){} 00155 00156 virtual bool isBounded(void) const {return false;} 00157 virtual bool hasNoBoundAtAll(void) const {return true;} 00158 virtual bool isMinBounded(void) const {return false;} 00159 virtual bool isMaxBounded(void) const {return false;} 00160 virtual void foldsInBounds(double &) const {return;} 00161 virtual void truncate(double &) const {return;} 00162 virtual bool isInBounds(double) const {return true;} 00163 00164 virtual long int minimum() const 00165 { 00166 throw std::logic_error("Trying to get minimum of unbounded eoIntBounds"); 00167 } 00168 virtual long int maximum() const 00169 { 00170 throw std::logic_error("Trying to get maximum of unbounded eoIntBounds"); 00171 } 00172 virtual long int range() const 00173 { 00174 throw std::logic_error("Trying to get range of unbounded eoIntBounds"); 00175 } 00176 00177 virtual double uniform(eoRng & _rng = eo::rng) const 00178 { 00179 (void)_rng; 00180 00181 throw std::logic_error("Trying to generate uniform values in unbounded eoIntBounds"); 00182 } 00183 00184 virtual long int random(eoRng & _rng = eo::rng) const 00185 { 00186 (void)_rng; 00187 00188 throw std::logic_error("Trying to generate uniform values in unbounded eoIntBounds"); 00189 } 00190 00191 // methods from eoPersistent 00198 virtual void readFrom(std::istream& _is) 00199 { 00200 (void)_is; 00201 00202 throw std::runtime_error("Should not use eoIntBounds::readFrom"); 00203 } 00204 00209 virtual void printOn(std::ostream& _os) const 00210 { 00211 _os << "[-inf,+inf]"; 00212 } 00213 00215 virtual eoIntBounds * dup() const 00216 { 00217 return new eoIntNoBounds(*this); 00218 } 00219 00220 }; 00221 00227 extern eoIntNoBounds eoDummyIntNoBounds; 00228 00235 class eoIntInterval : public eoIntBounds 00236 { 00237 public : 00238 virtual ~eoIntInterval(){} 00239 00243 eoIntInterval(long int _min=0, long int _max=1) : 00244 repMinimum(_min), repMaximum(_max), repRange(_max-_min) 00245 { 00246 if (repRange<=0) 00247 throw std::logic_error("Void range in eoIntBounds"); 00248 } 00249 00250 // accessors 00251 virtual long int minimum() const { return repMinimum; } 00252 virtual long int maximum() const { return repMaximum; } 00253 virtual long int range() const { return repRange; } 00254 00255 // description 00256 virtual bool isBounded(void) const {return true;} 00257 virtual bool hasNoBoundAtAll(void) const {return false;} 00258 virtual bool isMinBounded(void) const {return true;} 00259 virtual bool isMaxBounded(void) const {return true;} 00260 00261 virtual double uniform(eoRng & _rng = eo::rng) const 00262 { 00263 return repMinimum + _rng.uniform(repRange); 00264 } 00265 00266 virtual long int random(eoRng & _rng = eo::rng) const 00267 { 00268 return repMinimum + _rng.random(repRange); 00269 } 00270 00271 // says if a given double is within the bounds 00272 virtual bool isInBounds(double _r) const 00273 { 00274 if (_r < repMinimum) 00275 return false; 00276 if (_r > repMaximum) 00277 return false; 00278 return true; 00279 } 00280 00281 // folds a value into bounds 00282 virtual void foldsInBounds(double & _r) const 00283 { 00284 long iloc; 00285 double dlargloc = 2 * range() ; 00286 00287 if (fabs(_r) > 1.0E9) // iloc too large! 00288 { 00289 _r = uniform(); 00290 return; 00291 } 00292 00293 if ( (_r > maximum()) ) 00294 { 00295 iloc = (long) ( (_r-minimum()) / dlargloc ) ; 00296 _r -= dlargloc * iloc ; 00297 if ( _r > maximum() ) 00298 _r = 2*maximum() - _r ; 00299 } 00300 00301 if (_r < minimum()) 00302 { 00303 iloc = (long) ( (maximum()-_r) / dlargloc ) ; 00304 _r += dlargloc * iloc ; 00305 if (_r < minimum()) 00306 _r = 2*minimum() - _r ; 00307 } 00308 } 00309 00310 // truncates to the bounds 00311 virtual void truncate(double & _r) const 00312 { 00313 if (_r < repMinimum) 00314 _r = repMinimum; 00315 else if (_r > repMaximum) 00316 _r = repMaximum; 00317 return; 00318 } 00319 00320 // methods from eoPersistent 00327 virtual void readFrom(std::istream& _is) 00328 { 00329 (void)_is; 00330 00331 throw std::runtime_error("Should not use eoIntInterval::readFrom"); 00332 } 00333 00338 virtual void printOn(std::ostream& _os) const 00339 { 00340 _os << "[" << repMinimum << "," << repMaximum << "]"; 00341 } 00342 00344 virtual eoIntBounds * dup() const 00345 { 00346 return new eoIntInterval(*this); 00347 } 00348 00349 private : 00350 long int repMinimum; 00351 long int repMaximum; 00352 long int repRange; // to minimize operations ??? 00353 }; 00354 00361 class eoIntBelowBound : public eoIntBounds 00362 { 00363 public : 00364 virtual ~eoIntBelowBound(){} 00368 eoIntBelowBound(long int _min=0) : 00369 repMinimum(_min) 00370 {} 00371 00372 // accessors 00373 virtual long int minimum() const { return repMinimum; } 00374 00375 virtual long int maximum() const 00376 { 00377 throw std::logic_error("Trying to get maximum of eoIntBelowBound"); 00378 } 00379 virtual long int range() const 00380 { 00381 throw std::logic_error("Trying to get range of eoIntBelowBound"); 00382 } 00383 00384 virtual double uniform(eoRng & _rng = eo::rng) const 00385 { 00386 (void)_rng; 00387 00388 throw std::logic_error("Trying to generate uniform values in eoIntBelowBound"); 00389 } 00390 00391 virtual long int random(eoRng & _rng = eo::rng) const 00392 { 00393 (void)_rng; 00394 00395 throw std::logic_error("Trying to generate uniform values in eoIntBelowBound"); 00396 } 00397 00398 // description 00399 virtual bool isBounded(void) const {return false;} 00400 virtual bool hasNoBoundAtAll(void) const {return false;} 00401 virtual bool isMinBounded(void) const {return true;} 00402 virtual bool isMaxBounded(void) const {return false;} 00403 00404 // says if a given double is within the bounds 00405 virtual bool isInBounds(double _r) const 00406 { 00407 if (_r < repMinimum) 00408 return false; 00409 return true; 00410 } 00411 00412 // folds a value into bounds 00413 virtual void foldsInBounds(double & _r) const 00414 { 00415 // easy as a pie: symmetry w.r.t. minimum 00416 if (_r < repMinimum) // nothing to do otherwise 00417 _r = 2*repMinimum - _r; 00418 return ; 00419 } 00420 00421 // truncates to the bounds 00422 virtual void truncate(double & _r) const 00423 { 00424 if (_r < repMinimum) 00425 _r = repMinimum; 00426 return; 00427 } 00428 00429 // methods from eoPersistent 00436 virtual void readFrom(std::istream& _is) 00437 { 00438 (void)_is; 00439 00440 throw std::runtime_error("Should not use eoIntBelowBound::readFrom"); 00441 } 00442 00447 virtual void printOn(std::ostream& _os) const 00448 { 00449 _os << "[" << repMinimum << ",+inf]"; 00450 } 00451 00453 virtual eoIntBounds * dup() const 00454 { 00455 return new eoIntBelowBound(*this); 00456 } 00457 00458 private : 00459 long int repMinimum; 00460 }; 00461 00468 class eoIntAboveBound : public eoIntBounds 00469 { 00470 public : 00471 virtual ~eoIntAboveBound(){} 00472 00476 eoIntAboveBound(long int _max=0) : 00477 repMaximum(_max) 00478 {} 00479 00480 // accessors 00481 virtual long int maximum() const { return repMaximum; } 00482 00483 virtual long int minimum() const 00484 { 00485 throw std::logic_error("Trying to get minimum of eoIntAboveBound"); 00486 } 00487 virtual long int range() const 00488 { 00489 throw std::logic_error("Trying to get range of eoIntAboveBound"); 00490 } 00491 00492 virtual double uniform(eoRng & _rng = eo::rng) const 00493 { 00494 (void)_rng; 00495 00496 throw std::logic_error("Trying to generate uniform values in eoIntAboveBound"); 00497 } 00498 00499 virtual long int random(eoRng & _rng = eo::rng) const 00500 { 00501 (void)_rng; 00502 00503 throw std::logic_error("Trying to generate uniform values in eoIntAboveBound"); 00504 } 00505 00506 // description 00507 virtual bool isBounded(void) const {return false;} 00508 virtual bool hasNoBoundAtAll(void) const {return false;} 00509 virtual bool isMinBounded(void) const {return false;} 00510 virtual bool isMaxBounded(void) const {return true;} 00511 00512 // says if a given double is within the bounds 00513 virtual bool isInBounds(double _r) const 00514 { 00515 if (_r > repMaximum) 00516 return false; 00517 return true; 00518 } 00519 00520 // folds a value into bounds 00521 virtual void foldsInBounds(double & _r) const 00522 { 00523 // easy as a pie: symmetry w.r.t. maximum 00524 if (_r > repMaximum) // nothing to do otherwise 00525 _r = 2*repMaximum - _r; 00526 return ; 00527 } 00528 00529 // truncates to the bounds 00530 virtual void truncate(double & _r) const 00531 { 00532 if (_r > repMaximum) 00533 _r = repMaximum; 00534 return; 00535 } 00536 00537 // methods from eoPersistent 00544 virtual void readFrom(std::istream& _is) 00545 { 00546 (void)_is; 00547 00548 throw std::runtime_error("Should not use eoIntAboveBound::readFrom"); 00549 } 00550 00555 virtual void printOn(std::ostream& _os) const 00556 { 00557 _os << "[-inf," << repMaximum << "]"; 00558 } 00559 00561 virtual eoIntBounds * dup() const 00562 { 00563 return new eoIntAboveBound(*this); 00564 } 00565 00566 private : 00567 long int repMaximum; 00568 }; 00569 00571 00578 class eoGeneralIntBounds : public eoIntBounds 00579 { 00580 public: 00582 eoGeneralIntBounds(std::string _s = "[-infinity,+infinity]") 00583 { 00584 repBound = getBoundsFromString(_s); 00585 } 00586 00588 eoGeneralIntBounds(const eoGeneralIntBounds & _b) : eoIntBounds(_b) 00589 { 00590 // replicate the embedded bound (I'm pretty sure there is another 00591 // way to do that !!! 00592 00593 bool minBounded = _b.isMinBounded(); 00594 bool maxBounded = _b.isMaxBounded(); 00595 long int minimum, maximum; 00596 const eoIntBounds & bb = _b.theBounds(); 00597 if (minBounded) minimum = bb.minimum(); 00598 if (maxBounded) maximum = bb.maximum(); 00599 00600 if (minBounded && maxBounded) 00601 repBound = new eoIntInterval(minimum, maximum); 00602 else if (!minBounded && !maxBounded) // no bound at all 00603 repBound = new eoIntNoBounds; 00604 else if (!minBounded && maxBounded) 00605 repBound = new eoIntAboveBound(maximum); 00606 else if (minBounded && !maxBounded) 00607 repBound = new eoIntBelowBound(minimum); 00608 } 00609 00610 eoGeneralIntBounds& operator=(const eoGeneralIntBounds& _b) 00611 { 00612 // replicate the embedded bound (I'm pretty sure there is another 00613 // way to do that !!! 00614 00615 bool minBounded = _b.isMinBounded(); 00616 bool maxBounded = _b.isMaxBounded(); 00617 long int minimum, maximum; 00618 const eoIntBounds & bb = _b.theBounds(); 00619 if (minBounded) minimum = bb.minimum(); 00620 if (maxBounded) maximum = bb.maximum(); 00621 00622 // first delete the embedded bounds if necessary 00623 if (repBound) 00624 delete repBound; 00625 // now reallocate 00626 if (minBounded && maxBounded) 00627 repBound = new eoIntInterval(minimum, maximum); 00628 else if (!minBounded && !maxBounded) // no bound at all 00629 repBound = new eoIntNoBounds; 00630 else if (!minBounded && maxBounded) 00631 repBound = new eoIntAboveBound(maximum); 00632 else if (minBounded && !maxBounded) 00633 repBound = new eoIntBelowBound(minimum); 00634 return (*this); 00635 } 00636 00637 00639 ~eoGeneralIntBounds() 00640 { 00641 delete repBound; 00642 } 00643 00645 00647 virtual bool isBounded(void) const {return repBound->isBounded();} 00648 00652 virtual bool hasNoBoundAtAll(void) const {return repBound->hasNoBoundAtAll();} 00653 00656 virtual bool isMinBounded(void) const {return repBound->isMinBounded();} 00657 00660 virtual bool isMaxBounded(void) const {return repBound->isMaxBounded();} 00661 00664 virtual bool isInBounds(double _x) const {return repBound->isInBounds(_x);} 00665 00668 virtual void foldsInBounds(double & _x) const {return repBound->foldsInBounds(_x);} 00669 00672 virtual void truncate(double & _x) const {return repBound->truncate(_x);} 00673 00677 virtual long int minimum() const {return repBound->minimum();} 00681 virtual long int maximum() const {return repBound->maximum();} 00685 virtual long int range() const {return repBound->range();} 00686 00690 virtual double uniform(eoRng & _rng = eo::rng) const {(void)_rng; return repBound->uniform();} 00691 00695 virtual long int random(eoRng & _rng = eo::rng) const {(void)_rng; return repBound->random();} 00696 00698 virtual eoIntBounds * dup() const {return repBound->dup();} 00699 00701 const eoIntBounds & theBounds() const { return *repBound;} 00702 00706 virtual void printOn(std::ostream& _os) const 00707 { 00708 repBound->printOn(_os); 00709 } 00710 00712 virtual void readFrom(std::istream& _is) 00713 { 00714 std::string s; 00715 _is >> s; 00716 if (repBound) 00717 delete repBound; 00718 repBound = getBoundsFromString(s); 00719 } 00720 00721 private: 00722 // reading from a string 00723 eoIntBounds * getBoundsFromString(std::string); 00724 00725 eoIntBounds * repBound; 00726 }; 00727 00728 00729 #endif