00001 #ifndef INTERPOLATION_H_
00002 #define INTERPOLATION_H_
00003
00004 #include <map>
00005 #include <algorithm>
00006
00026 template<class V>
00027 class Interpolated {
00028 protected:
00029 V value;
00030
00031 public:
00032 bool isInterpolated;
00033
00034 public:
00035 Interpolated(V v, bool isIntpl = true):
00036 value(v), isInterpolated(isIntpl) {}
00037
00038 V& operator*() {
00039 return value;
00040 }
00041
00042 V* operator->() {
00043 return &value;
00044 }
00045
00046 bool operator==(const Interpolated<V>& other) {
00047 return other.value == value && other.isInterpolated == isInterpolated;
00048 }
00049
00050 bool operator!=(const Interpolated<V>& other) {
00051 return other.value != value || other.isInterpolated != isInterpolated;
00052 }
00053 };
00054
00060 template<class Pair, class Key>
00061 class PairLess {
00062 public:
00063 bool operator()(const Pair& p, const Key& v) {
00064 return p.first < v;
00065 }
00066
00067 bool operator()(const Key& v, const Pair& p) {
00068 return v < p.first;
00069 }
00070 };
00071
00083 template<class Key, class V, class Pair, class InputIterator>
00084 class NextSmaller {
00085 public:
00086 typedef Interpolated<V> interpolated;
00087 protected:
00088
00089 PairLess<Pair, Key> comp;
00090 bool continueOutOfRange;
00091 V outOfRangeVal;
00092 public:
00093 NextSmaller():
00094 continueOutOfRange(true) {}
00095
00096 NextSmaller(V oorv):
00097 continueOutOfRange(false), outOfRangeVal(oorv) {}
00098
00099 void setOutOfRangeVal(V oorv){
00100 outOfRangeVal = oorv;
00101 }
00102
00103 interpolated operator()(const InputIterator& first,
00104 const InputIterator& last,
00105 const Key& pos) const{
00106
00107 InputIterator right = std::upper_bound(first, last, pos, comp);
00108
00109 return operator()(first, last, pos, right);
00110 }
00111
00112 interpolated operator()(const InputIterator& first,
00113 const InputIterator& last,
00114 const Key& pos,
00115 InputIterator upperBound) const{
00116 if(first == last){
00117 if(continueOutOfRange)
00118 return interpolated(V());
00119 else
00120 return interpolated(outOfRangeVal);
00121 }
00122
00123 if(upperBound == first){
00124 if(continueOutOfRange)
00125 return interpolated(upperBound->second);
00126 else
00127 return interpolated(outOfRangeVal);
00128 }
00129
00130 upperBound--;
00131 if(upperBound->first == pos)
00132 return interpolated(upperBound->second, false);
00133
00134 return interpolated(upperBound->second);
00135 }
00136 };
00137
00146 template<class Key, class V, class Pair, class InputIterator>
00147 class Nearest {
00148 public:
00149 typedef Interpolated<V> interpolated;
00150 protected:
00151
00152 PairLess<Pair, Key> comp;
00153 bool continueOutOfRange;
00154 V outOfRangeVal;
00155 public:
00156 Nearest():
00157 continueOutOfRange(true) {}
00158
00159 Nearest(V oorv):
00160 continueOutOfRange(false), outOfRangeVal(oorv) {}
00161
00162 void setOutOfRangeVal(V oorv){
00163 outOfRangeVal = oorv;
00164 }
00165
00166 interpolated operator()(const InputIterator& first,
00167 const InputIterator& last,
00168 const Key& pos) const{
00169
00170 InputIterator right = std::upper_bound(first, last, pos, comp);
00171
00172 return operator()(first, last, pos, right);
00173 }
00174
00175 interpolated operator()(const InputIterator& first,
00176 const InputIterator& last,
00177 const Key& pos,
00178 InputIterator upperBound) const{
00179 if(first == last){
00180 if(continueOutOfRange)
00181 return interpolated(V());
00182 else
00183 return interpolated(outOfRangeVal);
00184 }
00185
00186 if(upperBound == first){
00187 if(continueOutOfRange)
00188 return interpolated(upperBound->second);
00189 else
00190 return interpolated(outOfRangeVal);
00191 }
00192
00193 InputIterator left = upperBound;
00194 --left;
00195
00196 if(left->first == pos)
00197 return interpolated(left->second, false);
00198
00199 InputIterator right = upperBound;
00200
00201 if(right == last){
00202 if(continueOutOfRange)
00203 return interpolated(left->second);
00204 else
00205 return interpolated(outOfRangeVal);
00206 }
00207
00208 if(pos - left->first < right->first - pos)
00209 return interpolated(left->second);
00210 else
00211 return interpolated(right->second);
00212 }
00213 };
00214
00222 template<class Key, class V, class Pair, class InputIterator>
00223 class Linear {
00224 public:
00225 typedef Interpolated<V> interpolated;
00226 protected:
00227
00228 PairLess<Pair, Key> comp;
00229 bool continueOutOfRange;
00230 V outOfRangeVal;
00231 public:
00232 Linear():
00233 continueOutOfRange(true) {}
00234
00235 Linear(V oorv):
00236 continueOutOfRange(false), outOfRangeVal(oorv) {}
00237
00238 void setOutOfRangeVal(V oorv){
00239 outOfRangeVal = oorv;
00240 }
00241
00242 static double linearInterpolation(const Key& t,
00243 const Key& t0, const Key& t1,
00244 const V& v0, const V& v1){
00245 return v0 + (v1 - v0) * (double)((t - t0) / (t1 - t0));
00246 }
00247
00248 interpolated operator()(const InputIterator& first,
00249 const InputIterator& last,
00250 const Key& pos) const{
00251
00252 InputIterator right = std::upper_bound(first, last, pos, comp);
00253
00254 return operator()(first, last, pos, right);
00255 }
00256
00257 interpolated operator()(const InputIterator& first,
00258 const InputIterator& last,
00259 const Key& pos,
00260 InputIterator upperBound) const{
00261 if(first == last){
00262 if(continueOutOfRange)
00263 return interpolated(V());
00264 else
00265 return interpolated(outOfRangeVal);
00266 }
00267
00268 if(upperBound == first){
00269 if(continueOutOfRange)
00270 return interpolated(upperBound->second);
00271 else
00272 return interpolated(outOfRangeVal);
00273 }
00274
00275 InputIterator right = upperBound;
00276 InputIterator left = --upperBound;
00277
00278 if(left->first == pos)
00279 return interpolated(left->second, false);
00280
00281 if(right == last){
00282 if(continueOutOfRange)
00283 return interpolated(left->second);
00284 else
00285 return interpolated(outOfRangeVal);
00286 }
00287
00288 return interpolated(linearInterpolation(pos, left->first, right->first, left->second, right->second));
00289 }
00290 };
00291
00335 template<class Key, class V,
00336 class Pair = const typename std::map<Key, V>::value_type,
00337 class Iterator = const typename std::map<Key, V>::const_iterator,
00338 class Interpolator = NextSmaller<Key, V, Pair, Iterator> >
00339 class ConstInterpolateableIterator {
00340 public:
00342 typedef Interpolated<V> interpolated;
00343 protected:
00344 Iterator first;
00345 Iterator last;
00346
00347 Iterator right;
00348
00349 Key position;
00350 const Interpolator& interpolate;
00351
00352 PairLess<Pair, Key> comp;
00353 public:
00358 ConstInterpolateableIterator(Iterator first, Iterator last, const Interpolator& intpl):
00359 first(first), last(last), right(first), position(), interpolate(intpl), comp(){
00360
00361 jumpToBegin();
00362 }
00363
00364 bool operator==(const ConstInterpolateableIterator& other) {
00365 return position == other.position && right == other.right;
00366 }
00367
00372 void jumpTo(const Key& pos) {
00373 if(pos == position)
00374 return;
00375
00376 if(first != last)
00377 right = std::upper_bound(first, last, pos, comp);
00378
00379 position = pos;
00380 }
00381
00385 void jumpToBegin() {
00386 right = first;
00387 if(right != last) {
00388 position = right->first;
00389 right++;
00390 } else {
00391 position = Key();
00392 }
00393 }
00394
00403 void iterateTo(const Key& pos) {
00404 if(pos == position)
00405 return;
00406
00407 while(right != last && !(pos < right->first))
00408 right++;
00409
00410 position = pos;
00411 }
00412
00421 void next() {
00422 if(hasNext()) {
00423 position = right->first;
00424 right++;
00425 } else
00426 position += 1;
00427 }
00428
00429 Key getNextPosition(){
00430 if(hasNext())
00431 return right->first;
00432 else
00433 return position + 1;
00434 }
00435
00440 bool inRange() const{
00441 if(first == last)
00442 return false;
00443
00444 Iterator tail = last;
00445
00446 return !(position < first->first) && !((--tail)->first < position);
00447 }
00448
00454 bool hasNext() const{
00455 return right != last;
00456 }
00457
00464 interpolated getValue() const{
00465
00466 return interpolate(first, last, position, right);
00467 }
00468
00469 interpolated getNextValue() const{
00470 if(right == last)
00471 return interpolate(first, last, position + 1, right);
00472 else{
00473 Iterator tmp = right;
00474 return interpolate(first, last, right->first, ++tmp);
00475 }
00476 }
00477
00481 Key getPosition() const{
00482 return position;
00483 }
00484
00485 };
00486
00503 template<class Key, class V,
00504 class Container = std::map<Key, V>,
00505 class Interpolator = NextSmaller<Key, V, typename Container::value_type, typename Container::const_iterator> >
00506 class InterpolateableIterator:public ConstInterpolateableIterator<Key, V,
00507 typename Container::value_type,
00508 typename Container::iterator,
00509 Interpolator>
00510 {
00511 protected:
00512 typedef typename Container::value_type value_type;
00513 typedef typename Container::iterator Iterator;
00514 typedef ConstInterpolateableIterator<Key,V,
00515 value_type,
00516 Iterator,
00517 Interpolator> BaseClassType;
00518
00519 Container& cont;
00520
00521 public:
00522 InterpolateableIterator(Container& cont, const Interpolator& intpl):
00523 BaseClassType(cont.begin(), cont.end(), intpl), cont(cont) {}
00524
00529 void setValue(const V& value) {
00530
00531 if(this->right == this->first) {
00532
00533 this->first = cont.insert(this->first, value_type(this->position, value));
00534
00535 } else {
00536 Iterator left = this->right;
00537 left--;
00538 if(left->first == this->position) {
00539 left->second = value;
00540 } else {
00541 cont.insert(this->right, value_type(this->position, value));
00542 }
00543 }
00544 }
00545 };
00546
00558 template<class Key, class V,
00559 class Interpolator = NextSmaller<Key, V, typename std::map<Key, V>::value_type, typename std::map<Key, V>::const_iterator> >
00560 class InterpolateableMap:public std::map<Key, V> {
00561 public:
00562 typedef std::map<Key, V> map_type;
00563 typedef typename map_type::const_iterator const_iterator;
00564 typedef typename map_type::iterator iterator;
00565 typedef typename map_type::value_type value_type;
00566 typedef InterpolateableIterator<Key, V, map_type, Interpolator> intpl_iterator;
00567 typedef ConstInterpolateableIterator<Key, V, const map_type,
00568 typename map_type::const_iterator,
00569 Interpolator> const_intpl_iterator;
00570 typedef Interpolated<V> interpolated;
00571
00572 protected:
00573
00574 Interpolator interpolate;
00575 public:
00576
00577 InterpolateableMap() {}
00578
00579 InterpolateableMap(V oorv):
00580 interpolate(oorv) {}
00581
00582 void setOutOfRangeVal(V oorv){
00583 interpolate.setOutOfRangeVal(oorv);
00584 }
00585
00586 interpolated getIntplValue(const Key& pos) const {
00587
00588
00589
00590 const_iterator it = this->upper_bound(pos);
00591
00592
00593
00594
00595
00596 return interpolate(this->begin(), this->end(), pos, it);
00597 }
00598
00599 const_intpl_iterator findIntpl(const Key& pos) const{
00600 const_intpl_iterator it(this->begin(), this->end(), interpolate);
00601
00602 it.jumpTo(pos);
00603
00604 return it;
00605 }
00606
00607 const_intpl_iterator beginIntpl() const{
00608 const_intpl_iterator it(this->begin(), this->end, interpolate);
00609
00610 return it;
00611 }
00612
00613 intpl_iterator findIntpl(const Key& pos) {
00614 intpl_iterator it(*this, interpolate);
00615
00616 it.jumpTo(pos);
00617
00618 return it;
00619 }
00620
00621 intpl_iterator beginIntpl() {
00622 intpl_iterator it(*this, interpolate);
00623
00624 return it;
00625 }
00626 };
00627 #endif