/*
* test_random_binomial.sli
*
* This file is part of NEST.
*
* Copyright (C) 2004 The NEST Initiative
*
* NEST is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* NEST is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NEST. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* BeginDocumentation
Name: testsuite::test_random_binomial - test of binomial random deviates
Synopsis: (test_random_binomial) run -> compare binomial random numbers with desired distribution.
Description:
Kolmogorov-Smirnov test of binomial random deviate generator.
This test performs a Kolmogorov-Smirnov test of the random numbers generated
by the binomial random deviate generator. It draws realizations and compares
the observed cumulative distribution function against the theoretical one.
Remarks:
The test was implemented following
http://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Smirnov_test
Author: July 2011, Moritz Deger
SeeAlso: rdevdict::binomial
*/
/unittest (6688) require
/unittest using
% The factorial is needed to compute the binomial coefficients that occur
% in the probability mass function.
% Direct computation of factorial. If n exceeds 12, integer values can
% not represent the number. This makes the test fail.
/factorial{
dup 12 leq assert_or_die
/x Set 1 /ret Set
{x 1 lt {exit} if
x ret mul /ret Set
x 1 sub /x Set } loop
ret
} def
% binomial prob of (k, p, n), k out of n with prob p
/binomialprob{ /n Set /p Set /k Set
n factorial k factorial n k sub factorial mul cvd div %binomial coefficient
p k pow mul
1 p sub n k sub pow mul
} def
% binomial CDF of (k, p, n), k out of n with prob p
/binomialcdf{
/n Set /p Set /kl Set
0.0 /res Set
0 /cou Set
{cou kl gt {exit} if % check if counter > k, exit if true
cou p n binomialprob res add /res Set % add probability of stack to return value
cou 1 add /cou Set % increment the counter
} loop
res % return res
} def
% estimate CDF of observed data
/observedcdf{
/data Set
1 add /kp1 Set
0 /cdfcount Set
data { kp1 lt {cdfcount 1 add /cdfcount Set} if } forall
cdfcount data length_a cvd div
} def
% compute kalpha to compare against
% python code to get value:
% import scipy.stats
% import scipy.optimize
% alpha = 0.05
% kalpha = scipy.optimize.fmin( lambda x: abs(1-alpha-scipy.stats.ksprob(x)), 1)
0.51962891 /kalpha Set
% actual test, seed as argument
% n should not exceed 12 because then factorial fails
/testbino{
% get seeded random deviate generator
/seedn Set
/n Set
/p Set
10000 /nsample Set
rngdict /MT19937 get seedn CreateRNG /rng Set
rng rdevdict /binomial get CreateRDV /bino Set
% set parameters and draw random numbers
bino << /p p /n n >> SetStatus
bino nsample RandomArray /data Set
% test the realizations against the theorical distribution
0.0 /teststat Set
0
{
dup n gt {exit} if % check if stack > n, exit if true
dup dup data observedcdf % 2x counter and observed CDF value on stack
exch p n binomialcdf % counter, obs. and theoretical CDF on stack
% compute difference of obs. and theo., memorize only if larger than old value.
sub dup abs teststat geq {/teststat Set} {pop} ifelse
1 add % increment stack counter
} loop
% test result (supremum of errors against kolmogorov distribution)
n sqrt teststat mul kalpha leq assert_or_die
} def
% run the test with several seeds, n and p
0.2 12 11652 testbino
0.1 8 7562 testbino
0.7 11 8766576 testbino