diff --git a/libraries/RunningMedian/RunningMedian.cpp b/libraries/RunningMedian/RunningMedian.cpp index c8c4c143..a0526d89 100644 --- a/libraries/RunningMedian/RunningMedian.cpp +++ b/libraries/RunningMedian/RunningMedian.cpp @@ -1,7 +1,7 @@ // // FILE: RunningMedian.cpp // AUTHOR: Rob dot Tillaart at gmail dot com -// VERSION: 0.1.07 +// VERSION: 0.1.08 // PURPOSE: RunningMedian library for Arduino // // HISTORY: @@ -13,6 +13,7 @@ // 0.1.05 - 2013-10-18 fixed bug in sort; removes default constructor; dynamic memory // 0.1.06 - 2013-10-19 faster sort, dynamic arrays, replaced sorted float array with indirection array // 0.1.07 - 2013-10-19 add correct median if _cnt is even. +// 0.1.08 - 2013-10-20 add getElement(), add getSottedElement() add predict() // // Released to the public domain // @@ -71,25 +72,9 @@ float RunningMedian::getMedian() } #ifdef RUNNING_MEDIAN_ALL -float RunningMedian::getHighest() -{ - if (_cnt > 0) - { - if (_sorted == false) sort(); // assumes other fields are also retrieved otherwise inefficient - return _ar[_p[_cnt-1]]; - } - return NAN; -} +float RunningMedian::getHighest() { return getSortedElement(_cnt-1); } -float RunningMedian::getLowest() -{ - if (_cnt > 0) - { - if (_sorted == false) sort(); - return _ar[_p[0]]; - } - return NAN; -} +float RunningMedian::getLowest() { return getSortedElement(0); } float RunningMedian::getAverage() { @@ -119,6 +104,44 @@ float RunningMedian::getAverage(uint8_t nMedians) return NAN; } +float RunningMedian::getElement(uint8_t n) +{ + if ((_cnt > 0) && (n < _cnt)) + { + return _ar[n]; + } + return NAN; +} + +float RunningMedian::getSortedElement(uint8_t n) +{ + if ((_cnt > 0) && (n < _cnt)) + { + if (_sorted == false) sort(); + return _ar[_p[n]]; + } + return NAN; +} + +float RunningMedian::predict(uint8_t n) +{ + if ((_cnt > 0) && (n < _cnt/2)) + { + float med = getMedian(); // takes care of sorting ! + if (_cnt & 0x01) + { + return max(med - _ar[_p[_cnt/2-n]], _ar[_p[_cnt/2+n]] - med); + } + else + { + float f1 = (_ar[_p[_cnt/2 - n]] + _ar[_p[_cnt/2 - n - 1]])/2; + float f2 = (_ar[_p[_cnt/2 + n]] + _ar[_p[_cnt/2 + n - 1]])/2; + return max(med - f1, f2 - med)/2; + } + } + return NAN; +} + uint8_t RunningMedian::getSize() { return _size; }; uint8_t RunningMedian::getCount() { return _cnt; }; diff --git a/libraries/RunningMedian/RunningMedian.h b/libraries/RunningMedian/RunningMedian.h index 566159ed..fc08d080 100644 --- a/libraries/RunningMedian/RunningMedian.h +++ b/libraries/RunningMedian/RunningMedian.h @@ -4,7 +4,7 @@ // FILE: RunningMedian.h // AUTHOR: Rob dot Tillaart at gmail dot com // PURPOSE: RunningMedian library for Arduino -// VERSION: 0.1.07 +// VERSION: 0.1.08 // URL: http://arduino.cc/playground/Main/RunningMedian // HISTORY: See RunningMedian.cpp // @@ -53,6 +53,10 @@ public: float getHighest(); // returns highest element float getLowest(); // return lowest element + float getElement(uint8_t n); // get n'th element from the values in time order + float getSortedElement(uint8_t n); // get n'th element from the values in size order + float predict(uint8_t n); // predict the max change of median after n additions + uint8_t getSize(); // returns size of internal buffer uint8_t getCount(); // returns current used elements, getCount() <= getSize() #endif diff --git a/libraries/RunningMedian/examples/RunningMedian2/RunningMedian2.ino b/libraries/RunningMedian/examples/RunningMedian2/RunningMedian2.ino index bdc34afd..a347459c 100644 --- a/libraries/RunningMedian/examples/RunningMedian2/RunningMedian2.ino +++ b/libraries/RunningMedian/examples/RunningMedian2/RunningMedian2.ino @@ -11,7 +11,7 @@ #include "RunningMedian.h" -RunningMedian samples = RunningMedian(7); +RunningMedian samples = RunningMedian(100); long count = 0; @@ -29,7 +29,7 @@ void loop() void test1() { - if (count % 20 == 0) Serial.println(F("\nmsec \tAnR \tSize \tCnt \tLow \tAvg \tAvg(7) \tAvg(3) \tMed \tHigh")); + if (count % 20 == 0) Serial.println(F("\nmsec \tAnR \tSize \tCnt \tLow \tAvg \tAvg(7) \tAvg(3) \tMed \tHigh \tPre(1) \tPre(2)")); count++; long x = analogRead(A0); @@ -44,6 +44,8 @@ void test1() float h = samples.getHighest(); int s = samples.getSize(); int c = samples.getCount(); + float p1 = samples.predict(1); + float p2 = samples.predict(2); Serial.print(millis()); Serial.print('\t'); @@ -63,7 +65,12 @@ void test1() Serial.print('\t'); Serial.print(m); Serial.print('\t'); - Serial.println(h); + Serial.print(h); + Serial.print('\t'); + Serial.print(p1, 2); + Serial.print('\t'); + Serial.println(p2, 2); + delay(100); } diff --git a/libraries/RunningMedian/keywords.txt b/libraries/RunningMedian/keywords.txt index e508e679..8859893d 100644 --- a/libraries/RunningMedian/keywords.txt +++ b/libraries/RunningMedian/keywords.txt @@ -21,6 +21,9 @@ getHighest KEYWORD2 getLowest KEYWORD2 getSize KEYWORD2 getCount KEYWORD2 +getElement KEYWORD2 +getSortedElement KEYWORD2 +predict KEYWORD2 getStatus KEYWORD2 #######################################