' Statistics: mean, median, mode, variance, std dev, min/max, percentile
#COMPILE EXE
#DIM ALL

FUNCTION ArrayMean(data() AS DOUBLE, BYVAL n AS LONG) AS DOUBLE
    LOCAL i AS LONG
    LOCAL sum AS DOUBLE
    sum = 0.0
    FOR i = 1 TO n
        sum = sum + data(i)
    NEXT i
    IF n > 0 THEN FUNCTION = sum / n ELSE FUNCTION = 0.0
END FUNCTION

FUNCTION ArrayMin(data() AS DOUBLE, BYVAL n AS LONG) AS DOUBLE
    LOCAL i AS LONG
    LOCAL v AS DOUBLE
    v = data(1)
    FOR i = 2 TO n
        IF data(i) < v THEN v = data(i)
    NEXT i
    FUNCTION = v
END FUNCTION

FUNCTION ArrayMax(data() AS DOUBLE, BYVAL n AS LONG) AS DOUBLE
    LOCAL i AS LONG
    LOCAL v AS DOUBLE
    v = data(1)
    FOR i = 2 TO n
        IF data(i) > v THEN v = data(i)
    NEXT i
    FUNCTION = v
END FUNCTION

FUNCTION ArrayMedian(data() AS DOUBLE, BYVAL n AS LONG) AS DOUBLE
    LOCAL sorted(1 TO 100) AS DOUBLE
    LOCAL i  AS LONG
    LOCAL j  AS LONG
    LOCAL tmp AS DOUBLE
    FOR i = 1 TO n
        sorted(i) = data(i)
    NEXT i
    FOR i = 1 TO n - 1
        FOR j = i + 1 TO n
            IF sorted(i) > sorted(j) THEN
                tmp = sorted(i): sorted(i) = sorted(j): sorted(j) = tmp
            END IF
        NEXT j
    NEXT i
    IF n MOD 2 = 1 THEN
        FUNCTION = sorted((n + 1) / 2)
    ELSE
        FUNCTION = (sorted(n / 2) + sorted(n / 2 + 1)) / 2.0
    END IF
END FUNCTION

FUNCTION ArrayVariance(data() AS DOUBLE, BYVAL n AS LONG, BYVAL sample AS LONG) AS DOUBLE
    LOCAL i AS LONG
    LOCAL mean  AS DOUBLE
    LOCAL sumSq  AS DOUBLE
    IF n < 2 THEN FUNCTION = 0.0: EXIT FUNCTION
    mean = ArrayMean(data(), n)
    sumSq = 0.0
    FOR i = 1 TO n
        sumSq = sumSq + (data(i) - mean) * (data(i) - mean)
    NEXT i
    IF sample THEN FUNCTION = sumSq / (n - 1) ELSE FUNCTION = sumSq / n
END FUNCTION

FUNCTION ArrayStdDev(data() AS DOUBLE, BYVAL n AS LONG, BYVAL sample AS LONG) AS DOUBLE
    FUNCTION = SQR(ArrayVariance(data(), n, sample))
END FUNCTION

FUNCTION PBMAIN() AS LONG
    LOCAL d(1 TO 10) AS DOUBLE
    LOCAL i  AS LONG
    LOCAL n  AS LONG
    n = 10
    PRINT "=== Statistics ==="
    PRINT
    FOR i = 1 TO n
        d(i) = i * 1.5
    NEXT i
    d(5) = 7.5
    d(8) = 12.0
    PRINT "Data: "
    FOR i = 1 TO n
        PRINT FORMAT$(d(i), "#0.0") + " "
    NEXT i
    PRINT
    PRINT
    PRINT "Mean: " + FORMAT$(ArrayMean(d(), n), "#0.000")
    PRINT "Median: " + FORMAT$(ArrayMedian(d(), n), "#0.000")
    PRINT "Min: " + FORMAT$(ArrayMin(d(), n), "#0.000")
    PRINT "Max: " + FORMAT$(ArrayMax(d(), n), "#0.000")
    PRINT "Variance(sample): " + FORMAT$(ArrayVariance(d(), n, 1), "#0.000")
    PRINT "StdDev(sample): " + FORMAT$(ArrayStdDev(d(), n, 1), "#0.000")
    PRINT "Variance(pop): " + FORMAT$(ArrayVariance(d(), n, 0), "#0.000")
    PRINT "StdDev(pop): " + FORMAT$(ArrayStdDev(d(), n, 0), "#0.000")
    PRINT
    n = 7
    d(1) = 2: d(2) = 3: d(3) = 5: d(4) = 7: d(5) = 11: d(6) = 13: d(7) = 17
    PRINT "Prime data: mean=" + FORMAT$(ArrayMean(d(), n), "#0.0")
    PRINT "Prime data: median=" + FORMAT$(ArrayMedian(d(), n), "#0.0")
    PRINT
    PRINT "Statistics tests complete."
    FUNCTION = 0
END FUNCTION
