EvolvingObjects
eoRealBounds.cpp
00001 #ifdef _MSC_VER
00002 // to avoid long name warnings
00003 #pragma warning(disable:4786)
00004 #endif
00005 
00006 #ifdef HAVE_CONFIG_H
00007 #include <config.h>
00008 #endif
00009 
00010 #include <ctime>
00011 #include <sstream>
00012 
00013 #include "eoRealBounds.h"
00014 #include "eoRealVectorBounds.h"
00015 
00016 
00017 // the global dummy bounds
00018 // (used for unbounded variables when bounds are required)
00019 eoRealNoBounds eoDummyRealNoBounds;
00020 eoRealVectorNoBounds eoDummyVectorNoBounds(0);
00021 
00023 
00024 // removes leading delimiters - return false if nothing else left
00025 bool remove_leading(std::string & _s, const std::string _delim)
00026 {
00027   size_t posDebToken = _s.find_first_not_of(_delim);
00028   if (posDebToken >= _s.size())
00029     return false;
00030   _s = _s.substr(posDebToken);
00031   return true;
00032 }
00033 
00034 double read_double(std::string _s)
00035 {
00036     std::istringstream is(_s);
00037   double r;
00038   is >> r;
00039   return r;
00040 }
00041 
00042 long int read_int(std::string _s)
00043 {
00044     std::istringstream is(_s);
00045   long int i;
00046   is >> i;
00047   return i;
00048 }
00049 
00050 // need to rewrite copy ctor and assignement operator because of ownedBounds
00051 eoRealVectorBounds::eoRealVectorBounds(const eoRealVectorBounds & _b):
00052     eoRealBaseVectorBounds(_b), eoPersistent()
00053 {
00054   factor = _b.factor;
00055   ownedBounds = _b.ownedBounds;
00056   // duplicate all pointers!
00057   if (ownedBounds.size()>0)
00058     for (unsigned i=0; i<ownedBounds.size(); i++)
00059       ownedBounds[i] = ownedBounds[i]->dup();
00060 }
00061 
00062 
00063 // the readFrom method of eoRealVectorNoBounds:
00064 // only calls the readFrom(string) - for param reading
00065 void eoRealVectorBounds::readFrom(std::istream& _is)
00066 {
00067   std::string value;
00068   _is >> value;
00069   readFrom(value);
00070   return;
00071 }
00072 
00073 void eoRealVectorBounds::readFrom(std::string _value)
00074 {
00075   // keep track of old size - to adjust in the end
00076   unsigned oldSize = size();
00077   // clean-up before filling in
00078   if (ownedBounds.size()>0)
00079     for (unsigned i = 0; i < ownedBounds.size(); ++i)
00080       {
00081         delete ownedBounds[i];
00082       }
00083   ownedBounds.resize(0);
00084   factor.resize(0);
00085   resize(0);
00086 
00087   // now read
00088   std::string delim(",; ");
00089   while (_value.size()>0)
00090     {
00091       if (!remove_leading(_value, delim)) // only delimiters were left
00092         break;
00093       // look for opening char
00094       size_t posDeb = _value.find_first_of("[(");
00095       if (posDeb >= _value.size())      // nothing left to read (though probably a syntax error there)
00096         {
00097           break;
00098         }
00099       // ending char
00100       std::string closeChar = (_value[posDeb] == '(' ? std::string(")") : std::string("]") );
00101 
00102       size_t posFin = _value.find_first_of(std::string(closeChar));
00103       if (posFin >= _value.size())
00104         throw std::runtime_error("Syntax error when reading bounds");
00105 
00106   // y a-t-il un nbre devant
00107       unsigned count = 1;
00108       if (posDeb > 0)                   // something before opening
00109         {
00110           std::string sCount = _value.substr(0, posDeb);
00111           count = read_int(sCount);
00112           if (count <= 0)
00113             throw std::runtime_error("Syntax error when reading bounds");
00114         }
00115 
00116       // the bounds
00117       std::string sBounds = _value.substr(posDeb+1, posFin-posDeb-1);
00118       // and remove from original string
00119       _value = _value.substr(posFin+1);
00120 
00121       remove_leading(sBounds, delim);
00122       size_t posDelim = sBounds.find_first_of(delim);
00123       if (posDelim >= sBounds.size())
00124         throw std::runtime_error("Syntax error when reading bounds");
00125 
00126       bool minBounded=false, maxBounded=false;
00127       double minBound=0, maxBound=0;
00128 
00129       // min bound
00130       std::string sMinBounds = sBounds.substr(0,posDelim);
00131       if (sMinBounds != std::string("-inf"))
00132         {
00133           minBounded = true;
00134           minBound = read_double(sMinBounds);
00135         }
00136 
00137       // max bound
00138       size_t posEndDelim = sBounds.find_first_not_of(delim,posDelim);
00139 
00140       std::string sMaxBounds = sBounds.substr(posEndDelim);
00141       if (sMaxBounds != std::string("+inf"))
00142         {
00143           maxBounded = true;
00144           maxBound = read_double(sMaxBounds);
00145         }
00146 
00147       // now create the eoRealBounds objects
00148       eoRealBounds *ptBounds;
00149       if (minBounded && maxBounded)
00150         ptBounds = new eoRealInterval(minBound, maxBound);
00151       else if (!minBounded && !maxBounded)      // no bound at all
00152         ptBounds = new eoRealNoBounds;
00153       else if (!minBounded && maxBounded)
00154         ptBounds = new eoRealAboveBound(maxBound);
00155       else if (minBounded && !maxBounded)
00156         ptBounds = new eoRealBelowBound(minBound);
00157       // store it for memory management
00158       ownedBounds.push_back(ptBounds);
00159       // push the count
00160       factor.push_back(count);
00161       // and add count of it to the actual bounds
00162       for (unsigned i=0; i<count; i++)
00163         push_back(ptBounds);
00164     }
00165   // now adjust the size to the initial value
00166   adjust_size(oldSize);
00167 }
00168 
00170 void eoRealVectorBounds::adjust_size(unsigned _dim)
00171 {
00172   if ( size() < _dim )
00173     {
00174       // duplicate last bound
00175       unsigned missing = _dim-size();
00176       eoRealBounds * ptBounds = back();
00177       for (unsigned i=0; i<missing; i++)
00178         push_back(ptBounds);
00179       // update last factor (warning: can be > 1 already!)
00180       factor[factor.size()-1] += missing;
00181     }
00182 }
00183 
00189 eoRealBounds* eoGeneralRealBounds::getBoundsFromString(std::string _value)
00190 {
00191   // now read
00192   std::string delim(",; ");
00193   std::string beginOrClose("[(])");
00194   if (!remove_leading(_value, delim)) // only delimiters were left
00195     throw std::runtime_error("Syntax error in eoGeneralRealBounds Ctor");
00196 
00197   // look for opening char
00198   size_t posDeb = _value.find_first_of(beginOrClose);   // allow ]a,b]
00199   if (posDeb >= _value.size())  // nothing left to read
00200     throw std::runtime_error("Syntax error in eoGeneralRealBounds Ctor");
00201 
00202   // ending char: next {}() after posDeb
00203   size_t posFin = _value.find_first_of(beginOrClose,posDeb+1);
00204   if (posFin >= _value.size())  // not found
00205     throw std::runtime_error("Syntax error in eoGeneralRealBounds Ctor");
00206 
00207   // the bounds
00208   std::string sBounds = _value.substr(posDeb+1, posFin-posDeb-1);
00209   // and remove from original string
00210   _value = _value.substr(posFin+1);
00211 
00212   remove_leading(sBounds, delim);
00213   size_t posDelim = sBounds.find_first_of(delim);
00214   if (posDelim >= sBounds.size())
00215     throw std::runtime_error("Syntax error in eoGeneralRealBounds Ctor");
00216 
00217       bool minBounded=false, maxBounded=false;
00218       double minBound=0, maxBound=0;
00219 
00220       // min bound
00221       std::string sMinBounds = sBounds.substr(0,posDelim);
00222 
00223       if ( (sMinBounds != std::string("-inf")) &&
00224            (sMinBounds != std::string("-infinity"))
00225            )
00226         {
00227           minBounded = true;
00228           minBound = read_double(sMinBounds);
00229         }
00230 
00231       // max bound
00232       size_t posEndDelim = sBounds.find_first_not_of(delim,posDelim);
00233 
00234       std::string sMaxBounds = sBounds.substr(posEndDelim);
00235 
00236       if ( (sMaxBounds != std::string("+inf")) &&
00237            (sMaxBounds != std::string("+infinity"))
00238            )
00239         {
00240           maxBounded = true;
00241           maxBound = read_double(sMaxBounds);
00242         }
00243 
00244       // now create the embedded eoRealBounds object
00245       eoRealBounds * locBound;
00246       if (minBounded && maxBounded)
00247         {
00248           if (maxBound <= minBound)
00249             throw std::runtime_error("Syntax error in eoGeneralRealBounds Ctor");
00250           locBound = new eoRealInterval(minBound, maxBound);
00251         }
00252       else if (!minBounded && !maxBounded)      // no bound at all
00253         locBound = new eoRealNoBounds;
00254       else if (!minBounded && maxBounded)
00255         locBound = new eoRealAboveBound(maxBound);
00256       else if (minBounded && !maxBounded)
00257         locBound = new eoRealBelowBound(minBound);
00258       return locBound;
00259 }
 All Classes Namespaces Files Functions Variables Typedefs Friends