Jump to content

_ArraySort gives ByRef Error


Recommended Posts

I'm trying to write a function that takes a 2D Array and a certain Index to calculate a median of that index

Func _ArrayMedian ($vaArray, $viIndex)
    ; Returns the median of the column of data asked for
    ; Assumes Array sends array dimentions in [0][0] = Rows [0][1] = Columns
    Local $X                                            ; Counter
    Local $vsSum                                        ; Sum of data
    _ArraySort(0, 0, 1, $viIndex)                   ; Sort Array by the index
    If $vaArray[0][0] = 0 Then                          ; Array empty
        Return 0
    ElseIf Mod($vaArray[0][0], 2) = 0 Then                  ; Array has even number
        Return ($vaArray[int(($vaArray[0][0] / 2))][$viIndex] + $vaArray[int($vaArray[0][0] / 2) + 1]][$viIndex) / 2
    Else                                                ; Array has odd number
        Return $vaArray[int($vaArray[0][0] / 2) + 1][$viIndex]
    EndIf
EndFunc

When I do a Syntex check  I get the error

"error: _ArraySort() called with Const or expression on ByRef-param(s)" when I call the _ArraySort() function.

I guess I don't understand what ByRef means so have no idea how to pass my $viIndex value through the function so it looks at the right column. Anyone able to educate me on this?

Thanks

 

Link to comment
Share on other sites

  • 3 years later...
15 hours ago, GeorgeP said:

this short function got me sorted in no time

The methodology here is still far away from "in no time".
It is not necessary to sort the array completely to calculate the median.
The array only has to be divided step by step into elements larger or smaller than a certain value and if these sub-ranges are treated step by step in the same way, the element in the middle is available at the end. (= "quick select" algorithm)
This way you can calculate the median much faster.

Example script (the required UDF is in the appendix):

#include "Stat_ListFunctions.au3"

; row size of array:
Global Const $N = 1e4 + 1
Global Const $C = 5

; create sample array:
Global $aArray[$N][$C]

For $i = 0 To $N -1
    ; fill only one column with sample data
    $aArray[$i][2] = Random(0, $N, 1)
Next

; copy sample array:
$aArray2 = $aArray

; first method: full sort:
$tTimer = TimerInit()
$iMedian = _Median2DbySorting($aArray, 2)
ConsoleWrite(StringFormat("method:\t%s\nmedian:\t%d\ntime:\t%.1f ms\n\n", "Full sort of array", $iMedian, TimerDiff($tTimer)))

; second method: partition of array
$tTimer = TimerInit()
$iMedian = _Median2DbyPartition($aArray2, 2)
ConsoleWrite(StringFormat("method:\t%s\nmedian:\t%d\ntime:\t%.1f ms\n\n", "partition of array", $iMedian, TimerDiff($tTimer)))


; calculate the median of a column of a 2D-Array by sorting it
Func _Median2DbySorting(ByRef $aArray, $iCol)
    Local Const $N = UBound($aArray)

    _ArraySort($aArray, 0, 0, 0, $iCol)

    Return Mod($N, 2) = 0 ? _
        ($aArray[Int($N/2)][$iCol] + $aArray[Int($N/2) + 1][$iCol]) / 2 : _
        $aArray[Int($N/2)][$iCol]
EndFunc

; extract the column and calculate the median by partition
Func _Median2DbyPartition(ByRef $aArray, $iCol)
    Local Const $N = UBound($aArray)
    Local $aTmp[$N]
    For $i = 0 To $N - 1
        $aTmp[$i] = $aArray[$i][$iCol]
    Next
    Return _stat_Median($aTmp)
EndFunc


produces the following output:

Quote

method:    Full sort of array
median:    5018
time:    1552.1 ms

method:    partition of array
median:    5018
time:    77.2 ms

 

Stat-UDF.zip

Link to comment
Share on other sites

On 8/30/2021 at 8:23 AM, AspirinJunkie said:

The methodology here is still far away from "in no time".

Then again, his “in no time” would appear to relate to his own time sorting out of the problem, not necessarily CPU cycles.

Still, instructive work!

Code hard, but don’t hard code...

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...