-
-
Notifications
You must be signed in to change notification settings - Fork 9
/
RunningMedian.h
113 lines (87 loc) · 3.23 KB
/
RunningMedian.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#pragma once
//
// FILE: RunningMedian.h
// AUTHOR: Rob Tillaart
// PURPOSE: RunningMedian library for Arduino
// VERSION: 0.3.9
// URL: https://github.com/RobTillaart/RunningMedian
// URL: http://arduino.cc/playground/Main/RunningMedian
// HISTORY: See RunningMedian.cpp
#include "Arduino.h"
#define RUNNING_MEDIAN_VERSION (F("0.3.9"))
// fall back to fixed storage for dynamic version => remove true
#ifndef RUNNING_MEDIAN_USE_MALLOC
#define RUNNING_MEDIAN_USE_MALLOC true
#endif
// MEDIAN_MIN_SIZE should at least be 3 to be practical,
#ifndef MEDIAN_MIN_SIZE
#define MEDIAN_MIN_SIZE 3
#endif
#ifndef MEDIAN_MAX_SIZE
#ifdef RUNNING_MEDIAN_USE_MALLOC
// max 250 to not overflow uint8_t internal variables
#define MEDIAN_MAX_SIZE 255
#else
// using fixed memory will be limited to 19 elements.
#define MEDIAN_MAX_SIZE 19
#endif
#endif
class RunningMedian
{
public:
// # elements in the internal buffer
// odd sizes results in a 'real' middle element and will be a bit faster.
// even sizes takes the average of the two middle elements as median
explicit RunningMedian(const uint8_t size);
~RunningMedian();
// resets internal buffer and variables
void clear();
// adds a new value to internal buffer, optionally replacing the oldest element.
void add(const float value);
// returns the median == middle element
float getMedian();
// returns the Quantile
float getQuantile(const float quantile);
// returns average of the values in the internal buffer
float getAverage();
// returns average of the middle nMedian values, removes noise from outliers
float getAverage(uint8_t nMedian);
// returns average of the middle nMedian values, removes noise from outliers
// Bias compensated see #22.
float getMedianAverage(uint8_t nMedian);
float getHighest() { return getSortedElement(_count - 1); };
float getLowest() { return getSortedElement(0); };
// get n-th element from the values in time order
float getElement(const uint8_t n);
// get n-th element from the values in size order
float getSortedElement(const uint8_t n);
// predict the max change of median after n additions
float predict(const uint8_t n);
uint8_t getSize() { return _size; };
// returns current used elements, getCount() <= getSize()
uint8_t getCount() { return _count; };
bool isFull() { return (_count == _size); }
// EXPERIMENTAL (might change in the future)
// searchMode defines how the internal insertionSort works
// can be used to optimize performance.
// 0 = LINEAR_SEARCH 1 = BINARY_SEARCH
void setSearchMode(uint8_t searchMode = 0);
uint8_t getSearchMode();
protected:
boolean _sorted; // _sortIdx{} is up to date
uint8_t _size; // max number of values
uint8_t _count; // current number of values <= size
uint8_t _index; // next index to add
// _values holds the elements themself
// _sortIdx holds the index for sorted
#if RUNNING_MEDIAN_USE_MALLOC
float * _values;
uint8_t * _sortIdx;
#else
float _values[MEDIAN_MAX_SIZE];
uint8_t _sortIdx[MEDIAN_MAX_SIZE];
#endif
void sort();
uint8_t _searchMode = 0;
};
// -- END OF FILE --