GreedySampler.cc
Go to the documentation of this file.00001 #include "GreedySampler.h"
00002 #include <algorithm>
00003 #include <iostream>
00004 #include <cmath>
00005
00006 float GreedySampler::sample() {
00007 if(ranges.size()==0) {
00008 float r = full.span/2;
00009 float x = full.min+r;
00010 full.min-=r;
00011 ranges.push_back(full);
00012 return x;
00013 } else {
00014 pop_heap(ranges.begin(), ranges.end());
00015 float r2 = ranges.back().span / 2;
00016 float x = ranges.back().min + r2;
00017 ranges.back().span = r2;
00018 push_heap(ranges.begin(), ranges.end());
00019 ranges.push_back(range(x,r2));
00020 push_heap(ranges.begin(), ranges.end());
00021 if(x < reqMin)
00022 x+=full.span;
00023 return x;
00024 }
00025 }
00026
00027 float GreedySampler::resolution() {
00028 if(ranges.size()==0) {
00029 return full.span;
00030 } else {
00031 return ranges.front().span;
00032 }
00033 }
00034
00035 void GreedySampler::remove(float x) {
00036 if(ranges.size()==0) {
00037 full.min = normalize(x) - full.span;
00038 ranges.push_back(full);
00039 } else {
00040 if(circular)
00041 x = normalize(x);
00042 if(x <= full.min || full.min+full.span <= x) {
00043 if(x==full.min || x==full.min+full.span)
00044 return;
00045 throw std::range_error("takeSample(x): x out of the sampled range");
00046 }
00047 std::vector<range>::iterator it=ranges.begin();
00048 for(; it!=ranges.end(); ++it) {
00049 if(it->min <= x && x < it->min+it->span) {
00050 break;
00051 }
00052 }
00053 #ifdef DEBUG
00054 if(it==ranges.end())
00055 throw std::runtime_error("takeSample(x): could not find x in sampled range");
00056 #endif
00057 if(it->min == x)
00058 return;
00059 float r = x - it->min;
00060 range n(x, it->span - r);
00061 it->span = r;
00062 ranges.push_back(n);
00063 make_heap(ranges.begin(),ranges.end());
00064 }
00065 }
00066
00067 void GreedySampler::reset() {
00068 full.min=reqMin;
00069 ranges.clear();
00070 if(!circular)
00071 ranges.push_back(full);
00072 }
00073
00074 void GreedySampler::reset(float min, float max, bool circ) {
00075 reqMin = full.min = min;
00076 full.span = max-min;
00077 circular=circ;
00078 ranges.clear();
00079 if(!circular)
00080 ranges.push_back(full);
00081 }
00082
00083 float GreedySampler::normalize(float value) {
00084 const float max = full.min + full.span;
00085 if ( value >= max ) {
00086 if ( value <= max+full.span ) {
00087 value -= full.span;
00088 } else {
00089 value = std::fmod(value,full.span);
00090 if( value > max )
00091 value -= full.span;
00092 }
00093 } else if ( value < full.min ) {
00094 if ( value >= full.min-full.span ) {
00095 value += full.span;
00096 } else {
00097 value = std::fmod(value,full.span);
00098 if( value <= full.min )
00099 value += full.span;
00100 }
00101 }
00102 return value;
00103 }
00104
00105 std::ostream& operator<<(std::ostream& os, const GreedySampler& gs) {
00106 for(std::vector<GreedySampler::range>::const_iterator it=gs.ranges.begin(); it!=gs.ranges.end(); ++it)
00107 os << "(" << it->min << "," << (it->min+it->span) << ") ";
00108 return os << "\n";
00109 }
00110