I need to find the median of a 64 element unsigned int array. I would use qsort() but my Keil compiler doesn't support it. I'm using the small model so the algorithm should be non-recursive. Just to make it interesting I have less than 500 microseconds to do the calc on a 25 MHz Silabs C8051F410.
The data is obtained sequentially from a ADC so that it may be possible to do some of the calculation while the ADC is still working.
I would welcome any suggestions/code etc.
Arthur
Didn't find your answer? Ask the community — no account required.
M
Mark McDougall
How much time between each of the 64 ADC acquisitions?
I'm thinking linked-list implementation (using static array) as each value is acquired...
Regards,
Mark McDougall, Engineer
Virtual Logic Pty Ltd,
21-25 King St, Rockdale, 2216
Ph: +612-9599-3255 Fax: +612-9599-3266
P
Peter Harrison
This seems to have a reasonable discussion and code samples:
formatting link
Pete Harrison
R
Rene Tschaggelar
Median means you sort a number of samples and take the middle one. It cannot be too difficult to implement that functionality by yourself.
What do you mean the Keil compiler doesn't support it?
Is this home work?
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills Staffs England /\/\/\/\/
/\/\/ chris@phaedsys.org www.phaedsys.org \/\/\
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
M
Mark McDougall
Nice resource... filed for future reference... ;)
Regards,
Mark McDougall, Engineer
Virtual Logic Pty Ltd,
21-25 King St, Rockdale, 2216
Ph: +612-9599-3255 Fax: +612-9599-3266
P
Paul Carpenter
Possibly look at smaller sorts of sections using the top 'n' bits of the data as a hashing table to specify your sections. This is best done with some link lists, but may end up using more data storage of byte size. The hashing table may be using 4 bits of the data if twelve bit ADC, so you only actually store the bottom 8 bits directly. Even a bubble sort of each index table (upto 64 values for each) on index to byte data may be fast, but puts in a level of indirection.
With only 64 items you could possibly just use a bubble sort as each value comes in, and start by putting the values in at the middle of the array. Potential for moving blocks of the array (or indecii/link list) when bounds reached. Basically filling from the middle may save time. However needs to keep track of current lowest and highest filled positions, which is still only byte information.
Paul Carpenter | paul@pcserviceselectronics.co.uk
PC Services
GNU H8 & mailing list info
For those web sites you hate
C
CBFalconer
That can be O(n). Just write your own. I assume the Keil beast doesn't support real C, since qsort is a part of the library. It lives in stdlib.h.
cbfalconer at maineline dot net
N
nospam
If you only want the median you don't have to store 64 elements. You only need to keep the lowest (or highest) 32 (or 31 depending on your definition of the median of an even number of elements).
Store the first 32 (or 31) conversions in an array. The next 32 (or 33) conversions search the array for the highest value and replace it with the current conversion if it is lower. At the end the highest value in the array is the median.
A
Arthur Richards
There is approximately 10 microsec between conversions - say 100 assembler instructions
A
Arthur Richards
Thanks,
I will try the Wirth algorithm and see how long it takes!
A
Arthur Richards
Sounds like a good idea. I will try the brute force kth_element approach first and if (or when) it takes too long this is certainly a worthwhile approach. It seems that for a small array a shell or bubble sort may be faster than a quicksort anyway. Your idea should utilize some of the wasted time while the conversions are proceeding.
Thanks, Arthur
A
Arthur Richards
I guess they omitted it because it is normally recursive and this doesn't suit the 8051 except perhaps with the LARGE model.
A
Arthur Richards
An interesting idea. I will certainly pursue this if my shellsort & kth element algorithms run out of time.
Thanks, Arthur
C
CBFalconer
... snip ...
I don't believe you can sort during input, since your input is an external and you need to keep an input queue. If you use a sort you will have to copy the queue to a sortable array. See Sedgewicks "Algorithms" for a quick modification of quicksort for median extraction. I don't know if you have to keep track during the initial build-up of the queue. Bubble sort is about the slowest means of processing.
cbfalconer at maineline dot net
H
Hans-Bernhard Bröker
... for a _hosted_ implementation of C, that is. But not for a freestanding one, which a lot of embedded work obviously is. Keil does support as much "real" C as a 8051 can usefully handle, but they know better than to try to offer a full, hosted implementation.
N
Neil
Try an Insertion Sort Then you can make use of the ADC Conversion Time
N
Newman
Interesting observation NoSpam, sounds correct.
Finding the max would be O(N/2xN/2) not bad It could be that finding the max could be tightly coded via inline coding with constant indexes for the compare operations from the array. The data sheet said that 70% of the instructions execute in 1-2 clock cycles
125 to 250 operations in the 10us sample interval with 25 MHz clock. Maybe could perform each iteration of find max O(64/2) within the sample period. Of course there are other considerations. Just thinking...
Nice post IMHO.
Newman
J
Jonathan Kirwan
It doesn't need to be recursive. One can simply stack one branch's indices and work the other side. The stack can be implemented without relying upon recursive calls, which is the real reason recursion is used in qsort -- as a handy, but expensive means of stacking a branch's span.
Jon
Join the Discussion
Have something to add? Share your thoughts — no account required.
Didn't find your answer?
Ask the community — no account required
Report Content
You are reporting this content to the moderators. They will look at it
ASAP.