MappingUtils.cc

00001 /*
00002  * MappingUtils.cc
00003  *
00004  *  Created on: 26.08.2008
00005  *      Author: Karl Wessel
00006  */
00007 
00008 #include "MappingUtils.h"
00009 
00010 
00011 FilledUpMappingIterator::FilledUpMappingIterator(FilledUpMapping& mapping):
00012   MultiDimMappingIterator<Linear>(mapping) {}
00013 
00014 FilledUpMappingIterator::FilledUpMappingIterator(FilledUpMapping& mapping, const Argument& pos):
00015   MultiDimMappingIterator<Linear>(mapping, pos) {}
00016 
00017 
00018 
00019 MappingUtils::MappingBuffer MappingUtils::mappingBuffer;
00020 
00021 ConstMapping* MappingUtils::createCompatibleMapping(ConstMapping& src, ConstMapping& dst){
00022   typedef FilledUpMapping::KeySet KeySet;
00023   typedef FilledUpMapping::KeyMap KeyMap;
00024   KeyMap keys;
00025 
00026   const DimensionSet& srcDims = src.getDimensionSet();
00027   const DimensionSet& dstDims = dst.getDimensionSet();
00028 
00029   DimensionSet::const_reverse_iterator srcDimIt = srcDims.rbegin();
00030   for (DimensionSet::const_reverse_iterator dstDimIt = dstDims.rbegin();
00031      dstDimIt != dstDims.rend(); ++dstDimIt)
00032   {
00033     while(srcDimIt != srcDims.rend() && *srcDimIt > *dstDimIt)
00034       ++srcDimIt;
00035     if(*srcDimIt != *dstDimIt){
00036       keys.insert(keys.end(),
00037             KeyMap::value_type(*dstDimIt, KeySet()));
00038     }
00039   }
00040 
00041   if(keys.empty())
00042     return &src;
00043 
00044   ConstMappingIterator* dstIt = dst.createConstIterator();
00045 
00046   if(!dstIt->inRange()){
00047     delete dstIt;
00048     return &src;
00049   }
00050 
00051   do{
00052     for (KeyMap::iterator keyDimIt = keys.begin();
00053        keyDimIt != keys.end(); ++keyDimIt)
00054     {
00055       keyDimIt->second.insert(dstIt->getPosition().getArgValue(keyDimIt->first));
00056     }
00057 
00058     if(!dstIt->hasNext())
00059       break;
00060 
00061     dstIt->next();
00062   }while(true);
00063 
00064   delete dstIt;
00065 
00066   ConstMapping* res = setMappingBuffer(new FilledUpMapping(&src, dstDims, &keys));
00067   return res;
00068 }
00069 
00070 bool MappingUtils::iterateToNext(ConstMappingIterator* it1, ConstMappingIterator* it2){
00071   bool it1HasNext = it1->hasNext();
00072   bool it2HasNext = it2->hasNext();
00073 
00074   if(it1HasNext || it2HasNext){
00075     if(it1HasNext && (!it2HasNext || it1->getNextPosition() < it2->getNextPosition())){
00076       it1->next();
00077       it2->iterateTo(it1->getPosition());
00078 
00079     } else {
00080       it2->next();
00081       it1->iterateTo(it2->getPosition());
00082     }
00083 
00084     return true;
00085   } else {
00086     return false;
00087   }
00088 }
00089 
00090 Mapping* MappingUtils::createMapping(const DimensionSet& domain,
00091                   Mapping::InterpolationMethod intpl) {
00092   assert(domain.hasDimension(Dimension::time));
00093 
00094   if(domain.size() == 1){
00095     switch(intpl){
00096     case Mapping::LINEAR:
00097       return new TimeMapping<Linear>(intpl);
00098       break;
00099     case Mapping::NEAREST:
00100       return new TimeMapping<Nearest>(intpl);
00101       break;
00102     case Mapping::STEPS:
00103       return new TimeMapping<NextSmaller>(intpl);
00104       break;
00105     }
00106     return 0;
00107   } else {
00108     switch(intpl){
00109     case Mapping::LINEAR:
00110       return new MultiDimMapping<Linear>(domain, intpl);
00111       break;
00112     case Mapping::NEAREST:
00113       return new MultiDimMapping<Nearest>(domain, intpl);
00114       break;
00115     case Mapping::STEPS:
00116       return new MultiDimMapping<NextSmaller>(domain, intpl);
00117       break;
00118     }
00119     return 0;
00120   }
00121 }
00122 
00123 Mapping* MappingUtils::createMapping(double outOfRangeVal,
00124                 const DimensionSet& domain,
00125                 Mapping::InterpolationMethod intpl) {
00126   assert(domain.hasDimension(Dimension::time));
00127 
00128   if(domain.size() == 1){
00129     switch(intpl){
00130     case Mapping::LINEAR:
00131       return new TimeMapping<Linear>(outOfRangeVal, intpl);
00132       break;
00133     case Mapping::NEAREST:
00134       return new TimeMapping<Nearest>(outOfRangeVal, intpl);
00135       break;
00136     case Mapping::STEPS:
00137       return new TimeMapping<NextSmaller>(outOfRangeVal, intpl);
00138       break;
00139     }
00140     return 0;
00141   } else {
00142     switch(intpl){
00143     case Mapping::LINEAR:
00144       return new MultiDimMapping<Linear>(domain, outOfRangeVal, intpl);
00145       break;
00146     case Mapping::NEAREST:
00147       return new MultiDimMapping<Nearest>(domain, outOfRangeVal, intpl);
00148       break;
00149     case Mapping::STEPS:
00150       return new MultiDimMapping<NextSmaller>(domain, outOfRangeVal, intpl);
00151       break;
00152     }
00153     return 0;
00154   }
00155 }
00156 
00157 Mapping* MappingUtils::multiply(ConstMapping &f1, ConstMapping &f2)
00158 {
00159   return applyElementWiseOperator(f1, f2, std::multiplies<double>());
00160 }
00161 
00162 Mapping* MappingUtils::divide(ConstMapping &f1, ConstMapping &f2)
00163 {
00164   return applyElementWiseOperator(f1, f2, std::divides<double>());
00165 }
00166 
00167 Mapping* MappingUtils::add(ConstMapping &f1, ConstMapping &f2)
00168 {
00169   return applyElementWiseOperator(f1, f2, std::plus<double>());
00170 }
00171 
00172 Mapping* MappingUtils::subtract(ConstMapping &f1, ConstMapping &f2)
00173 {
00174   return applyElementWiseOperator(f1, f2, std::minus<double>());
00175 }
00176 
00177 
00178 
00179 Mapping* MappingUtils::multiply(ConstMapping &f1, ConstMapping &f2, double outOfRangeVal)
00180 {
00181   return applyElementWiseOperator(f1, f2, std::multiplies<double>(), outOfRangeVal, false);
00182 }
00183 
00184 Mapping* MappingUtils::divide(ConstMapping &f1, ConstMapping &f2, double outOfRangeVal)
00185 {
00186   return applyElementWiseOperator(f1, f2, std::divides<double>(), outOfRangeVal, false);
00187 }
00188 
00189 Mapping* MappingUtils::add(ConstMapping &f1, ConstMapping &f2, double outOfRangeVal)
00190 {
00191   return applyElementWiseOperator(f1, f2, std::plus<double>(), outOfRangeVal, false);
00192 }
00193 
00194 Mapping* MappingUtils::subtract(ConstMapping &f1, ConstMapping &f2, double outOfRangeVal)
00195 {
00196   return applyElementWiseOperator(f1, f2, std::minus<double>(), outOfRangeVal, false);
00197 }
00198 
00199 
00200 
00201 Mapping* operator*(ConstMapping& f1, ConstMapping& f2) {
00202   return MappingUtils::multiply(f1, f2);
00203 }
00204 
00205 Mapping* operator/(ConstMapping& f1, ConstMapping& f2) {
00206   return MappingUtils::divide(f1, f2);
00207 }
00208 
00209 Mapping* operator+(ConstMapping& f1, ConstMapping& f2) {
00210   return MappingUtils::add(f1, f2);
00211 }
00212 
00213 Mapping* operator-(ConstMapping& f1, ConstMapping& f2) {
00214   return MappingUtils::subtract(f1, f2);
00215 }
00216 
00217 
00218 double MappingUtils::findMax(ConstMapping& m) {
00219   ConstMappingIterator* it = m.createConstIterator();
00220 
00221   double res = -DBL_MAX;
00222 
00223   while(it->inRange()){
00224     double val = it->getValue();
00225     if(val > res)
00226       res = val;
00227 
00228     if(!it->hasNext())
00229       break;
00230 
00231     it->next();
00232   }
00233   delete it;
00234   return res;
00235 }
00236 
00237 double MappingUtils::findMax(ConstMapping& m, const Argument& min, const Argument& max){
00238   //the passed interval should define a value for every dimension
00239   //of the mapping.
00240   assert(min.getDimensions().isSubSet(m.getDimensionSet()));
00241   assert(max.getDimensions().isSubSet(m.getDimensionSet()));
00242 
00243   ConstMappingIterator* it = m.createConstIterator(min);
00244 
00245   double res = it->getValue();
00246 
00247   while(it->hasNext() && it->getNextPosition().compare(max, m.getDimensionSet()) < 0){
00248     it->next();
00249 
00250     const Argument& next = it->getPosition();
00251     bool inRange = next.getTime() >= min.getTime() && next.getTime() <= max.getTime();
00252     if(inRange) {
00253       for(Argument::const_iterator itA = next.begin(); itA != next.end(); ++itA) {
00254         if(itA->second < min.getArgValue(itA->first) || itA->second > max.getArgValue(itA->first)) {
00255           inRange = false;
00256           break;
00257         }
00258       }
00259     }
00260 
00261     if(inRange) {
00262       double val = it->getValue();
00263       if(val > res)
00264         res = val;
00265     }
00266   }
00267   it->iterateTo(max);
00268   double val = it->getValue();
00269   if(val > res)
00270     res = val;
00271 
00272   delete it;
00273   return res;
00274 }
00275 
00276 double MappingUtils::findMin(ConstMapping& m) {
00277   ConstMappingIterator* it = m.createConstIterator();
00278 
00279   double res = DBL_MAX;
00280 
00281   while(it->inRange()){
00282     double val = it->getValue();
00283     if(val < res)
00284       res = val;
00285 
00286     if(!it->hasNext())
00287       break;
00288 
00289     it->next();
00290   }
00291   delete it;
00292   return res;
00293 }
00294 
00295 double MappingUtils::findMin(ConstMapping& m, const Argument& min, const Argument& max){
00296 
00297   //the passed interval should define a value for every dimension
00298   //of the mapping.
00299   assert(min.getDimensions().isSubSet(m.getDimensionSet()));
00300   assert(max.getDimensions().isSubSet(m.getDimensionSet()));
00301 
00302   ConstMappingIterator* it = m.createConstIterator(min);
00303 
00304   double res = it->getValue();
00305 
00306   while(it->hasNext() && it->getNextPosition().compare(max, m.getDimensionSet()) < 0){
00307     it->next();
00308 
00309     const Argument& next = it->getPosition();
00310     bool inRange = next.getTime() >= min.getTime() && next.getTime() <= max.getTime();
00311     if(inRange) {
00312       for(Argument::const_iterator itA = next.begin(); itA != next.end(); ++itA) {
00313         if(itA->second < min.getArgValue(itA->first) || itA->second > max.getArgValue(itA->first)) {
00314           inRange = false;
00315           break;
00316         }
00317       }
00318     }
00319 
00320     if(inRange) {
00321       double val = it->getValue();
00322       if(val < res)
00323         res = val;
00324     }
00325   }
00326   it->iterateTo(max);
00327   double val = it->getValue();
00328   if(val < res)
00329     res = val;
00330   delete it;
00331   return res;
00332 }
00333 
00334 
00335 void MappingUtils::addDiscontinuity(Mapping* m,
00336                   const Argument& pos, double value,
00337                   simtime_t limitTime, double limitValue)
00338 {
00339   // asserts/preconditions
00340   // make sure the time really differs at the discontinuity
00341   assert(limitTime != pos.getTime());
00342 
00343   // add (pos, value) to mapping
00344   m->setValue(pos, value);
00345 
00346   // create Argument limitPos for the limit-position, i.e. copy pos and set limitTime as its time
00347   Argument limitPos = pos;
00348   limitPos.setTime(limitTime);
00349 
00350   // add (limitPos, limitValue) to mapping
00351   m->setValue(limitPos, limitValue);
00352 }
00353 
00354 simtime_t MappingUtils::pre(simtime_t t)
00355 {
00356   t.setRaw(t.raw() - 1);
00357 
00358   return t;
00359 }
00360 
00361 simtime_t MappingUtils::post(simtime_t t)
00362 {
00363   assert(t.raw() < simtime_t::getMaxTime().raw());
00364 
00365   t.setRaw(t.raw() + 1);
00366 
00367   return t;
00368 }
00369 
00370 
00371 /*
00372 Mapping* Mapping::multiply(ConstMapping &f1, ConstMapping &f2, const Argument& from, const Argument& to)
00373 {
00374   return applyElementWiseOperator(f1, f2, std::multiplies<double>());
00375 }
00376 
00377 Mapping* Mapping::divide(ConstMapping &f1, ConstMapping &f2, const Argument& from, const Argument& to)
00378 {
00379   return applyElementWiseOperator(f1, f2, std::divides<double>());
00380 }
00381 
00382 Mapping* Mapping::add(ConstMapping &f1, ConstMapping &f2, const Argument& from, const Argument& to)
00383 {
00384   return applyElementWiseOperator(f1, f2, std::plus<double>());
00385 }
00386 
00387 Mapping* Mapping::subtract(ConstMapping &f1, ConstMapping &f2, const Argument& from, const Argument& to)
00388 {
00389   return applyElementWiseOperator(f1, f2, std::minus<double>());
00390 }
00391 */
00392 
00393 
00394 LinearIntplMappingIterator::LinearIntplMappingIterator(ConstMappingIterator* leftIt, ConstMappingIterator* rightIt, double f):
00395   leftIt(leftIt), rightIt(rightIt), factor(f) {
00396 
00397   assert(leftIt->getPosition() == rightIt->getPosition());
00398 }
00399 
00400 LinearIntplMappingIterator::~LinearIntplMappingIterator() {
00401   if(leftIt)
00402     delete leftIt;
00403   if(rightIt)
00404     delete rightIt;
00405 }