# 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)
    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 }