11//
22// FILE: RunningMedian.cpp
33// AUTHOR: Rob dot Tillaart at gmail dot com
4- // VERSION: 0.1.08
4+ // VERSION: 0.1.10
55// PURPOSE: RunningMedian library for Arduino
66//
77// HISTORY:
1414// 0.1.06 - 2013-10-19 faster sort, dynamic arrays, replaced sorted float array with indirection array
1515// 0.1.07 - 2013-10-19 add correct median if _cnt is even.
1616// 0.1.08 - 2013-10-20 add getElement(), add getSottedElement() add predict()
17+ // 0.1.09 - 2014-11-25 float to double (support ARM)
18+ // 0.1.10 - 2015-03-07 fix clear
1719//
1820// Released to the public domain
1921//
@@ -25,7 +27,7 @@ RunningMedian::RunningMedian(uint8_t size)
2527 _size = constrain (size, MEDIAN_MIN_SIZE, MEDIAN_MAX_SIZE);
2628
2729#ifdef RUNNING_MEDIAN_USE_MALLOC
28- _ar = (float *) malloc (_size * sizeof (float ));
30+ _ar = (double *) malloc (_size * sizeof (double ));
2931 _p = (uint8_t *) malloc (_size * sizeof (uint8_t ));
3032#endif
3133
@@ -47,47 +49,47 @@ void RunningMedian::clear()
4749 _idx = 0 ;
4850 _sorted = false ;
4951
50- for (uint8_t i=0 ; i< _size; i++) _p[i] = i ;
52+ for (uint8_t i=0 ; i< _size; i++) _p[i] = 0 ;
5153}
5254
5355// adds a new value to the data-set
5456// or overwrites the oldest if full.
55- void RunningMedian::add (float value)
57+ void RunningMedian::add (double value)
5658{
5759 _ar[_idx++] = value;
5860 if (_idx >= _size) _idx = 0 ; // wrap around
5961 if (_cnt < _size) _cnt++;
6062 _sorted = false ;
6163}
6264
63- float RunningMedian::getMedian ()
65+ double RunningMedian::getMedian ()
6466{
6567 if (_cnt > 0 )
6668 {
6769 if (_sorted == false ) sort ();
6870 if (_cnt & 0x01 ) return _ar[_p[_cnt/2 ]];
69- else return (_ar[_p[_cnt/2 ]] + _ar[_p[_cnt/2 - 1 ]]) / 2.0 ;
71+ else return (_ar[_p[_cnt/2 ]] + _ar[_p[_cnt/2 - 1 ]]) / 2 ;
7072 }
7173 return NAN;
7274}
7375
7476#ifdef RUNNING_MEDIAN_ALL
75- float RunningMedian::getHighest () { return getSortedElement (_cnt-1 ); }
77+ double RunningMedian::getHighest () { return getSortedElement (_cnt-1 ); }
7678
77- float RunningMedian::getLowest () { return getSortedElement (0 ); }
79+ double RunningMedian::getLowest () { return getSortedElement (0 ); }
7880
79- float RunningMedian::getAverage ()
81+ double RunningMedian::getAverage ()
8082{
8183 if (_cnt > 0 )
82- {
83- float sum = 0 ;
84+ {
85+ double sum = 0 ;
8486 for (uint8_t i=0 ; i< _cnt; i++) sum += _ar[i];
8587 return sum / _cnt;
8688 }
8789 return NAN;
8890}
8991
90- float RunningMedian::getAverage (uint8_t nMedians)
92+ double RunningMedian::getAverage (uint8_t nMedians)
9193{
9294 if ((_cnt > 0 ) && (nMedians > 0 ))
9395 {
@@ -96,15 +98,14 @@ float RunningMedian::getAverage(uint8_t nMedians)
9698 uint8_t stop = start + nMedians;
9799
98100 if (_sorted == false ) sort ();
99-
100- float sum = 0 ;
101+ double sum = 0 ;
101102 for (uint8_t i = start; i < stop; i++) sum += _ar[_p[i]];
102103 return sum / nMedians;
103104 }
104105 return NAN;
105106}
106107
107- float RunningMedian::getElement (uint8_t n)
108+ double RunningMedian::getElement (uint8_t n)
108109{
109110 if ((_cnt > 0 ) && (n < _cnt))
110111 {
@@ -113,7 +114,7 @@ float RunningMedian::getElement(uint8_t n)
113114 return NAN;
114115}
115116
116- float RunningMedian::getSortedElement (uint8_t n)
117+ double RunningMedian::getSortedElement (uint8_t n)
117118{
118119 if ((_cnt > 0 ) && (n < _cnt))
119120 {
@@ -123,28 +124,25 @@ float RunningMedian::getSortedElement(uint8_t n)
123124 return NAN;
124125}
125126
126- float RunningMedian::predict (uint8_t n)
127+ // n can be max <= half the (filled) size
128+ double RunningMedian::predict (uint8_t n)
127129{
128130 if ((_cnt > 0 ) && (n < _cnt/2 ))
129131 {
130- float med = getMedian (); // takes care of sorting !
132+ double med = getMedian (); // takes care of sorting !
131133 if (_cnt & 0x01 )
132134 {
133135 return max (med - _ar[_p[_cnt/2 -n]], _ar[_p[_cnt/2 +n]] - med);
134136 }
135137 else
136138 {
137- float f1 = (_ar[_p[_cnt/2 - n]] + _ar[_p[_cnt/2 - n - 1 ]])/2 ;
138- float f2 = (_ar[_p[_cnt/2 + n]] + _ar[_p[_cnt/2 + n - 1 ]])/2 ;
139+ double f1 = (_ar[_p[_cnt/2 - n]] + _ar[_p[_cnt/2 - n - 1 ]])/2 ;
140+ double f2 = (_ar[_p[_cnt/2 + n]] + _ar[_p[_cnt/2 + n - 1 ]])/2 ;
139141 return max (med - f1, f2 - med)/2 ;
140142 }
141143 }
142144 return NAN;
143145}
144-
145- uint8_t RunningMedian::getSize () { return _size; };
146-
147- uint8_t RunningMedian::getCount () { return _cnt; };
148146#endif
149147
150148void RunningMedian::sort ()
0 commit comments