Verify distribution uniformity/Naive: Difference between revisions

→‎{{header|Racket}}: naive test replaces better chi-squared test
(Added Hy.)
(→‎{{header|Racket}}: naive test replaces better chi-squared test)
Line 1,044:
 
=={{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>
#lang racket
(require
racket/flonum (planet williams/science:4:5/science)
(only-in (planet williams/science/unsafe-ops-utils) real->float))
 
<lang racket>#lang racket
; (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
(format "~a ~a" q (/ (sqrr (- o ed)) e)))
; 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])
(/ (sqr (- o e)) e)))
(- 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)))
(define ex (makemax-vector 10skew (/* n 10)δ 1/100))
(define r (randskewed? 10)v)
(> (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 (isstraight-uniform? rand n α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:
(definemin o6 (make-vectoradd1 10(random 07))))
; generate n random integers from 0 to 9.
(for ([_ (+ n 1)])
(define r (rand 10))
(vector-set! o r (+ (vector-ref o r) 1)))
; Expected values:
(define ex (make-vector 10 (/ n 10)))
 
; 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:
(istest-uniform?uniformity/naive (curry random 10) 1000 0.055)
; Test whether thea constantstraight generatordie failsis uniform:
(istest-uniform?uniformity/naive (λ(_) 5)straight-die 1000 0.055)
; 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}}==
569

edits