1111// 0.1.03 - 2013-09-30 added _sorted flag, minor refactor
1212// 0.1.04 - 2013-10-17 added getAverage(uint8_t) - kudo's to Sembazuru
1313// 0.1.05 - 2013-10-18 fixed bug in sort; removes default constructor; dynamic memory
14- // 0.1.06 - 2013-10-19 faster sort? more dyn test.
14+ // 0.1.06 - 2013-10-19 faster sort, dynamic arrays, replaced sorted float array with indirection array
1515//
1616// Released to the public domain
1717//
2121RunningMedian::RunningMedian (uint8_t size)
2222{
2323 _size = constrain (size, MEDIAN_MIN_SIZE, MEDIAN_MAX_SIZE);
24-
24+
2525#ifdef RUNNING_MEDIAN_USE_MALLOC
2626 _ar = (float *) malloc (_size * sizeof (float ));
27- _p = (uint8_t *) malloc (size * sizeof (uint8_t ));
27+ _p = (uint8_t *) malloc (_size * sizeof (uint8_t ));
2828#endif
2929
3030 clear ();
@@ -45,15 +45,16 @@ void RunningMedian::clear()
4545 _idx = 0 ;
4646 _sorted = false ;
4747
48- // for (uint8_t i=0; i< _size; i++) _p[i] = i;
48+ for (uint8_t i=0 ; i< _size; i++) _p[i] = i;
4949}
5050
5151// adds a new value to the data-set
5252// or overwrites the oldest if full.
5353void RunningMedian::add (float value)
5454{
55- _ar[ _idx++] = value ;
55+ _idx++;
5656 if (_idx >= _size) _idx = 0 ; // wrap around
57+ _ar[_idx] = value;
5758 if (_cnt < _size) _cnt++;
5859 _sorted = false ;
5960}
@@ -64,7 +65,6 @@ float RunningMedian::getMedian()
6465 {
6566 if (_sorted == false ) sort ();
6667 return _ar[_p[_cnt/2 ]];
67- // return _as[_cnt/2];
6868 }
6969 return NAN;
7070}
@@ -74,9 +74,8 @@ float RunningMedian::getHighest()
7474{
7575 if (_cnt > 0 )
7676 {
77- if (_sorted == false ) sort ();
77+ if (_sorted == false ) sort (); // assumes other fields are also retrieved otherwise inefficient
7878 return _ar[_p[_cnt-1 ]];
79- // return _as[_cnt-1];
8079 }
8180 return NAN;
8281}
@@ -87,7 +86,6 @@ float RunningMedian::getLowest()
8786 {
8887 if (_sorted == false ) sort ();
8988 return _ar[_p[0 ]];
90- // return _as[0];
9189 }
9290 return NAN;
9391}
@@ -110,9 +108,11 @@ float RunningMedian::getAverage(uint8_t nMedians)
110108 if (_cnt < nMedians) nMedians = _cnt; // when filling the array for first time
111109 uint8_t start = ((_cnt - nMedians)/2 );
112110 uint8_t stop = start + nMedians;
111+
113112 if (_sorted == false ) sort ();
113+
114114 float sum = 0 ;
115- for (uint8_t i = start; i < stop; i++) sum += _ar[_p[i]]; // _as[i];
115+ for (uint8_t i = start; i < stop; i++) sum += _ar[_p[i]];
116116 return sum / nMedians;
117117 }
118118 return NAN;
@@ -125,15 +125,7 @@ uint8_t RunningMedian::getCount() { return _cnt; };
125125
126126void RunningMedian::sort ()
127127{
128- // Serial.print("befor:\t");
129- // for (uint8_t i=0; i< _cnt; i++)
130- // {
131- // Serial.print(_ar[_p[i]]);
132- // Serial.print('\t');
133- // }
134- // Serial.println();
135-
136- // sort all
128+ // bubble sort with flag
137129 for (uint8_t i=0 ; i< _cnt-1 ; i++)
138130 {
139131 bool flag = true ;
@@ -149,53 +141,8 @@ void RunningMedian::sort()
149141 }
150142 if (flag) break ;
151143 }
152-
153- // for (uint8_t i=0; i< _cnt-1; i++)
154- // {
155- // uint8_t m = i;
156- // for (uint8_t j=i+1; j< _cnt; j++)
157- // {
158- // if (_ar[_p[j]] < _ar[_p[m]]) m = j;
159- // }
160- // if ( m != i )
161- // {
162- // uint8_t t = _p[i];
163- // _p[i] = _p[m];
164- // _p[m] = t;
165- // }
166- // }
167-
168- // Serial.print("after:\t");
169- // for (uint8_t i=0; i< _cnt; i++)
170- // {
171- // Serial.print(_ar[_p[i]]);
172- // Serial.print('\t');
173- // }
174- // Serial.println();
144+
175145 _sorted = true ;
176146}
177147
178- // void RunningMedian::sort()
179- // {
180- // // copy
181- // for (uint8_t i=0; i< _cnt; i++) _as[i] = _ar[i];
182-
183- // // sort all
184- // for (uint8_t i=0; i< _cnt-1; i++)
185- // {
186- // uint8_t m = i;
187- // for (uint8_t j=i+1; j< _cnt; j++)
188- // {
189- // if (_as[j] < _as[m]) m = j;
190- // }
191- // if (m != i)
192- // {
193- // float t = _as[m];
194- // _as[m] = _as[i];
195- // _as[i] = t;
196- // }
197- // }
198- // _sorted = true;
199- // }
200-
201148// END OF FILE
0 commit comments