Exceptional Averages

Counting up numbers into an Average takes time, but recently I developed a method of doing this without using a loop. Essentially once the Pile of numbers is full, we need to remove the oldest number from the Pile and add the new one.

Also, if you’re tracking over a long period of time, you want it to be accurate from the beginning. The JEOZ.Average Structure solves those issues.

The Average.Smooth Field is a GoNumber that helps even out the Average Value. When displaying numbers on screen it’s hard to follow if they move too quickly.

Public Structure Average
    Public Pile() As Single
    Public Average As Single
    Public Digits, Total As Integer
    Public Smooth As GoNumber
    Public SmoothSpeed As Single
    Private Index, NextIndex, Count, Available As Integer
    Private Sum As Single

    Public Sub New(_Count As Integer, Optional _Digits As Integer = 1,
                   Optional _Smooth As Single = 0.1)
        Setup(_Count, _Digits)
    End Sub
    Public Sub Setup(_Count As Integer, Optional _Digits As Integer = 1,
                     Optional _Smooth As Single = 0.1)
        Digits = _Digits
        Count = _Count - 1
        SmoothSpeed = _Smooth
        ReDim Numbers(Count)
        Smooth = New GoNumber(0)
    End Sub

    Public ReadOnly Property Value As Single
            Return Math.Round(Smooth.Now, Digits)
        End Get
    End Property

    Public Overrides Function ToString() As String
        Return Math.Round(Smooth.Now, Digits)
    End Function

Use the AddValue Function on each Frame of the GameLoop to add another value to the Pile.

    Public Sub AddValue(Value As Single)
        Total += Value
        '// Increase NextIndex until Count, then wrap to 0. In other words,
        '// "If NextIndex = Count Then NextIndex = 0 Else NextIndex += 1"
        NextIndex = If(NextIndex = Count, 0, NextIndex + 1)
        '// Remove previous value at the current index, because this index
        '// will be the oldest value, which is 0 if this is the first time.
        Sum -= Pile(NextIndex)
        '// Store Current Value into the Pile
        Pile(Index) = Value
        '// Move the Index forward
        Index = NextIndex
        '// Increase Available until we reach total Count
        '// to make the Average accurate from the start
        Available += If(Available <= Count, 1, 0)
        '// Add the new Value to the Sum Total
        Sum += Value
        '// Calculate the new Average
        Average = Sum / Available
        '// Set the Smooth GoNumber to follow the Average
        Smooth.Go = Average
    End Sub
End Structure

Use the [Average].Average Field to get the exact state, or the [Average].Value Property to Get the value Smoothed out over time.

MyBBXP is having trouble with the MyBB database connection, perhaps re-check your settings