00001 #include "MappingBase.h"
00002 #include <assert.h>
00003
00004
00005 const Dimension Dimension::time = Dimension::time_static();
00006 const Dimension Dimension::frequency = Dimension::frequency_static();
00007
00008 int& Dimension::nextFreeID () {
00009 static int* nextID = new int(1);
00010 return *nextID;
00011 }
00012
00013 Dimension::DimensionIDMap& Dimension::dimensionIDs() {
00014
00015
00016 static DimensionIDMap* dimIDs = new DimensionIDMap();
00017 return *dimIDs;
00018 }
00019
00020 Dimension::DimensionNameMap& Dimension::dimensionNames() {
00021
00022
00023 static DimensionNameMap* names = new DimensionNameMap();
00024 return *names;
00025 }
00026
00027 Dimension& Dimension::time_static() {
00028
00029
00030 static Dimension* time = new Dimension("time");
00031 return *time;
00032 }
00033
00034 Dimension& Dimension::frequency_static() {
00035 static Dimension* freq = new Dimension("frequency");
00036 return *freq;
00037 }
00038
00039 int Dimension::getDimensionID(const std::string& name)
00040 {
00041
00042 static DimensionIDMap& dimensionIDs = Dimension::dimensionIDs();
00043 static int& nextFreeID = Dimension::nextFreeID();
00044 static DimensionNameMap& dimensionNames = Dimension::dimensionNames();
00045
00046 DimensionIDMap::iterator it = dimensionIDs.lower_bound(name);
00047
00048 if(it == dimensionIDs.end() || it->first != name){
00049 int newID = 0;
00050
00051
00052 if(name == "time")
00053 newID = 0;
00054 else
00055 newID = nextFreeID++;
00056
00057 it = dimensionIDs.insert(it, DimensionIDMap::value_type(name, newID));
00058 dimensionNames[newID] = name;
00059 }
00060
00061 return it->second;
00062 }
00063
00064 Dimension::Dimension(const std::string & name):
00065 id(getDimensionID(name)){}
00066
00067 bool Dimension::operator ==(const Dimension & other) const
00068 {
00069 return id == other.id;
00070 }
00071
00072 bool Dimension::operator <(const Dimension & other) const
00073 {
00074 return id < other.id;
00075 }
00076
00077
00078 const DimensionSet DimensionSet::timeDomain(Dimension::time_static());
00079 const DimensionSet DimensionSet::timeFreqDomain(Dimension::time_static(), Dimension::frequency_static());
00080
00081
00082
00083 Argument::Argument(simtime_t timeVal):
00084 time(timeVal), values(), count(0) {}
00085
00086 Argument::Argument(const DimensionSet & dims, simtime_t timeVal):
00087 time(timeVal), values(), count(0)
00088 {
00089 DimensionSet::const_iterator it = dims.begin();
00090
00091 assert((*it) == Dimension::time_static());
00092
00093 it++;
00094 while(it != dims.end()) {
00095 values[count] = std::pair<Dimension, double>(*it, 0.0);
00096 count++;
00097 it++;
00098 }
00099 }
00100
00101 simtime_t Argument::getTime() const
00102 {
00103 return time;
00104 }
00105
00106 void Argument::setTime(simtime_t time)
00107 {
00108 this->time = time;
00109 }
00110
00111 Argument::iterator Argument::find(const Dimension& dim){
00112 assert(!(dim == Dimension::time_static()));
00113
00114 for(iterator it = begin(); it != end() && it->first <= dim; ++it){
00115 if(it->first == dim)
00116 return it;
00117 }
00118
00119 return end();
00120 }
00121 Argument::const_iterator Argument::find(const Dimension& dim) const{
00122 assert(!(dim == Dimension::time_static()));
00123
00124 for(const_iterator it = begin(); it != end() && it->first <= dim; ++it){
00125 if(it->first == dim)
00126 return it;
00127 }
00128
00129 return end();
00130 }
00131
00132 Argument::iterator Argument::lower_bound(const Dimension& dim){
00133 assert(!(dim == Dimension::time_static()));
00134
00135 iterator it = begin();
00136 while(it != end() && it->first < dim)
00137 ++it;
00138
00139 return it;
00140 }
00141 Argument::const_iterator Argument::lower_bound(const Dimension& dim) const{
00142 assert(!(dim == Dimension::time_static()));
00143
00144 const_iterator it = begin();
00145 while(it != end() && it->first < dim)
00146 ++it;
00147
00148 return it;
00149 }
00150
00151 bool Argument::hasArgVal(const Dimension& dim) const{
00152 return find(dim) != end();
00153 }
00154
00155 double Argument::getArgValue(const Dimension & dim) const
00156 {
00157 const_iterator it = find(dim);
00158
00159 if(it == end())
00160 return double();
00161
00162 return it->second;
00163 }
00164
00165 void Argument::setArgValue(const Dimension & dim, double value)
00166 {
00167 assert(!(dim == Dimension::time_static()));
00168
00169 insertValue(begin(), dim, value);
00170 }
00171
00172 Argument::iterator Argument::insertValue(iterator pos, const Dimension& dim, double value, bool ignoreUnknown){
00173 while(pos != end() && !(dim < pos->first)){
00174
00175 if(pos->first == dim){
00176 pos->second = value;
00177 return pos;
00178 }
00179 ++pos;
00180 }
00181
00182 if(ignoreUnknown)
00183 return pos;
00184
00185 if(pos == end()){
00186 count++;
00187 *pos = std::pair<Dimension, double>(dim, value);
00188 } else {
00189 count++;
00190 iterator tmpPos = pos;
00191 std::pair<Dimension, double> n = *tmpPos;
00192 *tmpPos = std::pair<Dimension, double>(dim, value);
00193 while(++tmpPos != end()){
00194 std::pair<Dimension, double> tmp = *tmpPos;
00195 *tmpPos = n;
00196 n = tmp;
00197 }
00198 }
00199
00200 return pos;
00201 }
00202
00203 void Argument::setArgValues(const Argument& o, bool ingoreUnknown){
00204 time = o.time;
00205
00206 iterator pos = begin();
00207 for(const_iterator i = o.begin(); i != o.end(); i++){
00208 pos = insertValue(pos, i->first, i->second, ingoreUnknown);
00209 }
00210 }
00211
00212 bool Argument::isSamePosition(const Argument & o) const
00213 {
00214 if(count < o.count){
00215 return false;
00216 }
00217
00218
00219 if(time != o.time){
00220 return false;
00221 }
00222
00223 if(o.count == 0)
00224 return true;
00225
00226 const_iterator itO = o.begin();
00227 const_iterator it = begin();
00228
00229 while (it != end())
00230 {
00231 if (itO->first < it->first) {
00232 break;
00233 } else if (it->first < itO->first)
00234 ++it;
00235 else {
00236
00237 if(it->second != itO->second){
00238 break;
00239 }
00240 ++it;
00241 ++itO;
00242 }
00243 if (itO == o.end()) return true;
00244 }
00245
00246 return false;
00247 }
00248
00249 bool Argument::isClose(const Argument& o, double epsilon) const{
00250 if(count != o.count)
00251 return false;
00252
00253 if(fabs(time - o.time) > epsilon)
00254 return false;
00255
00256 const_iterator itO = o.begin();
00257 for(const_iterator it = begin();
00258 it != end(); it++) {
00259
00260 if(!(it->first == itO->first) || (fabs(it->second - itO->second) > epsilon)){
00261 return false;
00262 }
00263 itO++;
00264 }
00265
00266 return true;
00267 }
00268
00269 bool Argument::operator==(const Argument & o) const
00270 {
00271 if(count != o.count)
00272 return false;
00273
00274 if(time != o.time)
00275 return false;
00276
00277 const_iterator itO = o.begin();
00278 for(const_iterator it = begin();
00279 it != end(); it++) {
00280
00281 if(!(it->first == itO->first) || (it->second != itO->second)){
00282 return false;
00283 }
00284 itO++;
00285 }
00286
00287 return true;
00288 }
00289
00290 void Argument::operator=(const Argument& o){
00291 count = o.count;
00292
00293 memcpy(values, o.values, sizeof(std::pair<Dimension, double>) * count);
00294
00295
00296
00297 time = o.time;
00298
00299 }
00300
00301 bool Argument::operator<(const Argument & o) const
00302 {
00303 assert(getDimensions() == o.getDimensions());
00304
00305 for(int it = (int)o.count - 1; it >= 0; --it){
00306 double diff = values[it].second - o.values[it].second;
00307
00308 if(diff != 0){
00309 return diff < 0.0;
00310 }
00311 }
00312
00313 return (time - o.time) < 0;
00314 }
00315
00316 double Argument::compare(const Argument& o, const DimensionSet& dims) const{
00317 DimensionSet::const_reverse_iterator rIt = dims.rbegin();
00318
00319 int ind = (int)count - 1;
00320 int indO = (int)o.count - 1;
00321
00322
00323 while(rIt != dims.rend()){
00324 const Dimension& dim = *rIt;
00325
00326
00327 if(dim == Dimension::time)
00328 {
00329 return SIMTIME_DBL(time - o.time);
00330 }
00331
00332
00333 while(ind >= 0 && dim < values[ind].first)
00334 --ind;
00335 while(indO >= 0 && dim < o.values[indO].first)
00336 --indO;
00337
00338
00339 if(ind < 0 || indO < 0)
00340 {
00341 return SIMTIME_DBL(time - o.time);
00342 }
00343
00344
00345
00346 if(values[ind].first == dim && o.values[indO].first == dim){
00347 double diff = values[ind].second - o.values[indO].second;
00348
00349
00350 if(diff != 0)
00351 return diff;
00352 }
00353 ++rIt;
00354 }
00355 return 0;
00356 }
00357
00358
00359
00360 SimpleConstMappingIterator::SimpleConstMappingIterator(ConstMapping* mapping,
00361 const std::set<Argument>* keyEntries,
00362 const Argument& start):
00363 mapping(mapping),
00364 dimensions(mapping->getDimensionSet()),
00365 position(dimensions),
00366 keyEntries(keyEntries)
00367 {
00368 assert(keyEntries);
00369
00370
00371
00372 assert(start.getDimensions().isSubSet(dimensions));
00373
00374
00375
00376
00377 position.setArgValues(start, true);
00378
00379 nextEntry = keyEntries->upper_bound(position);
00380 }
00381
00382 SimpleConstMappingIterator::SimpleConstMappingIterator(ConstMapping* mapping,
00383 const std::set<Argument>* keyEntries):
00384 mapping(mapping),
00385 dimensions(mapping->getDimensionSet()),
00386 position(dimensions),
00387 keyEntries(keyEntries)
00388 {
00389 assert(keyEntries);
00390
00391 jumpToBegin();
00392 }
00393
00394 void SimpleConstMapping::createKeyEntries(const Argument& from, const Argument& to, const Argument& step, Argument& pos){
00395
00396
00397 simtime_t fromT = from.getTime();
00398 simtime_t toT = to.getTime();
00399 simtime_t stepT = step.getTime();
00400
00401
00402 for(simtime_t t = fromT; t < toT; t += stepT){
00403
00404 pos.setTime(t);
00405 keyEntries.insert(pos);
00406 }
00407
00408
00409 pos.setTime(toT);
00410 keyEntries.insert(pos);
00411 }
00412
00413 void SimpleConstMapping::createKeyEntries(const Argument& from, const Argument& to, const Argument& step,
00414 DimensionSet::const_iterator curDim, Argument& pos){
00415
00416 Dimension d = *curDim;
00417
00418
00419 --curDim;
00420 bool nextIsTime = (*curDim == Dimension::time);
00421
00422
00423 double fromD = from.getArgValue(d);
00424 double toD = to.getArgValue(d);
00425 double stepD = step.getArgValue(d);
00426
00427
00428 for(double i = fromD; (i - toD) < -0.0001; i += stepD){
00429 pos.setArgValue(d, i);
00430
00431
00432 if(nextIsTime){
00433 createKeyEntries(from, to, step, pos);
00434 } else {
00435 createKeyEntries(from, to, step, curDim, pos);
00436 }
00437 }
00438
00439
00440 pos.setArgValue(d, toD);
00441 if(nextIsTime){
00442 createKeyEntries(from, to, step, pos);
00443 } else {
00444 createKeyEntries(from, to, step, curDim, pos);
00445 }
00446 }
00447
00448 void SimpleConstMapping::initializeArguments(const Argument& min,
00449 const Argument& max,
00450 const Argument& interval) {
00451 keyEntries.clear();
00452 DimensionSet::const_iterator dimIt = dimensions.end();
00453 --dimIt;
00454 Argument pos = min;
00455 if(*dimIt == Dimension::time)
00456 createKeyEntries(min, max, interval, pos);
00457 else
00458 createKeyEntries(min, max, interval, dimIt, pos);
00459 }
00460
00461
00462
00463
00464