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