changed MovingPercentile to use QList

This commit is contained in:
wangyix 2014-06-04 14:24:23 -07:00
parent ebfc405d9d
commit e2d3fcc518
2 changed files with 29 additions and 48 deletions

View file

@ -13,65 +13,47 @@
MovingPercentile::MovingPercentile(int numSamples, float percentile) MovingPercentile::MovingPercentile(int numSamples, float percentile)
: _numSamples(numSamples), : _numSamples(numSamples),
_percentile(percentile), _percentile(percentile),
_numExistingSamples(0), _samplesSorted(),
_valueAtPercentile(0.0f), _sampleIds(),
_indexOfPercentile(0) _newSampleId(0),
_indexOfPercentile(0),
_valueAtPercentile(0.0f)
{ {
_samplesSorted = new float[numSamples];
_sampleAges = new int[numSamples];
}
MovingPercentile::~MovingPercentile() {
delete[] _samplesSorted;
delete[] _sampleAges;
} }
void MovingPercentile::updatePercentile(float sample) { void MovingPercentile::updatePercentile(float sample) {
// age all current samples by 1 // insert the new sample into _samplesSorted
for (int i = 0; i < _numExistingSamples; i++) {
_sampleAges[i]++;
}
// find index at which to insert new sample in _samplesSorted
int newSampleIndex; int newSampleIndex;
if (_numExistingSamples < _numSamples) { if (_sampleIds.size() < _numSamples) {
// if samples have not been filled yet, this will be the next empty spot // if not all samples have been filled yet, simply append it
newSampleIndex = _numExistingSamples; newSampleIndex = _samplesSorted.size();
_numExistingSamples++; _samplesSorted.append(sample);
_sampleIds.append(_newSampleId);
// update _indexOfPercentile // update _indexOfPercentile
float index = _percentile * (float)(_numExistingSamples - 1); float index = _percentile * (float)(_sampleIds.size() - 1);
_indexOfPercentile = (int)(index + 0.5f); // round to int _indexOfPercentile = (int)(index + 0.5f); // round to int
} }
else { else {
// if samples have been filled, it will be the spot of the oldest sample // find index of sample with id = _newSampleId and replace it with new sample
newSampleIndex = 0; newSampleIndex = _sampleIds.indexOf(_newSampleId);
while (_sampleAges[newSampleIndex] != _numExistingSamples) { newSampleIndex++; } _samplesSorted[newSampleIndex] = sample;
} }
// insert new sample // increment _newSampleId. cycles from 0 thru N-1
_samplesSorted[newSampleIndex] = sample; _newSampleId = (_newSampleId == _numSamples - 1) ? 0 : _newSampleId + 1;
_sampleAges[newSampleIndex] = 0;
// swap new sample with neighboring elements in _samplesSorted until it's in sorted order // swap new sample with neighbors in _samplesSorted until it's in sorted order
// try swapping up first, then down. element will only be swapped one direction. // try swapping up first, then down. element will only be swapped one direction.
while (newSampleIndex < _numExistingSamples-1 && sample > _samplesSorted[newSampleIndex+1]) { while (newSampleIndex < _sampleIds.size() - 1 && sample > _samplesSorted[newSampleIndex + 1]) {
_samplesSorted[newSampleIndex] = _samplesSorted[newSampleIndex + 1]; _samplesSorted.swap(newSampleIndex, newSampleIndex + 1);
_samplesSorted[newSampleIndex+1] = sample; _sampleIds.swap(newSampleIndex, newSampleIndex + 1);
_sampleAges[newSampleIndex] = _sampleAges[newSampleIndex+1];
_sampleAges[newSampleIndex+1] = 0;
newSampleIndex++; newSampleIndex++;
} }
while (newSampleIndex > 0 && sample < _samplesSorted[newSampleIndex - 1]) { while (newSampleIndex > 0 && sample < _samplesSorted[newSampleIndex - 1]) {
_samplesSorted[newSampleIndex] = _samplesSorted[newSampleIndex - 1]; _samplesSorted.swap(newSampleIndex, newSampleIndex - 1);
_samplesSorted[newSampleIndex - 1] = sample; _sampleIds.swap(newSampleIndex, newSampleIndex - 1);
_sampleAges[newSampleIndex] = _sampleAges[newSampleIndex - 1];
_sampleAges[newSampleIndex - 1] = 0;
newSampleIndex--; newSampleIndex--;
} }

View file

@ -11,27 +11,26 @@
#ifndef hifi_MovingPercentile_h #ifndef hifi_MovingPercentile_h
#define hifi_MovingPercentile_h #define hifi_MovingPercentile_h
#include <qlist.h>
class MovingPercentile { class MovingPercentile {
public: public:
MovingPercentile(int numSamples, float percentile = 0.5f); MovingPercentile(int numSamples, float percentile = 0.5f);
~MovingPercentile();
void updatePercentile(float sample); void updatePercentile(float sample);
float getValueAtPercentile() const { return _valueAtPercentile; } float getValueAtPercentile() const { return _valueAtPercentile; }
private: private:
const int _numSamples; const int _numSamples;
const float _percentile; const float _percentile;
float* _samplesSorted; QList<float> _samplesSorted;
int* _sampleAges; // _sampleAges[i] is the "age" of the sample at _sampleSorted[i] (higher means older) QList<int> _sampleIds; // incrementally assigned, is cyclic
int _numExistingSamples; int _newSampleId;
float _valueAtPercentile;
int _indexOfPercentile; int _indexOfPercentile;
float _valueAtPercentile;
}; };
#endif #endif