diff --git a/src/core/CCRandom.ml b/src/core/CCRandom.ml index f80b13a4..0f24d77b 100644 --- a/src/core/CCRandom.ml +++ b/src/core/CCRandom.ml @@ -3,7 +3,6 @@ (** {1 Random Generators} *) -open CCShims_ include Random type state = Random.State.t @@ -208,35 +207,6 @@ let __default_state = Random.State.make_self_init () let run ?(st=__default_state) g = g st -let uniformity_test ?(size_hint=10) k rng st = - let histogram = Hashtbl.create size_hint in - let add x = let n = try Hashtbl.find histogram x with Not_found -> 0 in - Hashtbl.replace histogram x (n + 1) in - let () = - for _i = 0 to ( k - 1 ) do - add (rng st) - done in - let cardinal = float_of_int (Hashtbl.length histogram) in - let kf = float_of_int k in - (* average number of points assuming an uniform distribution *) - let average = kf /. cardinal in - (* The number of points is a sum of random variables with binomial distribution *) - let p = 1. /. cardinal in - (* The variance of a binomial distribution with average p is *) - let variance = p *. (1. -. p ) in - (* Central limit theorem: a confidence interval of 4σ provides a false positive rate - of 0.00634% *) - let confidence = 4. in - let std = confidence *. (sqrt (kf *. variance)) in - let predicate _key n acc = - let (<) (a : float) b = Stdlib.(<) a b in - acc && abs_float (average -. float_of_int n) < std in - Hashtbl.fold predicate histogram true - -(*$T split_list - run ~st:(QCheck_runner.random_state()) ( uniformity_test 50_000 (split_list 10 ~len:3) ) -*) - (*$R let open Containers in ignore @@ List.random_choose [1;2;3] (Random.get_state()) diff --git a/src/core/CCRandom.mli b/src/core/CCRandom.mli index cec88c3d..47b41226 100644 --- a/src/core/CCRandom.mli +++ b/src/core/CCRandom.mli @@ -158,11 +158,3 @@ include CCShimsMkLet_.S with type 'a t_let := 'a t val run : ?st:state -> 'a t -> 'a (** Using a random state (possibly the one in argument) run a generator. *) - -(**/**) - -val uniformity_test : ?size_hint:int -> int -> 'a t -> bool t -(** [uniformity_test k rng] tests the uniformity of the random generator [rng] using - [k] samples. - @since 0.15 -*) diff --git a/src/core/tests/dune b/src/core/tests/dune index a52331d7..3aa1e4f8 100644 --- a/src/core/tests/dune +++ b/src/core/tests/dune @@ -2,12 +2,25 @@ (executable (name check_labelled_mods) + (modules check_labelled_mods) (flags :standard -warn-error -a -w -3-33-35-27-39-50 -nolabels) (libraries containers)) +(executable + (name test_hash) + (modules test_hash) + (flags :standard -warn-error -a+8) + (libraries containers)) + +(alias + (name runtest) + (locks ctest) + (package containers) + (action (run ./test_random.exe))) + ; what matters is that it compiles (alias - (name runtest) + (name runtest) (locks ctest) (package containers) (action (run ./check_labelled_mods.exe))) diff --git a/src/core/tests/test_random.ml b/src/core/tests/test_random.ml new file mode 100644 index 00000000..54058d12 --- /dev/null +++ b/src/core/tests/test_random.ml @@ -0,0 +1,32 @@ + +open CCRandom + +let uniformity_test ?(size_hint=10) k rng st = + let histogram = Hashtbl.create size_hint in + let add x = let n = try Hashtbl.find histogram x with Not_found -> 0 in + Hashtbl.replace histogram x (n + 1) in + let () = + for _i = 0 to ( k - 1 ) do + add (rng st) + done in + let cardinal = float_of_int (Hashtbl.length histogram) in + let kf = float_of_int k in + (* average number of points assuming an uniform distribution *) + let average = kf /. cardinal in + (* The number of points is a sum of random variables with binomial distribution *) + let p = 1. /. cardinal in + (* The variance of a binomial distribution with average p is *) + let variance = p *. (1. -. p ) in + (* Central limit theorem: a confidence interval of 4σ provides a false positive rate + of 0.00634% *) + let confidence = 4. in + let std = confidence *. (sqrt (kf *. variance)) in + let predicate _key n acc = + let (<) (a : float) b = Stdlib.(<) a b in + acc && abs_float (average -. float_of_int n) < std in + Hashtbl.fold predicate histogram true + +let () = + let st = Random.State.make_self_init() in + let ok = run ~st ( uniformity_test 50_000 (split_list 10 ~len:3) ) in + if not ok then failwith "uniformity check failed"