Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

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) { // implies circular
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) // implies circular with an initial removal
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) { // implies circular
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; // technically not in the 'sampled' range, but we'll ignore it
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()) // this shouldn't be possible (already did range check), but just in case...
00055       throw std::runtime_error("takeSample(x): could not find x in sampled range");
00056 #endif
00057     if(it->min == x)
00058       return; // duplicate sample, ignore it
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 { // use fmod only if necessary
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 { // use fmod only if necessary
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 

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:41 2016 by Doxygen 1.6.3