EvolvingObjects
|
00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- 00002 00003 //----------------------------------------------------------------------------- 00004 // eoRealBounds.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 _eoRealBounds_h 00028 #define _eoRealBounds_h 00029 00030 #include <stdexcept> // std::exceptions! 00031 #include <utils/eoRNG.h> 00032 00085 class eoRealBounds : public eoPersistent 00086 { 00087 public: 00088 virtual ~eoRealBounds(){} 00089 00092 virtual bool isBounded(void) const = 0; 00093 00097 virtual bool hasNoBoundAtAll(void) const = 0; 00098 00101 virtual bool isMinBounded(void) const = 0; 00102 00105 virtual bool isMaxBounded(void) const = 0; 00106 00109 virtual bool isInBounds(double) const = 0; 00110 00113 virtual void foldsInBounds(double &) const = 0; 00114 00117 virtual void truncate(double &) const = 0; 00118 00122 virtual double minimum() const = 0 ; 00126 virtual double maximum() const = 0 ; 00130 virtual double range() const = 0; 00131 00135 virtual double uniform(eoRng & _rng = eo::rng) const = 0; 00136 00138 virtual eoRealBounds * dup() const = 0; 00139 }; 00140 00145 class eoRealNoBounds : public eoRealBounds 00146 { 00147 public: 00148 virtual ~eoRealNoBounds(){} 00149 00150 virtual bool isBounded(void) const {return false;} 00151 virtual bool hasNoBoundAtAll(void) const {return true;} 00152 virtual bool isMinBounded(void) const {return false;} 00153 virtual bool isMaxBounded(void) const {return false;} 00154 virtual void foldsInBounds(double &) const {return;} 00155 virtual void truncate(double &) const {return;} 00156 virtual bool isInBounds(double) const {return true;} 00157 00158 virtual double minimum() const 00159 { 00160 throw std::logic_error("Trying to get minimum of unbounded eoRealBounds"); 00161 } 00162 virtual double maximum() const 00163 { 00164 throw std::logic_error("Trying to get maximum of unbounded eoRealBounds"); 00165 } 00166 virtual double range() const 00167 { 00168 throw std::logic_error("Trying to get range of unbounded eoRealBounds"); 00169 } 00170 00171 virtual double uniform(eoRng & _rng = eo::rng) const 00172 { 00173 (void)_rng; 00174 00175 throw std::logic_error("Trying to generate uniform values in unbounded eoRealBounds"); 00176 } 00177 00178 // methods from eoPersistent 00185 virtual void readFrom(std::istream& _is) 00186 { 00187 (void)_is; 00188 00189 throw std::runtime_error("Should not use eoRealBounds::readFrom"); 00190 } 00191 00196 virtual void printOn(std::ostream& _os) const 00197 { 00198 _os << "[-inf,+inf]"; 00199 } 00200 00202 virtual eoRealBounds * dup() const 00203 { 00204 return new eoRealNoBounds(*this); 00205 } 00206 00207 }; 00208 00212 extern eoRealNoBounds eoDummyRealNoBounds; 00213 00219 class eoRealInterval : public eoRealBounds 00220 { 00221 public : 00222 virtual ~eoRealInterval(){} 00223 00227 eoRealInterval(double _min=0, double _max=1) : 00228 repMinimum(_min), repMaximum(_max), repRange(_max-_min) 00229 { 00230 if (repRange<=0) 00231 throw std::logic_error("Void range in eoRealBounds"); 00232 } 00233 00234 // accessors 00235 virtual double minimum() const { return repMinimum; } 00236 virtual double maximum() const { return repMaximum; } 00237 virtual double range() const { return repRange; } 00238 00239 // description 00240 virtual bool isBounded(void) const {return true;} 00241 virtual bool hasNoBoundAtAll(void) const {return false;} 00242 virtual bool isMinBounded(void) const {return true;} 00243 virtual bool isMaxBounded(void) const {return true;} 00244 00245 virtual double uniform(eoRng & _rng = eo::rng) const 00246 { 00247 return repMinimum + _rng.uniform(repRange); 00248 } 00249 00250 // says if a given double is within the bounds 00251 virtual bool isInBounds(double _r) const 00252 { 00253 if (_r < repMinimum) 00254 return false; 00255 if (_r > repMaximum) 00256 return false; 00257 return true; 00258 } 00259 00260 // folds a value into bounds 00261 virtual void foldsInBounds(double & _r) const 00262 { 00263 long iloc; 00264 double dlargloc = 2 * range() ; 00265 00266 if (fabs(_r) > 1.0E9) // iloc too large! 00267 { 00268 _r = uniform(); 00269 return; 00270 } 00271 00272 if ( (_r > maximum()) ) 00273 { 00274 iloc = (long) ( (_r-minimum()) / dlargloc ) ; 00275 _r -= dlargloc * iloc ; 00276 if ( _r > maximum() ) 00277 _r = 2*maximum() - _r ; 00278 } 00279 00280 if (_r < minimum()) 00281 { 00282 iloc = (long) ( (maximum()-_r) / dlargloc ) ; 00283 _r += dlargloc * iloc ; 00284 if (_r < minimum()) 00285 _r = 2*minimum() - _r ; 00286 } 00287 } 00288 00289 // truncates to the bounds 00290 virtual void truncate(double & _r) const 00291 { 00292 if (_r < repMinimum) 00293 _r = repMinimum; 00294 else if (_r > repMaximum) 00295 _r = repMaximum; 00296 return; 00297 } 00298 00299 // methods from eoPersistent 00306 virtual void readFrom(std::istream& _is) 00307 { 00308 (void)_is; 00309 00310 throw std::runtime_error("Should not use eoRealInterval::readFrom"); 00311 } 00312 00317 virtual void printOn(std::ostream& _os) const 00318 { 00319 _os << "[" << repMinimum << "," << repMaximum << "]"; 00320 } 00321 00323 virtual eoRealBounds * dup() const 00324 { 00325 return new eoRealInterval(*this); 00326 } 00327 00328 private : 00329 double repMinimum; 00330 double repMaximum; 00331 double repRange; // to minimize operations ??? 00332 }; 00333 00339 class eoRealBelowBound : public eoRealBounds 00340 { 00341 public : 00342 virtual ~eoRealBelowBound(){} 00346 eoRealBelowBound(double _min=0) : 00347 repMinimum(_min) 00348 {} 00349 00350 // accessors 00351 virtual double minimum() const { return repMinimum; } 00352 00353 virtual double maximum() const 00354 { 00355 throw std::logic_error("Trying to get maximum of eoRealBelowBound"); 00356 } 00357 virtual double range() const 00358 { 00359 throw std::logic_error("Trying to get range of eoRealBelowBound"); 00360 } 00361 00362 // random generators 00363 virtual double uniform(eoRng & _rng = eo::rng) const 00364 { 00365 (void)_rng; 00366 00367 throw std::logic_error("Trying to generate uniform values in eoRealBelowBound"); 00368 } 00369 00370 // description 00371 virtual bool isBounded(void) const {return false;} 00372 virtual bool hasNoBoundAtAll(void) const {return false;} 00373 virtual bool isMinBounded(void) const {return true;} 00374 virtual bool isMaxBounded(void) const {return false;} 00375 00376 // says if a given double is within the bounds 00377 virtual bool isInBounds(double _r) const 00378 { 00379 if (_r < repMinimum) 00380 return false; 00381 return true; 00382 } 00383 00384 // folds a value into bounds 00385 virtual void foldsInBounds(double & _r) const 00386 { 00387 // easy as a pie: symmetry w.r.t. minimum 00388 if (_r < repMinimum) // nothing to do otherwise 00389 _r = 2*repMinimum - _r; 00390 return ; 00391 } 00392 00393 // truncates to the bounds 00394 virtual void truncate(double & _r) const 00395 { 00396 if (_r < repMinimum) 00397 _r = repMinimum; 00398 return; 00399 } 00400 00401 // methods from eoPersistent 00408 virtual void readFrom(std::istream& _is) 00409 { 00410 (void)_is; 00411 00412 throw std::runtime_error("Should not use eoRealBelowBound::readFrom"); 00413 } 00414 00419 virtual void printOn(std::ostream& _os) const 00420 { 00421 _os << "[" << repMinimum << ",+inf]"; 00422 } 00423 00425 virtual eoRealBounds * dup() const 00426 { 00427 return new eoRealBelowBound(*this); 00428 } 00429 00430 private : 00431 double repMinimum; 00432 }; 00433 00437 class eoRealAboveBound : public eoRealBounds 00438 { 00439 public : 00440 virtual ~eoRealAboveBound(){} 00441 00445 eoRealAboveBound(double _max=0) : 00446 repMaximum(_max) 00447 {} 00448 00449 // accessors 00450 virtual double maximum() const { return repMaximum; } 00451 00452 virtual double minimum() const 00453 { 00454 throw std::logic_error("Trying to get minimum of eoRealAboveBound"); 00455 } 00456 virtual double range() const 00457 { 00458 throw std::logic_error("Trying to get range of eoRealAboveBound"); 00459 } 00460 00461 // random generators 00462 virtual double uniform(eoRng & _rng = eo::rng) const 00463 { 00464 (void)_rng; 00465 00466 throw std::logic_error("Trying to generate uniform values in eoRealAboveBound"); 00467 } 00468 00469 // description 00470 virtual bool isBounded(void) const {return false;} 00471 virtual bool hasNoBoundAtAll(void) const {return false;} 00472 virtual bool isMinBounded(void) const {return false;} 00473 virtual bool isMaxBounded(void) const {return true;} 00474 00475 // says if a given double is within the bounds 00476 virtual bool isInBounds(double _r) const 00477 { 00478 if (_r > repMaximum) 00479 return false; 00480 return true; 00481 } 00482 00483 // folds a value into bounds 00484 virtual void foldsInBounds(double & _r) const 00485 { 00486 // easy as a pie: symmetry w.r.t. maximum 00487 if (_r > repMaximum) // nothing to do otherwise 00488 _r = 2*repMaximum - _r; 00489 return ; 00490 } 00491 00492 // truncates to the bounds 00493 virtual void truncate(double & _r) const 00494 { 00495 if (_r > repMaximum) 00496 _r = repMaximum; 00497 return; 00498 } 00499 00500 // methods from eoPersistent 00507 virtual void readFrom(std::istream& _is) 00508 { 00509 (void)_is; 00510 00511 throw std::runtime_error("Should not use eoRealAboveBound::readFrom"); 00512 } 00513 00518 virtual void printOn(std::ostream& _os) const 00519 { 00520 _os << "[-inf," << repMaximum << "]"; 00521 } 00522 00524 virtual eoRealBounds * dup() const 00525 { 00526 return new eoRealAboveBound(*this); 00527 } 00528 00529 private : 00530 double repMaximum; 00531 }; 00532 00534 00540 class eoGeneralRealBounds : public eoRealBounds 00541 { 00542 public: 00544 eoGeneralRealBounds(std::string _s = "[-infinity,+infinity]") 00545 { 00546 repBound = getBoundsFromString(_s); 00547 } 00548 00550 eoGeneralRealBounds(const eoGeneralRealBounds & _b):eoRealBounds(_b) 00551 { 00552 // replicate the embedded bound (I'm pretty sure there is another 00553 // way to do that !!! 00554 00555 bool minBounded = _b.isMinBounded(); 00556 bool maxBounded = _b.isMaxBounded(); 00557 double minimum, maximum; 00558 const eoRealBounds & bb = _b.theBounds(); 00559 if (minBounded) minimum = bb.minimum(); 00560 if (maxBounded) maximum = bb.maximum(); 00561 00562 if (minBounded && maxBounded) 00563 repBound = new eoRealInterval(minimum, maximum); 00564 else if (!minBounded && !maxBounded) // no bound at all 00565 repBound = new eoRealNoBounds; 00566 else if (!minBounded && maxBounded) 00567 repBound = new eoRealAboveBound(maximum); 00568 else if (minBounded && !maxBounded) 00569 repBound = new eoRealBelowBound(minimum); 00570 } 00571 00572 eoGeneralRealBounds& operator=(const eoGeneralRealBounds& _b) 00573 { 00574 // replicate the embedded bound (I'm pretty sure there is another 00575 // way to do that !!! 00576 00577 bool minBounded = _b.isMinBounded(); 00578 bool maxBounded = _b.isMaxBounded(); 00579 double minimum, maximum; 00580 const eoRealBounds & bb = _b.theBounds(); 00581 if (minBounded) minimum = bb.minimum(); 00582 if (maxBounded) maximum = bb.maximum(); 00583 00584 // first delete the embedded bounds if necessary 00585 if (repBound) 00586 delete repBound; 00587 // now reallocate 00588 if (minBounded && maxBounded) 00589 repBound = new eoRealInterval(minimum, maximum); 00590 else if (!minBounded && !maxBounded) // no bound at all 00591 repBound = new eoRealNoBounds; 00592 else if (!minBounded && maxBounded) 00593 repBound = new eoRealAboveBound(maximum); 00594 else if (minBounded && !maxBounded) 00595 repBound = new eoRealBelowBound(minimum); 00596 return (*this); 00597 } 00598 00599 00601 ~eoGeneralRealBounds() 00602 { 00603 delete repBound; 00604 } 00605 00607 00609 virtual bool isBounded(void) const {return repBound->isBounded();} 00610 00614 virtual bool hasNoBoundAtAll(void) const {return repBound->hasNoBoundAtAll();} 00615 00618 virtual bool isMinBounded(void) const {return repBound->isMinBounded();} 00619 00622 virtual bool isMaxBounded(void) const {return repBound->isMaxBounded();} 00623 00626 virtual bool isInBounds(double _x) const {return repBound->isInBounds(_x);} 00627 00630 virtual void foldsInBounds(double & _x) const {return repBound->foldsInBounds(_x);} 00631 00634 virtual void truncate(double & _x) const {return repBound->truncate(_x);} 00635 00639 virtual double minimum() const {return repBound->minimum();} 00643 virtual double maximum() const {return repBound->maximum();} 00647 virtual double range() const {return repBound->range();} 00648 00652 virtual double uniform(eoRng & _rng = eo::rng) const {(void)_rng; return repBound->uniform();} 00653 00655 virtual eoRealBounds * dup() const {return repBound->dup();} 00656 00658 const eoRealBounds & theBounds() const { return *repBound;} 00659 00663 virtual void printOn(std::ostream& _os) const 00664 { 00665 repBound->printOn(_os); 00666 } 00667 00669 virtual void readFrom(std::istream& _is) 00670 { 00671 std::string s; 00672 _is >> s; 00673 if (repBound) 00674 delete repBound; 00675 repBound = getBoundsFromString(s); 00676 } 00677 00678 private: 00679 // reading from a string 00680 eoRealBounds * getBoundsFromString(std::string); 00681 00682 eoRealBounds * repBound; 00683 }; 00684 00685 00686 #endif