MappingUtils.h

00001 /*
00002  * SignalInterfaces.h
00003  *
00004  *  Created on: 26.08.2008
00005  *      Author: karl wessel
00006  */
00007 
00008 #ifndef SIGNALINTERFACES_H_
00009 #define SIGNALINTERFACES_H_
00010 
00011 #include "MappingBase.h"
00012 
00013 class FilledUpMapping;
00014 
00028 template<class Base>
00029 class BaseFilteredIterator : public Base{
00030 protected:
00031   Base* origIterator;
00032 
00033 public:
00034   BaseFilteredIterator(Base* orig):
00035     origIterator(orig) {}
00036 
00037   virtual ~BaseFilteredIterator() {
00038     delete origIterator;
00039   }
00040 
00041   virtual const Argument& getNextPosition() const { return origIterator->getNextPosition(); }
00042 
00043   virtual void jumpTo(const Argument& pos) { origIterator->jumpTo(pos); }
00044 
00045   virtual void jumpToBegin() { origIterator->jumpToBegin(); }
00046 
00047   virtual void iterateTo(const Argument& pos) { origIterator->iterateTo(pos); }
00048 
00049   virtual void next() { origIterator->next(); }
00050 
00051   virtual bool inRange() const { return origIterator->inRange(); }
00052 
00053   virtual bool hasNext() const { return origIterator->hasNext(); }
00054 
00055   virtual const Argument& getPosition() const { return origIterator->getPosition(); }
00056 
00057   virtual double getValue() const { return origIterator->getValue(); }
00058 };
00059 
00068 typedef BaseFilteredIterator<ConstMappingIterator> FilteredConstMappingIterator;
00069 
00078 class FilteredMappingIterator : public BaseFilteredIterator<MappingIterator> {
00079 public:
00080   FilteredMappingIterator(MappingIterator* orig):
00081     BaseFilteredIterator<MappingIterator>(orig) {}
00082 
00083   virtual ~FilteredMappingIterator() {}
00084 
00085   virtual void setValue(double value) { origIterator->setValue(value); }
00086 };
00087 
00088 
00096 template<template <class Key, class Value, class Pair, class Iterator> class Interpolator>
00097 class TimeMappingIterator:public MappingIterator {
00098 protected:
00100   typedef std::map<simtime_t, double> MapType;
00101 
00103   typedef typename InterpolateableMap<simtime_t, double,
00104                  Interpolator<simtime_t, double,
00105                       MapType::value_type,
00106                       MapType::const_iterator> >::intpl_iterator IteratorType;
00107 
00109   IteratorType valueIt;
00110 
00112   Argument position;
00113 
00115   Argument nextPosition;
00116 
00117   bool isStepMapping;
00118 
00119   bool atPreStep;
00120 protected:
00121   void updateNextPos(){
00122     simtime_t t = valueIt.getNextPosition();
00123     if(isStepMapping && !atPreStep){
00124       t.setRaw(t.raw() - 1);
00125     }
00126     nextPosition.setTime(t);
00127   }
00128 public:
00129 
00133   TimeMappingIterator(IteratorType it, bool isStepMapping):
00134     valueIt(it), isStepMapping(isStepMapping), atPreStep(false) {
00135 
00136     position.setTime(valueIt.getPosition());
00137     updateNextPos();
00138   }
00139 
00147   void jumpTo(const Argument& pos) {
00148     atPreStep = false;
00149     valueIt.jumpTo(pos.getTime());
00150     position.setTime(pos.getTime());
00151     nextPosition.setTime(valueIt.getNextPosition());
00152   }
00153 
00165   void iterateTo(const Argument& pos) {
00166     atPreStep = false;
00167     valueIt.iterateTo(pos.getTime());
00168     position.setTime(pos.getTime());
00169     nextPosition.setTime(valueIt.getNextPosition());
00170   }
00171 
00180   virtual void next() {
00181     if(isStepMapping && !atPreStep){
00182       valueIt.iterateTo(nextPosition.getTime());
00183       atPreStep = true;
00184     } else {
00185       valueIt.next();
00186       atPreStep = false;
00187     }
00188     position.setTime(valueIt.getPosition());
00189     updateNextPos();
00190   }
00191 
00201   virtual bool inRange() const {
00202     return valueIt.inRange();
00203   }
00204 
00210   virtual const Argument& getPosition() const {
00211     return position;
00212   }
00213 
00219   virtual const Argument& getNextPosition() const {
00220     return nextPosition;
00221   }
00222 
00229   virtual double getValue() const {
00230     return *valueIt.getValue();
00231   }
00232 
00241   virtual void jumpToBegin() {
00242     valueIt.jumpToBegin();
00243     position.setTime(valueIt.getPosition());
00244   }
00245 
00252     virtual bool hasNext() const {
00253       return valueIt.hasNext();
00254     }
00255 
00262   virtual void setValue(double value) {
00263     valueIt.setValue(value);
00264   }
00265 };
00266 
00275 template<template <class Key, class Value, class Pair, class Iterator> class Interpolator>
00276 class TimeMapping:public Mapping {
00277 protected:
00279   typedef std::map<simtime_t, double> MapType;
00280 
00282   typedef InterpolateableMap<simtime_t, double,
00283                  Interpolator<simtime_t, double,
00284                       MapType::value_type,
00285                       MapType::const_iterator> > ValueMap;
00286 
00288   ValueMap entries;
00289 
00298   bool isStepMapping;
00299 public:
00300 
00304   TimeMapping(InterpolationMethod intpl = LINEAR):
00305     Mapping(), entries(), isStepMapping(intpl == STEPS) {}
00306 
00310   TimeMapping(double outOfRangeVal, InterpolationMethod intpl = LINEAR):
00311     Mapping(), entries(outOfRangeVal), isStepMapping(intpl == STEPS) {}
00312 
00316   virtual Mapping* clone() const { return new TimeMapping<Interpolator>(*this); }
00317 
00324   virtual double getValue(const Argument& pos) const {
00325     return *entries.getIntplValue(pos.getTime());
00326   }
00327 
00334   virtual void setValue(const Argument& pos, double value) {
00335     entries[pos.getTime()] = value;
00336   }
00337 
00345   virtual MappingIterator* createIterator() {
00346     return new TimeMappingIterator<Interpolator>(entries.beginIntpl(), isStepMapping);
00347   }
00348 
00356   virtual MappingIterator* createIterator(const Argument& pos) {
00357     return new TimeMappingIterator<Interpolator>(entries.findIntpl(pos.getTime()), isStepMapping);
00358   }
00359 };
00360 
00361 
00370 class LinearIntplMappingIterator:public MappingIterator {
00371 protected:
00373   ConstMappingIterator* leftIt;
00375   ConstMappingIterator* rightIt;
00376 
00379   double factor;
00380 
00381 public:
00386   LinearIntplMappingIterator(ConstMappingIterator* leftIt, ConstMappingIterator* rightIt, double f);
00387 
00391   virtual ~LinearIntplMappingIterator();
00392 
00398   virtual bool hasNext() const { return false; }
00404   virtual bool inRange() const { return false; }
00405 
00409   virtual void jumpToBegin() { assert(false); }
00413   virtual void next() { assert(false); }
00414 
00418   virtual void setValue(double value) { assert(false); }
00419 
00426   virtual void jumpTo(const Argument& pos){
00427     leftIt->jumpTo(pos);
00428     rightIt->jumpTo(pos);
00429   }
00430 
00442   virtual void iterateTo(const Argument& pos){
00443     leftIt->iterateTo(pos);
00444     rightIt->iterateTo(pos);
00445   }
00446 
00453   virtual double getValue() const {
00454     double v0 = leftIt->getValue();
00455     double v1 = rightIt->getValue();
00456     return v0 + (v1 - v0) * factor;
00457   }
00458 
00464   virtual const Argument& getPosition() const {
00465     return leftIt->getPosition();
00466   }
00467 
00471   virtual const Argument& getNextPosition() const { assert(false); }
00472 };
00473 
00481 class LinearIntplMapping:public Mapping {
00482 protected:
00484   ConstMapping* left;
00486   ConstMapping* right;
00487 
00490   double factor;
00491 
00492 public:
00493 
00498   LinearIntplMapping(ConstMapping* left = 0, ConstMapping* right = 0, double f = 0.0):
00499     left(left), right(right), factor(f) {}
00500 
00504   virtual Mapping* clone() const{ assert(false); return 0; }
00505 
00513   virtual double getValue(const Argument& pos) const {
00514     assert(left);
00515     assert(right);
00516 
00517     double v0 = left->getValue(pos);
00518     double v1 = right->getValue(pos);
00519     return v0 + (v1 - v0) * factor;
00520   }
00521 
00526   virtual MappingIterator* createIterator() {
00527     assert(false);
00528     return 0;
00529   }
00530 
00539   virtual MappingIterator* createIterator(const Argument& pos) {
00540     assert(left);
00541     assert(right);
00542 
00543     return new LinearIntplMappingIterator(left->createConstIterator(pos), right->createConstIterator(pos), factor);
00544   }
00545 
00549   virtual void setValue(const Argument& pos, double value) { assert(false); }
00550 };
00551 
00563 template<>
00564 class Interpolated<Mapping*> {
00565 protected:
00567   LinearIntplMapping mapping;
00568 
00570   Mapping* value;
00571 
00573   bool isPointer;
00574 public:
00576   bool isInterpolated;
00577 
00578 public:
00584   Interpolated(const LinearIntplMapping& m):
00585     mapping(m), isPointer(false), isInterpolated(true) {
00586 
00587     value = &mapping;
00588   }
00589 
00596   Interpolated(Mapping* m, bool isIntpl = true):
00597     mapping(), value(m), isPointer(true), isInterpolated(isIntpl) {}
00598 
00602   Interpolated(const Interpolated<Mapping*>& o):
00603     mapping() {
00604 
00605     isInterpolated = o.isInterpolated;
00606     isPointer = o.isPointer;
00607     if(isPointer){
00608       value = o.value;
00609     } else {
00610       mapping = o.mapping;
00611       value = &mapping;
00612     }
00613   }
00614 
00619   const Interpolated<Mapping*>& operator=(const Interpolated<Mapping*>& o){
00620     isInterpolated = o.isInterpolated;
00621     isPointer = o.isPointer;
00622     if(isPointer){
00623       value = o.value;
00624     } else {
00625       mapping = o.mapping;
00626       value = &mapping;
00627     }
00628     return *this;
00629   }
00630 
00635   Mapping*& operator*() {
00636     return value;
00637   }
00638 
00643   Mapping** operator->() {
00644     return &value;
00645   }
00646 
00652   bool operator==(const Interpolated<Mapping*>& other) {
00653     return value == other.value && isInterpolated == other.isInterpolated;
00654   }
00655 
00661   bool operator!=(const Interpolated<Mapping*>& other) {
00662     return value != other.value || isInterpolated != other.isInterpolated;
00663   }
00664 };
00665 
00673 template<>
00674 class Linear<double, Mapping*, std::map<double, Mapping*>::value_type, std::map<double, Mapping*>::const_iterator> {
00675 public:
00677   typedef std::map<double, Mapping*>::const_iterator InputIterator;
00678 
00680   typedef Interpolated<Mapping*> interpolated;
00681 protected:
00682 
00684   PairLess<std::map<double, Mapping*>::value_type, double> comp;
00685 
00686 
00687   bool continueOutOfRange;
00688   Mapping* outOfRangeVal;
00689 
00690 public:
00691   Linear():
00692     continueOutOfRange(true) {}
00693 
00694   Linear(Mapping* oorv):
00695     continueOutOfRange(false), outOfRangeVal(oorv) {}
00696 
00697   void setOutOfRangeVal(Mapping* oorv) { outOfRangeVal = oorv; }
00698 
00703   static double linearInterpolationFactor(const double& t,
00704                     const double& t0, const double& t1){
00705     return (t - t0) / (t1 - t0);
00706   }
00707 
00719   interpolated operator()(const InputIterator& first,
00720               const InputIterator& last,
00721               const double& pos) const{
00722 
00723     InputIterator right = std::upper_bound(first, last, pos, comp);
00724 
00725     return operator()(first, last, pos, right);
00726   }
00727 
00742   interpolated operator()(const InputIterator& first,
00743               const InputIterator& last,
00744               const double& pos,
00745               InputIterator upperBound) const{
00746     if(first == last){
00747       if(continueOutOfRange)
00748         return interpolated(0);
00749       else
00750         return interpolated(outOfRangeVal);
00751     }
00752 
00753     if(upperBound == first){
00754       if(continueOutOfRange)
00755         return interpolated(upperBound->second);
00756       else
00757         return interpolated(outOfRangeVal);
00758     }
00759 
00760     InputIterator right = upperBound;
00761     InputIterator left = --upperBound;
00762 
00763     if(left->first == pos)
00764       return interpolated(left->second, false);
00765 
00766     if(right == last){
00767       if(continueOutOfRange)
00768         return interpolated(left->second);
00769       else
00770         return interpolated(outOfRangeVal);
00771     }
00772 
00773     double fact = linearInterpolationFactor(pos, left->first, right->first);
00774 
00775     return interpolated(LinearIntplMapping(left->second, right->second, fact));
00776   }
00777 };
00778 
00787 class ConstantSimpleConstMapping : public SimpleConstMapping {
00788 protected:
00789   double value;
00790 
00791 public:
00792   ConstantSimpleConstMapping(const DimensionSet& dims, double val):
00793     SimpleConstMapping(dims), value(val) {}
00794 
00795   ConstantSimpleConstMapping(const DimensionSet& dims,
00796                  const Argument& key,
00797                  double val):
00798     SimpleConstMapping(dims, key), value(val) {}
00799 
00800   virtual double getValue(const Argument& pos) const {
00801     return value;
00802   }
00803 
00807   double getValue() const {
00808     return value;
00809   }
00810 
00814   void setValue(double val) { value = val; }
00815 
00816   ConstMapping* constClone() const  {
00817     return new ConstantSimpleConstMapping(dimensions, value);
00818   }
00819 };
00820 
00831 class ConstMappingIteratorWrapper : public MappingIterator {
00832 protected:
00833   ConstMappingIterator* iterator;
00834 public:
00835   ConstMappingIteratorWrapper(ConstMappingIterator* it):
00836     iterator(it) {}
00837 
00838   virtual ~ConstMappingIteratorWrapper() {
00839     if(iterator)
00840       delete iterator;
00841   }
00842 
00843   virtual void setValue(double value) { assert(false); }
00844 
00845   virtual const Argument& getNextPosition() const { return iterator->getNextPosition(); }
00846 
00847   virtual void jumpTo(const Argument& pos) { iterator->jumpTo(pos); }
00848 
00849   virtual void jumpToBegin() { iterator->jumpToBegin(); }
00850 
00851   virtual void iterateTo(const Argument& pos) { iterator->iterateTo(pos); }
00852 
00853   virtual void next() { iterator->next(); }
00854 
00855   virtual bool inRange() const { return iterator->inRange(); }
00856 
00857   virtual bool hasNext() const { return iterator->hasNext(); }
00858 
00859   virtual const Argument& getPosition() const { return iterator->getPosition(); }
00860 
00861   virtual double getValue() const { return iterator->getValue(); }
00862 };
00863 
00873 class ConstMappingWrapper : public Mapping {
00874 protected:
00875   ConstMapping* mapping;
00876 
00877 public:
00878   ConstMappingWrapper(ConstMapping* m):
00879     Mapping(m->getDimensionSet()), mapping(m) {}
00880 
00881   virtual void setValue(const Argument& pos, double value) { assert(false); }
00882 
00883   virtual MappingIterator* createIterator() {
00884     return new ConstMappingIteratorWrapper(mapping->createConstIterator());
00885   }
00886 
00887   virtual MappingIterator* createIterator(const Argument& pos) {
00888     return new ConstMappingIteratorWrapper(mapping->createConstIterator(pos));
00889   }
00890 
00891   virtual double getValue(const Argument& pos) const { return mapping->getValue(pos); }
00892 
00893   virtual ConstMappingIterator* createConstIterator() {
00894     return mapping->createConstIterator();
00895   }
00896 
00897   virtual ConstMappingIterator* createConstIterator(const Argument& pos) {
00898     return mapping->createConstIterator(pos);
00899   }
00900 
00901   virtual ConstMapping* constClone() const { return mapping->constClone(); }
00902 
00903   virtual Mapping* clone() const {
00904     return new ConstMappingWrapper(mapping->constClone());
00905   }
00906 };
00907 
00908 template<template <class Key, class Value,
00909           class Pair,
00910           class iterator> class Interpolator>
00911 class MultiDimMapping;
00912 
00932 template<template <class Key, class Value,
00933           class Pair,
00934           class iterator> class Interpolator>
00935 class MultiDimMappingIterator:public MappingIterator {
00936 protected:
00938   typedef InterpolateableMap<double, Mapping*,
00939                  Interpolator<double, Mapping*,
00940                         std::map<double, Mapping*>::value_type,
00941                         std::map<double, Mapping*>::const_iterator> > MapType;
00943   typedef typename MapType::intpl_iterator IteratorType;
00944 
00946   MultiDimMapping<Interpolator>& mapping;
00947 
00950   IteratorType valueIt;
00951 
00953   typename MapType::interpolated subMapping;
00954 
00957   MappingIterator* subIterator;
00958 
00960   Argument position;
00961 
00963   Argument nextPosition;
00964 
00965 protected:
00966 
00974   void updateSubIterator(const Argument& pos) {
00975     typename MapType::interpolated subM = valueIt.getValue();
00976     if(subM != subMapping) {
00977       if(subIterator)
00978         delete subIterator;
00979 
00980       subMapping = subM;
00981       if(*subMapping)
00982         subIterator = (*subMapping)->createIterator(pos);
00983       else
00984         subIterator = 0;
00985     } else {
00986       if(subIterator)
00987         subIterator->jumpTo(pos);
00988     }
00989   }
00990 
00998   void updateSubIterator() {
00999     typename MapType::interpolated subM = valueIt.getValue();
01000     if(subM != subMapping) {
01001       if(subIterator)
01002         delete subIterator;
01003 
01004       subMapping = subM;
01005       if(*subMapping){
01006         if(subMapping.isInterpolated)
01007           subIterator = (*subMapping)->createIterator(position);
01008         else
01009           subIterator = (*subMapping)->createIterator();
01010       }else
01011         subIterator = 0;
01012     } else {
01013       if(subIterator)
01014         subIterator->jumpToBegin();
01015     }
01016   }
01017 
01023   void updateNextPosition(){
01024     bool intp = subMapping.isInterpolated;
01025 
01026     bool noSubIt = false;
01027     bool hasNoNext = false;
01028     if(!intp){
01029       noSubIt = !subIterator;
01030       if(!noSubIt)
01031         hasNoNext = !subIterator->hasNext();
01032     }
01033     if(intp || noSubIt || hasNoNext){
01034       if(valueIt.hasNext()){
01035         ConstMappingIterator* tmp = (*valueIt.getNextValue())->createConstIterator();
01036         nextPosition.setArgValues(tmp->getPosition());
01037         delete tmp;
01038       }else{
01039         nextPosition = position;
01040       }
01041       nextPosition.setArgValue(mapping.myDimension, valueIt.getNextPosition());
01042 
01043     } else {
01044       nextPosition.setArgValues(subIterator->getNextPosition());
01045     }
01046   }
01047 
01048 public:
01053   MultiDimMappingIterator(MultiDimMapping<Interpolator>& mapping):
01054     mapping(mapping),
01055     valueIt(mapping.entries.beginIntpl()),
01056     subMapping(0), subIterator(0),
01057     position(){
01058 
01059     subMapping = valueIt.getValue();
01060     if(!subMapping.isInterpolated && *subMapping) {
01061       subIterator = (*subMapping)->createIterator();
01062       position = subIterator->getPosition();
01063       position.setArgValue(mapping.myDimension, valueIt.getPosition());
01064     } else {
01065       position = Argument(mapping.dimensions);
01066     }
01067     nextPosition = position;
01068 
01069     updateNextPosition();
01070   }
01071 
01076   MultiDimMappingIterator(MultiDimMapping<Interpolator>& mapping, const Argument& pos):
01077     mapping(mapping),
01078     valueIt(mapping.entries.findIntpl(pos.getArgValue(mapping.myDimension))),
01079     subMapping(0), subIterator(0),
01080     position(){
01081 
01082     subMapping = valueIt.getValue();
01083     if(*subMapping){
01084       subIterator = (*subMapping)->createIterator(pos);
01085     }
01086 
01087     position = pos;
01088     nextPosition = position;
01089     updateNextPosition();
01090 
01091   }
01092 
01096   virtual ~MultiDimMappingIterator() {
01097     if(subIterator)
01098       delete subIterator;
01099   }
01100 
01109     void jumpTo(const Argument& pos){
01110     double argVal = pos.getArgValue(mapping.myDimension);
01111 
01112     if(argVal != valueIt.getPosition() && pos.hasArgVal(mapping.myDimension)) {
01113       valueIt.jumpTo(argVal);
01114       updateSubIterator(pos);
01115     } else {
01116       if(subIterator)
01117         subIterator->jumpTo(pos);
01118     }
01119 
01120     position.setArgValues(pos);
01121     nextPosition.setArgValues(position);
01122     updateNextPosition();
01123   }
01124 
01135   void iterateTo(const Argument& pos){
01136     double argVal = pos.getArgValue(mapping.myDimension);
01137 
01138     if(argVal != valueIt.getPosition() && pos.hasArgVal(mapping.myDimension)) {
01139       valueIt.iterateTo(argVal);
01140       updateSubIterator(pos);
01141     } else {
01142       if(subIterator)
01143         subIterator->iterateTo(pos);
01144     }
01145 
01146     position.setArgValues(pos);
01147     updateNextPosition();
01148   }
01149 
01162   virtual void next(){
01163     if(!subMapping.isInterpolated && subIterator && subIterator->hasNext()) {
01164       subIterator->next();
01165     } else {
01166       valueIt.next();
01167       updateSubIterator();
01168     }
01169 
01170 
01171     if(subIterator)
01172       position.setArgValues(subIterator->getPosition());
01173 
01174     position.setArgValue(mapping.myDimension, valueIt.getPosition());
01175 
01176     updateNextPosition();
01177   }
01178 
01188   virtual bool inRange() const {
01189     return valueIt.inRange() && (subMapping.isInterpolated || (subIterator && subIterator->inRange()));
01190   }
01191 
01197   virtual const Argument& getPosition() const {
01198     return position;
01199   }
01200 
01206   virtual const Argument& getNextPosition() const {
01207     return nextPosition;
01208   }
01209 
01216   virtual double getValue() const {
01217     if(subIterator)
01218       return subIterator->getValue();
01219     else
01220       return 0.0;
01221   }
01222 
01231   virtual void jumpToBegin(){
01232     valueIt.jumpToBegin();
01233     updateSubIterator();
01234     if(subIterator)
01235       position.setArgValues(subIterator->getPosition());
01236 
01237     position.setArgValue(mapping.myDimension, valueIt.getPosition());
01238     updateNextPosition();
01239   }
01240 
01247     virtual bool hasNext() const {
01248       return valueIt.hasNext() or (subIterator and subIterator->hasNext() and valueIt.inRange());
01249     }
01250 
01257   virtual void setValue(double value){
01258     if(subMapping.isInterpolated) {
01259       valueIt.setValue(mapping.createSubSignal());
01260       updateSubIterator(position);
01261     }
01262     subIterator->setValue(value);
01263   }
01264 };
01265 
01266 
01267 
01283 template<template <class Key, class Value,
01284           class Pair,
01285           class iterator> class Interpolator>
01286 class MultiDimMapping:public Mapping {
01287 protected:
01289   typedef InterpolateableMap<double, Mapping*,
01290                  Interpolator<double, Mapping*,
01291                         std::map<double, Mapping*>::value_type,
01292                         std::map<double, Mapping*>::const_iterator> > SubFunctionMap;
01293 
01298   ConstantSimpleConstMapping* outOfRangeMapping;
01299 
01304   ConstMappingWrapper* wrappedOORMapping;
01305 
01307   SubFunctionMap entries;
01308 
01310   Dimension myDimension;
01311 
01312   friend class MultiDimMappingIterator<Interpolator>;
01313 
01314   bool isMaster;
01315 
01316 protected:
01325   MultiDimMapping(const DimensionSet& myDims, Dimension myDim, InterpolationMethod intpl = STEPS):
01326       Mapping(myDims),
01327       outOfRangeMapping(0),
01328       wrappedOORMapping(0),
01329       entries(),
01330       myDimension(myDim),
01331       isMaster(false) {}
01332 
01341   MultiDimMapping(const DimensionSet& myDims, Dimension myDim,
01342           ConstantSimpleConstMapping* oorm,
01343           ConstMappingWrapper* wrappedoorm,
01344           InterpolationMethod intpl = STEPS):
01345       Mapping(myDims),
01346       outOfRangeMapping(oorm),
01347       wrappedOORMapping(wrappedoorm),
01348       entries(wrappedOORMapping),
01349       myDimension(myDim),
01350       isMaster(false) {}
01351 
01356   MultiDimMapping(const MultiDimMapping<Interpolator>& o,
01357           ConstantSimpleConstMapping* oorm,
01358           ConstMappingWrapper* wrappedoorm):
01359     Mapping(o),
01360     outOfRangeMapping(oorm),
01361     wrappedOORMapping(wrappedoorm),
01362     entries(o.entries),
01363     myDimension(o.myDimension),
01364     isMaster(false){
01365 
01366     entries.setOutOfRangeVal(wrappedOORMapping);
01367 
01368     copySubMappings(o);
01369   }
01370 
01375   Mapping* createSubSignal() const{
01376     DimensionSet::const_iterator it = dimensions.find(myDimension);
01377     Dimension nextDim = *(--it);
01378     if(wrappedOORMapping == 0) {
01379       if(nextDim == Dimension::time)
01380         return new TimeMapping<Interpolator>();
01381       else
01382         return new MultiDimMapping<Interpolator>(dimensions, nextDim, LINEAR);
01383     } else {
01384       if(nextDim == Dimension::time)
01385         return new TimeMapping<Interpolator>(outOfRangeMapping->getValue());
01386       else
01387         return new MultiDimMapping<Interpolator>(dimensions, nextDim,
01388                        outOfRangeMapping,
01389                        wrappedOORMapping, LINEAR);
01390     }
01391   }
01392 
01393   void copySubMappings(const MultiDimMapping& o){
01394     DimensionSet::const_iterator dimIt = dimensions.find(myDimension);
01395     Dimension nextDim = *(--dimIt);
01396 
01397     if(nextDim == Dimension::time_static())
01398     {
01399       for(typename SubFunctionMap::iterator it = entries.begin();
01400         it != entries.end(); it++)
01401       {
01402         it->second = new TimeMapping<Interpolator>(*(static_cast<TimeMapping<Interpolator>*>(it->second)));
01403       }
01404     } else
01405     {
01406       for(typename SubFunctionMap::iterator it = entries.begin();
01407         it != entries.end(); it++)
01408       {
01409         if(outOfRangeMapping == 0) {
01410           it->second = new MultiDimMapping<Interpolator>(*(static_cast<MultiDimMapping<Interpolator>*>(it->second)));
01411         } else {
01412           it->second = new MultiDimMapping<Interpolator>(*(static_cast<MultiDimMapping<Interpolator>*>(it->second)),
01413                            outOfRangeMapping,
01414                            wrappedOORMapping);
01415         }
01416       }
01417     }
01418   }
01419 
01420 public:
01426   MultiDimMapping(const DimensionSet& myDims, InterpolationMethod intpl = STEPS):
01427     Mapping(myDims),
01428     outOfRangeMapping(0),
01429     wrappedOORMapping(0),
01430     entries(),
01431     isMaster(true){
01432 
01433     myDimension = *(dimensions.rbegin());
01434   }
01435 
01441   MultiDimMapping(const DimensionSet& myDims, double oorv, InterpolationMethod intpl = STEPS):
01442     Mapping(myDims),
01443     outOfRangeMapping(new ConstantSimpleConstMapping(myDims, oorv)),
01444     wrappedOORMapping(new ConstMappingWrapper(outOfRangeMapping)),
01445     entries(wrappedOORMapping),
01446     isMaster(true) {
01447 
01448     myDimension = *(dimensions.rbegin());
01449   }
01450 
01455   MultiDimMapping(const MultiDimMapping<Interpolator>& o):
01456     Mapping(o),
01457     outOfRangeMapping(o.outOfRangeMapping),
01458     wrappedOORMapping(o.wrappedOORMapping),
01459     entries(o.entries),
01460     myDimension(o.myDimension),
01461     isMaster(true){
01462 
01463     if(outOfRangeMapping != 0){
01464       outOfRangeMapping = new ConstantSimpleConstMapping(dimensions, o.outOfRangeMapping->getValue());
01465       wrappedOORMapping = new ConstMappingWrapper(outOfRangeMapping);
01466       entries.setOutOfRangeVal(wrappedOORMapping);
01467     }
01468 
01469 
01470     copySubMappings(o);
01471   }
01472 
01477   const MultiDimMapping& operator=(const MultiDimMapping<Interpolator>& o){
01478     for(typename SubFunctionMap::iterator it = entries.begin();
01479       it != entries.end(); it++) {
01480 
01481       if(it->second)
01482         delete it->second;
01483     }
01484 
01485     dimensions = o.dimensions;
01486     entries = o.entries;
01487     myDimension = o.myDimension;
01488     outOfRangeMapping = o.outOfRangeMapping;
01489     wrappedOORMapping = o.wrappedOORMapping;
01490     isMaster = true;
01491 
01492     if(outOfRangeMapping != 0){
01493       outOfRangeMapping = new ConstantSimpleConstMapping(dimensions, o.outOfRangeMapping->getValue());
01494       wrappedOORMapping = new ConstMappingWrapper(outOfRangeMapping);
01495       entries.setOutOfRangeVal(wrappedOORMapping);
01496     }
01497 
01498     copySubMappings(o);
01499 
01500     return *this;
01501   }
01502 
01506   virtual Mapping* clone() const { return new MultiDimMapping<Interpolator>(*this); }
01507 
01511   virtual ~MultiDimMapping() {
01512       for(typename SubFunctionMap::iterator it = entries.begin();
01513         it != entries.end(); it++) {
01514 
01515         if(it->second)
01516           delete it->second;
01517       }
01518 
01519       if(isMaster) {
01520         if(outOfRangeMapping)
01521           delete outOfRangeMapping;
01522         if(wrappedOORMapping)
01523           delete wrappedOORMapping;
01524       }
01525     }
01526 
01534   virtual double getValue(const Argument& pos) const {
01535     assert(pos.hasArgVal(myDimension));
01536     double argVal = pos.getArgValue(myDimension);
01537 
01538     Interpolated<Mapping*> subM = entries.getIntplValue(argVal);
01539 
01540     if(!(*subM))
01541       return double();
01542 
01543     return (*subM)->getValue(pos);
01544   }
01545 
01553   virtual void setValue(const Argument& pos, double value) {
01554     double argVal = pos.getArgValue(myDimension);
01555 
01556       typename SubFunctionMap::iterator posIt = entries.lower_bound(argVal);
01557 
01558     if(posIt == entries.end() || posIt->first != argVal) {
01559       Mapping* subF = createSubSignal();
01560         posIt = entries.insert(posIt, typename SubFunctionMap::value_type(argVal, subF));
01561       }
01562 
01563       posIt->second->setValue(pos, value);
01564   }
01565 
01573   virtual MappingIterator* createIterator() {
01574     return new MultiDimMappingIterator<Interpolator>(*this);
01575   }
01576 
01584   virtual MappingIterator* createIterator(const Argument& pos) {
01585     return new MultiDimMappingIterator<Interpolator>(*this, pos);
01586   }
01587 
01588 
01592   Dimension getDimension() { return myDimension; }
01593 };
01594 
01595 
01596 
01597 
01598 
01609 class FilledUpMappingIterator : public MultiDimMappingIterator<Linear>{
01610 public:
01611   FilledUpMappingIterator(FilledUpMapping& mapping);
01612 
01613   FilledUpMappingIterator(FilledUpMapping& mapping, const Argument& pos);
01614 
01615   virtual void setValue(double value) {
01616     assert(false);
01617   }
01618 };
01619 
01633 class FilledUpMapping : public MultiDimMapping<Linear> {
01634 //--------members----------
01635 public:
01636   typedef std::set<double> KeySet;
01637   typedef std::map<Dimension, KeySet > KeyMap;
01638 protected:
01639   Mapping* fillRef;
01640   const KeyMap* keys;
01641 
01642 //--------methods----------
01643 protected:
01644   void fillRefIfNecessary() {
01645     KeyMap::const_iterator it = keys->find(myDimension);
01646 
01647     if(it == keys->end())
01648       return;
01649 
01650     fillRef = createSubSignal();
01651 
01652     for (KeySet::const_iterator keyIt = it->second.begin();
01653        keyIt != it->second.end(); ++keyIt)
01654     {
01655       entries.insert(entries.end(), SubFunctionMap::value_type(*keyIt, fillRef));
01656     }
01657   }
01658 
01659   FilledUpMapping(const DimensionSet& myDims, Dimension myDim, const KeyMap* keys, InterpolationMethod intpl = STEPS):
01660     MultiDimMapping<Linear>(myDims, myDim, intpl), fillRef(0), keys(keys)
01661   {
01662     fillRefIfNecessary();
01663   }
01664 
01665   Mapping* createSubSignal() const{
01666     DimensionSet::const_iterator it = dimensions.find(myDimension);
01667     Dimension nextDim = *(--it);
01668     if(nextDim == Dimension::time)
01669       return new TimeMapping<Linear>();
01670     else
01671       return new FilledUpMapping(dimensions, nextDim, keys, LINEAR);
01672   }
01673 public:
01674   FilledUpMapping(ConstMapping* source, const DimensionSet& dims, const KeyMap* keys):
01675     MultiDimMapping<Linear>(dims), fillRef(0), keys(keys)
01676   {
01677     ConstMappingIterator* it = source->createConstIterator();
01678 
01679     if(it->inRange())
01680     {
01681       fillRefIfNecessary();
01682 
01683       while(it->inRange()){
01684         appendValue(it->getPosition(), it->getValue());
01685 
01686         if(!it->hasNext())
01687           break;
01688 
01689         it->next();
01690       }
01691     }
01692 
01693     delete it;
01694 
01695     keys = 0;
01696   }
01697 
01698   virtual ~FilledUpMapping(){
01699     if(fillRef != 0){
01700       delete fillRef;
01701       entries.clear();
01702     }
01703   }
01704 
01705   virtual void appendValue(const Argument& pos, double value) {
01706     assert(keys != 0);
01707 
01708     if(fillRef != 0)
01709     {
01710       fillRef->appendValue(pos, value);
01711     }
01712     else
01713     {
01714       double argVal = pos.getArgValue(myDimension);
01715 
01716       SubFunctionMap::iterator posIt = entries.lower_bound(argVal);
01717 
01718       if(posIt == entries.end() || posIt->first != argVal) {
01719         Mapping* subF = createSubSignal();
01720         posIt = entries.insert(posIt, SubFunctionMap::value_type(argVal, subF));
01721       }
01722 
01723       posIt->second->appendValue(pos, value);
01724     }
01725 
01726   }
01727 
01728   virtual MappingIterator* createIterator() {
01729     return new FilledUpMappingIterator(*this);
01730   }
01731 
01732   virtual MappingIterator* createIterator(const Argument& pos) {
01733     return new FilledUpMappingIterator(*this, pos);
01734   }
01735 };
01736 
01743 class MappingUtils {
01744 public:
01745   typedef std::list<ConstMapping*> MappingBuffer;
01746 private:
01747   static MappingBuffer mappingBuffer;
01748 
01749 private:
01750   static void freeMappingBuffer(ConstMapping* m){
01751     MappingBuffer::iterator it = std::find(mappingBuffer.begin(), mappingBuffer.end(), m);
01752     if(it != mappingBuffer.end()){
01753       delete m;
01754       mappingBuffer.erase(it);
01755     }
01756   }
01757 
01758   static ConstMapping* setMappingBuffer(ConstMapping* mapping){
01759 
01760     mappingBuffer.push_front(mapping);
01761     return mapping;
01762   }
01763 
01764   static ConstMapping* createCompatibleMapping(ConstMapping& src, ConstMapping& dst);
01765 
01766   static bool iterateToNext(ConstMappingIterator* it1, ConstMappingIterator* it2);
01767 
01768 public:
01769 
01776   static Mapping* createMapping(const DimensionSet& domain = DimensionSet(Dimension::time_static()),
01777                   Mapping::InterpolationMethod intpl = Mapping::LINEAR);
01778 
01785   static Mapping* createMapping(double outOfRangeValue,
01786                   const DimensionSet& domain = DimensionSet(Dimension::time_static()),
01787                   Mapping::InterpolationMethod intpl = Mapping::LINEAR);
01788 
01789   template<class Operator>
01790   static Mapping* applyElementWiseOperator(ConstMapping& f1, ConstMapping& f2,
01791                        const Argument& intvlStart,
01792                        const Argument& intvlEnd,
01793                        Operator op){
01794 
01795     return 0;
01796   }
01797 
01798   template<class Operator>
01799   static Mapping* applyElementWiseOperator(ConstMapping& f1, ConstMapping& f2, Operator op,
01800                        double outOfRangeVal = 0.0,
01801                        bool contOutOfRange = true){
01802 
01803 
01804     ConstMapping* f2Comp = createCompatibleMapping(f2, f1);
01805     ConstMapping* f1Comp = createCompatibleMapping(f1, f2);
01806 
01807     const DimensionSet& domain = f1Comp->getDimensionSet();
01808 
01809     Mapping* result = 0;
01810     if(contOutOfRange)
01811       result = MappingUtils::createMapping(domain);
01812     else
01813       result = MappingUtils::createMapping(outOfRangeVal, domain);
01814 
01815     ConstMappingIterator* itF1 = f1Comp->createConstIterator();
01816     ConstMappingIterator* itF2 = f2Comp->createConstIterator();
01817 
01818     if(!itF1->inRange() && !itF2->inRange()){
01819       delete itF1;
01820       delete itF2;
01821       return result;
01822     }
01823 
01824     MappingIterator* itRes = 0;
01825 
01826     if(itF1->inRange() && (!itF2->inRange() || itF1->getPosition() < itF2->getPosition())){
01827       itF2->jumpTo(itF1->getPosition());
01828     } else {
01829       itF1->jumpTo(itF2->getPosition());
01830     }
01831 
01832     itRes = result->createIterator(itF1->getPosition());
01833 
01834     while(itF1->inRange() || itF2->inRange()) {
01835       assert(itF1->getPosition().isSamePosition(itF2->getPosition()));
01836 
01837       double prod = op(itF1->getValue(), itF2->getValue());
01838       //result->setValue(itF1->getPosition(), prod);
01839       itRes->setValue(prod);
01840 
01841       if(!iterateToNext(itF1, itF2))
01842         break;
01843 
01844       itRes->iterateTo(itF1->getPosition());
01845     }
01846 
01847     delete itF1;
01848     delete itF2;
01849     delete itRes;
01850 
01851     freeMappingBuffer(f2Comp);
01852     freeMappingBuffer(f1Comp);
01853 
01854     return result;
01855   }
01856 
01857 
01858 
01868   static Mapping* multiply(ConstMapping& f1, ConstMapping& f2);
01869   static Mapping* add(ConstMapping& f1, ConstMapping& f2);
01870   static Mapping* subtract(ConstMapping& f1, ConstMapping& f2);
01871   static Mapping* divide(ConstMapping& f1, ConstMapping& f2);
01872 
01873   static Mapping* multiply(ConstMapping& f1, ConstMapping& f2, double outOfRangeVal);
01874   static Mapping* add(ConstMapping& f1, ConstMapping& f2, double outOfRangeVal);
01875   static Mapping* subtract(ConstMapping& f1, ConstMapping& f2, double outOfRangeVal);
01876   static Mapping* divide(ConstMapping& f1, ConstMapping& f2, double outOfRangeVal);
01877 
01882   static double findMax(ConstMapping& m);
01883 
01894   static double findMax(ConstMapping& m, const Argument& min, const Argument& max);
01895 
01900   static double findMin(ConstMapping& m);
01901 
01912   static double findMin(ConstMapping& m, const Argument& min, const Argument& max);
01913 
01914 
01915   /*
01916   static Mapping* multiply(ConstMapping& f1, ConstMapping& f2, const Argument& from, const Argument& to);
01917   static Mapping* add(ConstMapping& f1, ConstMapping& f2, const Argument& from, const Argument& to);
01918   static Mapping* subtract(ConstMapping& f1, ConstMapping& f2, const Argument& from, const Argument& to);
01919   static Mapping* divide(ConstMapping& f1, ConstMapping& f2, const Argument& from, const Argument& to);
01920   */
01921 
01922 
01943   static void addDiscontinuity(Mapping* m,
01944                  const Argument& pos, double value,
01945                  simtime_t limitTime, double limitValue);
01946 
01950   static simtime_t pre(simtime_t t);
01951 
01955   static simtime_t post(simtime_t t);
01956 };
01957 
01958 
01959 
01966 class ConcatConstMappingIterator : public FilteredConstMappingIterator{
01967 //--------members----------
01968 protected:
01969   ConstMapping* baseMapping;
01970 
01971 public:
01972   ConcatConstMappingIterator(ConstMapping* baseMapping):
01973     FilteredConstMappingIterator(baseMapping->createConstIterator()),
01974     baseMapping(baseMapping) {}
01975 
01976   ConcatConstMappingIterator(ConstMapping* baseMapping, const Argument& pos):
01977     FilteredConstMappingIterator(baseMapping->createConstIterator(pos)),
01978     baseMapping(baseMapping) {}
01979 
01980   virtual ~ConcatConstMappingIterator() {
01981     delete baseMapping;
01982   }
01983 };
01984 
01992 template<class Operator>
01993 class ConcatConstMapping: public ConstMapping {
01994 protected:
01995   typedef std::pair<Dimension, Argument::const_iterator> DimIteratorPair;
01996   typedef std::list<ConstMapping*> MappingSet;
01997   MappingSet mappings;
01998   ConstMapping* refMapping;
01999 
02000   bool continueOutOfRange;
02001   double oorValue;
02002 
02003   Operator op;
02004 public:
02009   template<class Iterator>
02010   ConcatConstMapping(ConstMapping* refMapping,
02011              Iterator first, Iterator last,
02012              bool continueOutOfRange = true,
02013              double oorValue = 0.0,
02014              Operator op = Operator()):
02015     ConstMapping(refMapping->getDimensionSet()),
02016     refMapping(refMapping),
02017     continueOutOfRange(continueOutOfRange),
02018     oorValue(oorValue),
02019     op(op)
02020   {
02021     while(first != last){
02022       mappings.push_back(*first);
02023       ++first;
02024     }
02025   }
02026 
02031   ConcatConstMapping(ConstMapping* refMapping, ConstMapping* other,
02032              bool continueOutOfRange = true,
02033              double oorValue = 0.0,
02034              Operator op = Operator()):
02035     ConstMapping(refMapping->getDimensionSet()),
02036     refMapping(refMapping),
02037     continueOutOfRange(continueOutOfRange),
02038     oorValue(oorValue),
02039     op(op)
02040   {
02041     mappings.push_back(other);
02042   }
02043 
02048   void addMapping(ConstMapping* m) {
02049     mappings.push_back(m);
02050   }
02051 
02052   virtual double getValue(const Argument& pos) const {
02053     MappingSet::const_iterator it = mappings.begin();
02054     double res = refMapping->getValue(pos);
02055 
02056     for (MappingSet::const_iterator it = mappings.begin();
02057        it != mappings.end(); ++it)
02058     {
02059       res = op(res, (*it)->getValue(pos));
02060     }
02061 
02062     return res;
02063   }
02064 
02068   Mapping* createConcatenatedMapping(){
02069     assert(!mappings.empty());
02070 
02071     MappingSet::const_iterator it = mappings.begin();
02072 
02073     Mapping* result = MappingUtils::applyElementWiseOperator(*refMapping, **it, op,
02074                                  oorValue, continueOutOfRange);
02075 
02076     while(++it != mappings.end()){
02077       Mapping* buf = result;
02078       result = MappingUtils::applyElementWiseOperator(*buf, **it, op,
02079                               oorValue, continueOutOfRange);
02080       delete buf;
02081     }
02082 
02083     return result;
02084   }
02085 
02086   virtual ConstMappingIterator* createConstIterator() {
02087     if(mappings.empty()) {
02088       return refMapping->createConstIterator();
02089     }
02090     return new ConcatConstMappingIterator(createConcatenatedMapping());
02091   }
02092 
02093   virtual ConstMappingIterator* createConstIterator(const Argument& pos) {
02094     if(mappings.empty()) {
02095       return refMapping->createConstIterator(pos);
02096     }
02097     return new ConcatConstMappingIterator(createConcatenatedMapping(), pos);
02098   }
02099 
02100   virtual ConstMapping* constClone() const {
02101     return new ConcatConstMapping(*this);
02102   }
02103 
02107   ConstMapping* getRefMapping() {
02108     return refMapping;
02109   }
02110 };
02111 
02119 template<class Base, class Iterator>
02120 class BaseDelayedIterator: public Base {
02121 protected:
02122   simtime_t delay;
02123 
02124   Argument position;
02125   Argument nextPosition;
02126 protected:
02127   Argument undelayPosition(const Argument& pos) const{
02128     Argument res(pos);
02129     res.setTime(res.getTime() - delay);
02130     return res;
02131   }
02132 
02133   Argument delayPosition(const Argument& pos) const {
02134     Argument res(pos);
02135       res.setTime(res.getTime() + delay);
02136       return res;
02137   }
02138 
02139   void updatePosition() {
02140     nextPosition = delayPosition(this->origIterator->getNextPosition());
02141     position = delayPosition(this->origIterator->getPosition());
02142   }
02143 
02144 public:
02145   BaseDelayedIterator(Iterator* it, simtime_t delay):
02146     Base(it), delay(delay) {
02147 
02148     updatePosition();
02149   }
02150 
02151   virtual ~BaseDelayedIterator() {}
02152 
02153   virtual const Argument& getNextPosition() const { return nextPosition; }
02154 
02155   virtual void jumpTo(const Argument& pos) {
02156     this->origIterator->jumpTo(undelayPosition(pos));
02157     updatePosition();
02158   }
02159 
02160   virtual void jumpToBegin() {
02161     this->origIterator->jumpToBegin();
02162     updatePosition();
02163   }
02164 
02165   virtual void iterateTo(const Argument& pos) {
02166     this->origIterator->iterateTo(undelayPosition(pos));
02167     updatePosition();
02168   }
02169 
02170   virtual void next() {
02171     this->origIterator->next();
02172     updatePosition();
02173   }
02174 
02175   virtual const Argument& getPosition() const {
02176     return position;
02177   }
02178 };
02179 
02187 typedef BaseDelayedIterator<FilteredConstMappingIterator, ConstMappingIterator> ConstDelayedMappingIterator;
02188 
02196 typedef BaseDelayedIterator<FilteredMappingIterator, MappingIterator> DelayedMappingIterator;
02197 
02205 template<class Base>
02206 class BaseDelayedMapping: public Base {
02207 protected:
02208   Base* mapping;
02209   simtime_t delay;
02210 
02211 
02212 protected:
02213   Argument delayPosition(const Argument& pos) const {
02214     Argument res(pos);
02215     res.setTime(res.getTime() - delay);
02216     return res;
02217   }
02218 
02219 public:
02220   BaseDelayedMapping(Base* mapping, simtime_t delay):
02221     Base(mapping->getDimensionSet()), mapping(mapping), delay(delay) {}
02222 
02223   virtual ~BaseDelayedMapping() {}
02224 
02225   virtual double getValue(const Argument& pos) const {
02226     return mapping->getValue(delayPosition(pos));
02227   }
02228 
02229   virtual ConstMappingIterator* createConstIterator() {
02230     return new ConstDelayedMappingIterator(mapping->createConstIterator(), delay);
02231   }
02232 
02233   virtual ConstMappingIterator* createConstIterator(const Argument& pos) {
02234     return new ConstDelayedMappingIterator(mapping->createConstIterator(delayPosition(pos)), delay);
02235   }
02236 
02240   virtual simtime_t getDelay() const {
02241     return delay;
02242   }
02243 
02247   virtual void delayMapping(simtime_t d) {
02248     delay = d;
02249   }
02250 };
02251 
02261 class ConstDelayedMapping: public BaseDelayedMapping<ConstMapping> {
02262 public:
02263   ConstDelayedMapping(ConstMapping* mapping, simtime_t delay):
02264     BaseDelayedMapping<ConstMapping>(mapping, delay) {}
02265 
02266   virtual ~ConstDelayedMapping() {}
02267 
02268   virtual ConstMapping* constClone() const {
02269     return new ConstDelayedMapping(mapping->constClone(), delay);
02270   }
02271 };
02272 
02282 class DelayedMapping: public BaseDelayedMapping<Mapping> {
02283 public:
02284   DelayedMapping(Mapping* mapping, simtime_t delay):
02285     BaseDelayedMapping<Mapping>(mapping, delay) {}
02286 
02287   virtual ~DelayedMapping() {}
02288 
02289   virtual void setValue(const Argument& pos, double value) {
02290     mapping->setValue(delayPosition(pos), value);
02291   }
02292 
02293   virtual Mapping* clone() const {
02294     return new DelayedMapping(mapping->clone(), delay);
02295   }
02296 
02297   virtual MappingIterator* createIterator() {
02298     return new DelayedMappingIterator(mapping->createIterator(), delay);
02299   }
02300 
02301   virtual MappingIterator* createIterator(const Argument& pos) {
02302     return new DelayedMappingIterator(mapping->createIterator(delayPosition(pos)), delay);
02303   }
02304 };
02305 
02306 
02307 Mapping* operator*(ConstMapping& f1, ConstMapping& f2);
02308 Mapping* operator/(ConstMapping& f1, ConstMapping& f2);
02309 Mapping* operator+(ConstMapping& f1, ConstMapping& f2);
02310 Mapping* operator-(ConstMapping& f1, ConstMapping& f2);
02311 
02312 #endif /* SIGNALINTERFACES_H_ */