00001
00002
00003
00004
00005
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
00239
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
00298
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
00340
00341 assert(limitTime != pos.getTime());
00342
00343
00344 m->setValue(pos, value);
00345
00346
00347 Argument limitPos = pos;
00348 limitPos.setTime(limitTime);
00349
00350
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
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
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 }