eoRealBounds.h

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 
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   // methods from eoPersistent
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 // one object for all - see eoRealBounds.cpp
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   // accessors  
00215   virtual double minimum() const { return repMinimum; }
00216   virtual double maximum() const { return repMaximum; }
00217   virtual double range()  const { return repRange; }
00218 
00219   // description
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   // says if a given double is within the bounds
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   // folds a value into bounds
00241   virtual void foldsInBounds(double &  _r) const 
00242   {
00243     long iloc;
00244     double dlargloc = 2 * range() ;
00245 
00246     if (fabs(_r) > 1.0E9)               // iloc too large!
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   // truncates to the bounds
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   // methods from eoPersistent
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;                         // to minimize operations ???
00310 };
00311 
00315 class eoRealBelowBound : public eoRealBounds
00316 {
00317 public :
00318   virtual ~eoRealBelowBound(){}  
00322   eoRealBelowBound(double _min=0) : 
00323     repMinimum(_min)
00324   {}
00325 
00326   // accessors  
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   // random generators
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   // description
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   // says if a given double is within the bounds
00351   virtual bool isInBounds(double _r) const 
00352   {
00353     if (_r < repMinimum)
00354       return false;
00355     return true;
00356   }
00357 
00358   // folds a value into bounds
00359   virtual void foldsInBounds(double &  _r) const 
00360   {
00361     // easy as a pie: symmetry w.r.t. minimum
00362     if (_r < repMinimum)           // nothing to do otherwise
00363       _r = 2*repMinimum - _r;
00364     return ;
00365   }    
00366 
00367   // truncates to the bounds
00368   virtual void truncate(double & _r) const 
00369   {
00370     if (_r < repMinimum)
00371       _r = repMinimum;
00372     return;
00373   }
00374 
00375   // methods from eoPersistent
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   // accessors  
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   // random generators
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   // description
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   // says if a given double is within the bounds
00446   virtual bool isInBounds(double _r) const 
00447   {
00448     if (_r > repMaximum)
00449       return false;
00450     return true;
00451   }
00452 
00453   // folds a value into bounds
00454   virtual void foldsInBounds(double &  _r) const 
00455   {
00456     // easy as a pie: symmetry w.r.t. maximum
00457     if (_r > repMaximum)           // nothing to do otherwise
00458       _r = 2*repMaximum - _r;
00459     return ;
00460   }    
00461 
00462   // truncates to the bounds
00463   virtual void truncate(double & _r) const 
00464   {
00465     if (_r > repMaximum)
00466       _r = repMaximum;
00467     return;
00468   }
00469 
00470   // methods from eoPersistent
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     // replicate the embedded bound (I'm pretty sure there is another
00519     // way to do that !!!
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)      // no bound at all
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     // replicate the embedded bound (I'm pretty sure there is another
00541     // way to do that !!!
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     // first delete the embedded bounds if necessary
00551     if (repBound)
00552       delete repBound;
00553     // now reallocate
00554       if (minBounded && maxBounded)
00555         repBound = new eoRealInterval(minimum, maximum);
00556       else if (!minBounded && !maxBounded)      // no bound at all
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   // reading from a string
00646   eoRealBounds * getBoundsFromString(std::string);
00647 
00648   eoRealBounds * repBound;
00649 };
00650 
00651 
00652 #endif

Generated on Thu Oct 19 05:06:37 2006 for EO by  doxygen 1.3.9.1