Verify distribution uniformity/Naive: Difference between revisions
Content added Content deleted
Underscore (talk | contribs) (Added Hy.) |
(→{{header|Racket}}: naive test replaces better chi-squared test) |
||
Line 1,044: | Line 1,044: | ||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
{{trans|Tcl}} |
|||
{{incorrect|Racket|Arguments don't fit the task description.}} |
|||
The code below implements a chi-squared test in order to determine |
|||
whether a given source of random numbers produce uniformly distributed |
|||
numbers. |
|||
Returns a pair of a boolean stating uniformity and either the "uniform" distribution or a report of the first skew number found. |
|||
⚫ | |||
#lang racket |
|||
(require |
|||
racket/flonum (planet williams/science:4:5/science) |
|||
(only-in (planet williams/science/unsafe-ops-utils) real->float)) |
|||
⚫ | |||
; (chi^2-goodness-of-fit-test observed expected df) |
|||
(define (pretty-fraction f) |
|||
; Given: observed, a sequence of observed frequencies |
|||
(if (integer? f) f |
|||
; expected, a sequence of expected frequencies |
|||
(let* ((d (denominator f)) (n (numerator f)) (q (quotient n d)) (r (remainder n d))) |
|||
; df, the degrees of freedom |
|||
⚫ | |||
; Result: P-value = 1-chi^2cdf(X^2,df) , the p-value |
|||
(define (chi^2-goodness-of-fit-test observed expected df) |
|||
(define X^2 (for/sum ([o observed] [e expected]) |
|||
⚫ | |||
(- 1.0 (chi-squared-cdf X^2 df))) |
|||
(define (test-uniformity/naive r n δ) |
|||
(define observation (make-hash)) |
|||
(for ((_ (in-range n))) (hash-update! observation (r) add1 0)) |
|||
(define target (/ n (hash-count observation))) |
|||
⚫ | |||
⚫ | |||
(> (abs (- v target)) max-skew)) |
|||
(let/ec ek |
|||
(cons |
|||
#t |
|||
(for/list ((k (sort (hash-keys observation) <))) |
|||
(define v (hash-ref observation k)) |
|||
(when (skewed? v) |
|||
(ek (cons |
|||
#f |
|||
(format "~a distribution of ~s potentially skewed for ~a. expected ~a got ~a" |
|||
'test-uniformity/naive r k (pretty-fraction target) v)))) |
|||
(cons k v))))) |
|||
(define ( |
(define (straight-die) |
||
(min 6 (add1 (random 6)))) |
|||
; Use significance level α to test whether |
|||
; n small random numbers generated by rand |
|||
; have a uniform distribution. |
|||
(define (crooked-die) |
|||
; Observed values: |
|||
( |
(min 6 (add1 (random 7)))) |
||
; generate n random integers from 0 to 9. |
|||
(for ([_ (+ n 1)]) |
|||
⚫ | |||
(vector-set! o r (+ (vector-ref o r) 1))) |
|||
; Expected values: |
|||
⚫ | |||
; Calculate the P-value: |
|||
(define P (chi^2-goodness-of-fit-test o ex (- n 1))) |
|||
; If the P-value is larger than α we accept the |
|||
; hypothesis that the numbers are distributed uniformly. |
|||
(> P α)) |
|||
; Test whether the builtin generator is uniform: |
; Test whether the builtin generator is uniform: |
||
( |
(test-uniformity/naive (curry random 10) 1000 5) |
||
; Test whether |
; Test whether a straight die is uniform: |
||
( |
(test-uniformity/naive straight-die 1000 5) |
||
; Test whether a biased die fails: |
|||
</lang> |
|||
(test-uniformity/naive crooked-die 1000 5)</lang> |
|||
Output: |
|||
<lang racket> |
|||
{{out}} |
|||
#t |
|||
<pre>'(#t (0 . 96) (1 . 100) (2 . 103) (3 . 86) (4 . 94) (5 . 111) (6 . 106) (7 . 99) (8 . 108) (9 . 97)) |
|||
#f |
|||
'(#t (1 . 169) (2 . 185) (3 . 184) (4 . 163) (5 . 144) (6 . 155)) |
|||
</lang> |
|||
'(#f . "test-uniformity/naive distribution of #<procedure:crooked-die> potentially skewed for 6. expected 166 2/3 got 262")</pre> |
|||
=={{header|REXX}}== |
=={{header|REXX}}== |