## -*- tcl -*- # Tests for the PRNG procedures -*- tcl -*- # # This file contains a collection of tests for one or more of the Tcllib # procedures. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # $Id: random.test,v 1.1 2011/06/17 06:40:14 arjenmarkus Exp $ # # Copyright (c) 2011 by Arjen Markus # All rights reserved. # # ------------------------------------------------------------------------- source [file join \ [file dirname [file dirname [file join [pwd] [info script]]]] \ devtools testutilities.tcl] testsNeedTcl 8.4 testsNeedTcltest 2.1 #support { # useLocal random.tcl simulation::random #} testing { useLocal random.tcl simulation::random } # ------------------------------------------------------------------------- # # As the values were given with four digits, an absolute # error is most appropriate # proc matchNumbers {expected actual} { set match 1 foreach a $actual e $expected { if {abs($a-$e) > 0.1e-4} { set match 0 break } } return $match } customMatch numbers matchNumbers # ------------------------------------------------------------------------- test "Bernoulli-1.0" "Bernoulli generator with p=0" \ -body { set p [::simulation::random::prng_Bernoulli 0.0] set count 0 for {set i 0} {$i < 1000} {incr i} { set rnd [$p] if { $rnd > 0.0 } { incr count } } set count } -result 0 test "Bernoulli-1.1" "Bernoulli generator with p=1" \ -body { set p [::simulation::random::prng_Bernoulli 1.0] set count 0 for {set i 0} {$i < 1000} {incr i} { set rnd [$p] if { $rnd > 0.0 } { incr count } } set count } -result 1000 test "Uniform-1.0" "Uniform generator with number between -1.0 and 1.0" \ -body { set p [::simulation::random::prng_Uniform -1.0 1.0] set nearminus1 0 set nearplus1 0 set outside 0 for {set i 0} {$i < 1000} {incr i} { set rnd [$p] if { $rnd > 0.9 } { incr nearplus1 } if { $rnd < -0.9 } { incr nearminus1 } if { $rnd < -1.0 || $rnd > 1.0 } { incr outside } } # # It is very unlikely that all 1000 numbers stay within the range -0.9 -- 0.9 # set result [expr {$nearplus1 > 0 && $nearminus1 > 0 && $outside == 0}] } -result 1 test "Exponential-1.0" "Exponential generator with minimum -1.0 and mean 1" \ -body { set p [::simulation::random::prng_Exponential -1.0 1.0] set outside 0 set mean 0.0 for {set i 0} {$i < 1000} {incr i} { set rnd [$p] if { $rnd < -1.0 } { incr outside } set mean [expr {$mean + $rnd}] } set mean [expr {$mean / 1000.0}] # # We use a rough estimate for the deviation in the mean # set result [expr {$outside == 0 && abs($mean - 1.0) < 0.5}] } -result 1 test "Discrete-1.0" "Discrete generator with numbers 0, 1, 2 and 3" \ -body { set p [::simulation::random::prng_Discrete 4] set outside 0 for {set i 0} {$i < 1000} {incr i} { set rnd [$p] switch -- $rnd { 0 - 1 - 2 - 3 { # Nothing to do } default { incr outside } } } set result [expr {$outside == 0}] } -result 1 test "Poisson-1.0" "Poisson generator with mean 10" \ -body { set p [::simulation::random::prng_Poisson 10] set noninteger 0 set mean 0.0 for {set i 0} {$i < 1000} {incr i} { set rnd [$p] if { ![string is integer -strict $rnd] } { incr noninteger } set mean [expr {$mean + $rnd}] } set mean [expr {$mean / 1000.0}] # # We use a rough estimate for the deviation in the mean # set result [expr {$noninteger == 0 && abs($mean - 10.0) < 0.5}] } -result 1 test "Normal-1.0" "Normal generator with mean 1 and standard deviation 1" \ -body { set p [::simulation::random::prng_Normal 1 1] set mean 0.0 set stdev 0.0 for {set i 0} {$i < 1000} {incr i} { set rnd [$p] set mean [expr {$mean + $rnd}] set stdev [expr {$stdev + $rnd * $rnd}] } set mean [expr {$mean / 1000.0}] set stdev [expr {sqrt($stdev / 1000.0)}] # # We use a rough estimate for the deviation in the mean and stdev # Main effect of test: is the procedure syntactically correct? # set result [expr {abs($mean - 1.0) < 0.5 && abs($stdev - 1.0) < 0.5}] } -result 1 # # TODO: These tests merely check that the generated procedure "works" # test "Pareto-1.0" "Pareto generator with minimum 1 and steepness 2" \ -body { set p [::simulation::random::prng_Pareto 1 2] set rnd [$p] set result 1 } -result 1 test "Gumbel-1.0" "Gumbel generator with minimum 1 and scale factor 3" \ -body { set p [::simulation::random::prng_Gumbel 1 3] set rnd [$p] set result 1 } -result 1 test "ChiSquared-1.0" "chi-squared generator with 4 degrees of freedom" \ -body { set p [::simulation::random::prng_chiSquared 4] set rnd [$p] set result 1 } -result 1 test "Disk-1.0" "disk generator with radius 2" \ -body { set p [::simulation::random::prng_Disk 2] set rnd [$p] set result [llength $rnd] } -result 2 test "Ball-1.0" "ball generator with radius 2" \ -body { set p [::simulation::random::prng_Ball 2] set rnd [$p] set result [llength $rnd] } -result 3 test "Sphere-1.0" "sphere generator with radius 2.5" \ -body { set p [::simulation::random::prng_Sphere 2.5] set rnd [$p] set result [llength $rnd] } -result 3 test "Rectangle-1.0" "rectangle generator with sides 10 and 0.1" \ -body { set p [::simulation::random::prng_Rectangle 10 0.1] set rnd [$p] set result [llength $rnd] } -result 2 test "Block-1.0" "block generator with sides 10, 0.1 and 2.5" \ -body { set p [::simulation::random::prng_Block 10 0.1 2.5] set rnd [$p] set result [llength $rnd] } -result 3 test "Triangle-1.0" "triangularly distributed numbers between -1.0 and 1.0" \ -body { set p [::simulation::random::prng_Triangle -1.0 1.0] set okay 1 for {set i 0} {$i < 1000} {incr i} { set rnd [$p] if { $rnd < -1.0 || $rnd > 1.0 } { set okay 0 break } } set okay } -result 1 test "Triangle-1.1" "triangularly distributed numbers between -1.0 and 1.0 (alternative)" \ -body { set p [::simulation::random::prng_Triangle 1.0 -1.0] set okay 1 for {set i 0} {$i < 1000} {incr i} { set rnd [$p] if { $rnd < -1.0 || $rnd > 1.0 } { set okay 0 break } } set okay } -result 1 # End of test cases testsuiteCleanup