EvolvingObjects
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 
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
 All Classes Namespaces Files Functions Variables Typedefs Friends