EvolvingObjects
|
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 }