Number Sort Algorithm


Closed Thread
Results 1 to 40 of 55

Hybrid View

  1. #1
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default

    Hi Darrel, I tested the sorting snippet you have posted, using a rather interesting swapping technique.

    The code worked, but now and than, it was yielding very fanny results.

    From a closer code analysis, I came to the conclusion that :

    Code:
    If CounterA > 0 then CounterA=CounterA-2
    should be corrected with:

    Code:
    If CounterA > 1 then CounterA=CounterA-2
    After the correction, I didn't see any fanny result for the rest of my testing period.

    The explanation I have given is the following:

    If CounterA = 1 then CounterA - 2 = 255 and this screw up everything.

    Can you confirm?

    Al.
    Last edited by aratti; - 19th December 2009 at 18:14.
    All progress began with an idea

  2. #2
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by aratti View Post
    Hi Darrel, I tested the sorting snippet you have posted, using a rather interesting swapping technique.
    The code worked, but now and than, it was yielding very fanny results.
    From a closer code analysis, I came to the conclusion that :
    Code:
    If CounterA > 0 then CounterA=CounterA-2
    should be corrected with:
    Code:
    If CounterA > 1 then CounterA=CounterA-2
    After the correction, I didn't see any fanny result for the rest of my testing period.
    The explanation I have given is the following:

    If CounterA = 1 then CounterA - 2 = 255 and this screw up everything.

    Can you confirm?

    Al.
    Well, I wouldn't think it's a problem.
    Right after the IF block that statement is in, Melanie put a ...

    CounterA=CounterA+1

    So if CounterA = 1, subtracting 2 makes it 255, then adding 1 makes it 0 again.

    Had you made any other changes?
    <br>
    DT

  3. #3
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default

    Had you made any other changes?
    Yes, a second one, but more for cleaning the code, since it didn't effect functionality:

    Code:
    RawData(CounterA+1+0) = RawData(CounterA) ^ RawData(CounterA+1)
    Has been cleaned with:

    Code:
    RawData(CounterA+1) = RawData(CounterA) ^ RawData(CounterA+1)

    Well, I wouldn't think it's a problem.
    Right after the IF block that statement is in, Melanie put a ...

    CounterA=CounterA+1

    So if CounterA = 1, subtracting 2 makes it 255, then adding 1 makes it 0 again
    But the above make sense, I do better check the whole system again.

    Thank you Darrel.

    Al.
    Last edited by aratti; - 19th December 2009 at 20:16.
    All progress began with an idea

  4. #4
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default fleshing out the sort

    WOW, must be a good day!
    I remembered Melanie had a comment on sorting out changing inputs, but I couldn't find my bookmark for it. I went to the main forum page and there it was on the right column!
    Whew! someone must be looking out for me....

    My situation involves reading WORD sized data every 30ms (with quite a few spurious readings) and controlling a PWM output with somewhere near a 2-3 second response to drive some mechanicals that require slow reaction. I have been trying to mold Darrel's DT_Average16 routine to make it work, but with little success in this application.

    Can someone elaborate a bit on feeding fresh data into this sort and trimming the top and bottom readings? I don't understand how to run this with a continuous data stream without blowing up the sort.

    Thanks
    Bo

  5. #5
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default

    Here is what I have come up with so far.....
    it is getting closer.
    Derived from Malanie's suggestion about parsing data and DT's averaging scheme * PIC18F2525 @ 8 MHz
    Code:
    ByteData var byte                                                                                                      
    CounterA    var word             ' sort counter
    CounterB    var byte
    CounterC    var byte
    DataA       var word             ' storage for sorted values
    DatSort     var byte             ' pointer to middle 8 values
    DatAvg      var word             ' averaged value of sorted data
    RawData     var word[16]         ' storage for raw data
    Clear
    AvgCount	CON  8		         ' = Number of samples to average
    FAspread	CON  1000	         ' = Fast Average threshold +/-
    INCLUDE "AllDigital.pbp"
    DEFINE OSC 8
    OSCCON = %01110000
    DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
    DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
    DEFINE HSER_CLROERR 1 ' Clear overflow automatically
    DEFINE HSER_SPBRG 34  ' 57600 Baud @ 8MHz, -0.79%
    SPBRGH = 0
    BAUDCON.3 = 1         ' Enable 16 bit baudrate generator
    
    hserout["SortAverage",10,13]
    pause 500
    goto Start
    
    'Sort Array SUB ** collects 16 readings, sorts, and averages middle 8 ******
    SortArray:
        CounterA=0
    SortLoop:                          ' sorts 16 readings of RawData in order
        If RawData(CounterA+1) < RawData(CounterA) then
            DataA=RawData(CounterA)
            RawData(CounterA)=RawData(CounterA+1)
            RawData(CounterA+1+0)=DataA
            If CounterA > 0 then CounterA=CounterA-2
            endif
        CounterA=CounterA+1
        If CounterA < 15 then goto SortLoop
    '    for CounterC = 0 to 15        ' These three lines O/P the sort results
    '    hserout["Ordered[",dec CounterC,"]= ", dec RawData[CounterC],10,13] 
    '    next CounterC
    '**** Trim and Average ***************************************************
       for DatSort = 4 to 11                    ' pick out middle 8 readings
        IF ABS (DatAvg - RawData[DatSort]) > FAspread Then CatchUp
        IF ABS (DatAvg - RawData[DatSort]) < AvgCount Then RealClose
        DatAvg = DatAvg - (DatAvg/AvgCount)
        DatAvg = DatAvg + (RawData[DatSort]/AvgCount)
        GoTo AVGok
      CatchUp:
        DatAvg = DatAvg + (RawData[DatSort]/8)  ' catch-up by 1/8 value of reading
        GoTo AVGok
      RealClose:
        DatAvg = DatAvg - (RawData[DatSort]/(AvgCount/4))
        DatAvg = DatAvg + (DatAvg/(AvgCount/4))
      AVGok:
    ' hserout["Middle[",dec datsort,"] = ",dec RawData[DatSort],10,13] 'SHOW mid 8
       next DatSort
        Return  
    '** END SUB************************
    Start:
          FOR CounterB=0 to 15
         HSERIN [RawData[CounterB]]
          NEXT CounterB      
          FOR CounterB=0 to 15
          HSEROUT["RawData[",DEC counterB,"] = ",DEC rawdata[CounterB],10,13]
          NEXT CounterB
          CALL SortArray
          HSEROUT ["Sorted Averaged result ",dec DatAvg,10,13]
         GOTO start

  6. #6
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default

    Code:
    for DatSort = 4 to 11                    ' pick out middle 8 readings
     DatAvg = DatAvg + RawData[DatSort]
    NEXT DatSort
    
    DatAvg = DatAvg >>3
    Return
    You can short and semplify your averaging routine with the above example. DatAvg sums up the 8 central values then you devide by 8 for the average.

    Al.
    All progress began with an idea

  7. #7
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default

    Hi Al. Thanks for looking at it.

    I like the way you simplified, but my concern was that since I will be working with WORD data, the result of the addition could get big enough that I would have to use LONGs if I didn't use DT's running average scheme.

    So far, I have only tested it with byte data, and it does seem to settle slowly on something close to average. I need to try WORD data and see how that works.

    Bo

Similar Threads

  1. Dynamic USB Serial Number (PIC18F4550)
    By awmt102 in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 16th July 2009, 18:03
  2. Working with the random number generator
    By kwelna in forum mel PIC BASIC
    Replies: 9
    Last Post: - 16th January 2007, 18:50
  3. Random number results
    By bartman in forum mel PIC BASIC
    Replies: 3
    Last Post: - 9th March 2005, 18:39
  4. more random number questions
    By bartman in forum mel PIC BASIC
    Replies: 1
    Last Post: - 14th November 2004, 18:55
  5. Split number into variables
    By psmeets in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 7th January 2004, 05:15

Members who have read this thread : 2

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts