eoIntBounds.h

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 
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   // methods from eoPersistent
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 // one object for all - see eoIntBounds.cpp
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   // accessors  
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   // description
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   // says if a given double is within the bounds
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   // folds a value into bounds
00270   virtual void foldsInBounds(double &  _r) const 
00271   {
00272     long iloc;
00273     double dlargloc = 2 * range() ;
00274 
00275     if (fabs(_r) > 1.0E9)               // iloc too large!
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   // truncates to the bounds
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   // methods from eoPersistent
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;                       // to minimize operations ???
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   // accessors  
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   // description
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   // says if a given double is within the bounds
00383   virtual bool isInBounds(double _r) const 
00384   {
00385     if (_r < repMinimum)
00386       return false;
00387     return true;
00388   }
00389 
00390   // folds a value into bounds
00391   virtual void foldsInBounds(double &  _r) const 
00392   {
00393     // easy as a pie: symmetry w.r.t. minimum
00394     if (_r < repMinimum)           // nothing to do otherwise
00395       _r = 2*repMinimum - _r;
00396     return ;
00397   }    
00398 
00399   // truncates to the bounds
00400   virtual void truncate(double & _r) const 
00401   {
00402     if (_r < repMinimum)
00403       _r = repMinimum;
00404     return;
00405   }
00406 
00407   // methods from eoPersistent
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   // accessors  
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   // description
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   // says if a given double is within the bounds
00481   virtual bool isInBounds(double _r) const 
00482   {
00483     if (_r > repMaximum)
00484       return false;
00485     return true;
00486   }
00487 
00488   // folds a value into bounds
00489   virtual void foldsInBounds(double &  _r) const 
00490   {
00491     // easy as a pie: symmetry w.r.t. maximum
00492     if (_r > repMaximum)           // nothing to do otherwise
00493       _r = 2*repMaximum - _r;
00494     return ;
00495   }    
00496 
00497   // truncates to the bounds
00498   virtual void truncate(double & _r) const 
00499   {
00500     if (_r > repMaximum)
00501       _r = repMaximum;
00502     return;
00503   }
00504 
00505   // methods from eoPersistent
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     // replicate the embedded bound (I'm pretty sure there is another
00554     // way to do that !!!
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)      // no bound at all
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     // replicate the embedded bound (I'm pretty sure there is another
00576     // way to do that !!!
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     // first delete the embedded bounds if necessary
00586     if (repBound)
00587       delete repBound;
00588     // now reallocate
00589       if (minBounded && maxBounded)
00590         repBound = new eoIntInterval(minimum, maximum);
00591       else if (!minBounded && !maxBounded)      // no bound at all
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   // reading from a string
00686   eoIntBounds * getBoundsFromString(std::string);
00687 
00688   eoIntBounds * repBound;
00689 };
00690 
00691 
00692 #endif

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