Skip to content

Commit

Permalink
Merge pull request #298 from jmid/add-exponential-gen
Browse files Browse the repository at this point in the history
Add an exponential generator
  • Loading branch information
jmid authored Dec 7, 2024
2 parents 8d03c74 + c30deb1 commit 7b6e50c
Show file tree
Hide file tree
Showing 15 changed files with 457 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## NEXT RELEASE

- Add `exponential` generator to `QCheck`, `QCheck.Gen`, and `QCheck2.Gen`
- Add `Shrink.bool` and use it in `QCheck.bool`
- Remove unread `fun_gen` field from `QCheck2`'s `fun_repr_tbl` type
thereby silencing a compiler warning
Expand Down
8 changes: 8 additions & 0 deletions src/core/QCheck.ml
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,12 @@ module Gen = struct

let (--.) = float_range

let exponential mean =
if Float.is_nan mean then invalid_arg "Gen.exponential";
let unit_gen = float_bound_inclusive 1.0 in
map (fun p -> -. mean *. (log p)) unit_gen
(* See https://en.wikipedia.org/wiki/Relationships_among_probability_distributions *)

let neg_int st = -(nat st)

let option ?(ratio = 0.85) f st =
Expand Down Expand Up @@ -1103,6 +1109,8 @@ let float_bound_exclusive bound =

let float_range low high = make_scalar ~print:string_of_float (Gen.float_range low high)

let exponential mean = make_scalar ~print:Print.float (Gen.exponential mean)

let int = make_int Gen.int
let int_bound n = make_int (Gen.int_bound n)
let int_range a b = make_int (Gen.int_range a b)
Expand Down
12 changes: 12 additions & 0 deletions src/core/QCheck.mli
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,12 @@ module Gen : sig
(** Synonym for [float_range]
@since 0.11 *)

val exponential : float -> float t
(** [exponential m] generates floating-point numbers following an exponential
distribution with a mean of [m].
@raise Invalid_argument if [m] is NaN.
@since NEXT_VERSION *)

val nat : int t (** Generates small natural numbers. *)

val big_nat : int t
Expand Down Expand Up @@ -1233,6 +1239,12 @@ val float_range : float -> float -> float arbitrary
@raise Invalid_argument if [low > high] or if the range is larger than [max_float].
@since 0.11 *)

val exponential : float -> float arbitrary
(** [exponential m] generates floating-point numbers following an exponential
distribution with a mean of [m].
@raise Invalid_argument if [m] is NaN.
@since NEXT_VERSION *)

val int : int arbitrary
(** Int generator. Uniformly distributed. *)

Expand Down
6 changes: 6 additions & 0 deletions src/core/QCheck2.ml
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,12 @@ module Gen = struct

let (--.) low high = float_range ?origin:None low high

let exponential (mean : float) =
if Float.is_nan mean then invalid_arg "Gen.exponential";
let unit_gen = float_bound_inclusive 1.0 in
map (fun p -> -. mean *. (log p)) unit_gen
(* See https://en.wikipedia.org/wiki/Relationships_among_probability_distributions *)

let neg_int : int t = nat >|= Int.neg

(** [option gen] shrinks towards [None] then towards shrinks of [gen]. *)
Expand Down
8 changes: 8 additions & 0 deletions src/core/QCheck2.mli
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,14 @@ module Gen : sig
@since 0.11 *)

val exponential : float -> float t
(** [exponential m] generates floating-point numbers following an exponential
distribution with a mean of [m].
@raise Invalid_argument if [m] is NaN.
@since NEXT_VERSION *)

val char_range : ?origin:char -> char -> char -> char t
(** [char_range ?origin low high] generates chars between [low] and [high], inclusive.
Example: [char_range 'a' 'z'] for all lower case ASCII letters.
Expand Down
52 changes: 51 additions & 1 deletion test/core/QCheck2_expect_test.expected.ocaml4.32
Original file line number Diff line number Diff line change
Expand Up @@ -1395,9 +1395,59 @@ stats dist:
751619287.. 858993469: 0
858993470.. 966367652: 0
966367653.. 1073741823: ################# 189

+++ Stats for exponential 10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

stats dist:
num: 5000, avg: 9.56, stddev: 9.91, median 7, min 0, max 89
0.. 4: ####################################################### 1934
5.. 9: ################################## 1202
10.. 14: #################### 727
15.. 19: ############ 452
20.. 24: ######## 284
25.. 29: #### 164
30.. 34: ## 103
35.. 39: # 51
40.. 44: 26
45.. 49: 24
50.. 54: 15
55.. 59: 7
60.. 64: 3
65.. 69: 2
70.. 74: 2
75.. 79: 1
80.. 84: 1
85.. 89: 2
90.. 94: 0
95.. 99: 0

+++ Stats for exponential -10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

stats dist:
num: 5000, avg: -9.56, stddev: 9.91, median -7, min -89, max 0
-89..-85: 2
-84..-80: 1
-79..-75: 1
-74..-70: 2
-69..-65: 2
-64..-60: 3
-59..-55: 7
-54..-50: 15
-49..-45: 24
-44..-40: 26
-39..-35: # 51
-34..-30: ## 103
-29..-25: #### 164
-24..-20: ######## 284
-19..-15: ############ 452
-14..-10: #################### 727
-9.. -5: ################################## 1202
-4.. 0: ####################################################### 1934
1.. 5: 0
6.. 10: 0
================================================================================
1 warning(s)
failure (64 tests failed, 3 tests errored, ran 141 tests)
failure (64 tests failed, 3 tests errored, ran 143 tests)
random seed: 153870556

+++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Expand Down
52 changes: 51 additions & 1 deletion test/core/QCheck2_expect_test.expected.ocaml4.64
Original file line number Diff line number Diff line change
Expand Up @@ -1459,9 +1459,59 @@ stats dist:
3228180212899171968.. 3689348814741910783: 0
3689348814741910784.. 4150517416584649599: 0
4150517416584649600.. 4611686018427387903: ################# 189

+++ Stats for exponential 10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

stats dist:
num: 5000, avg: 9.56, stddev: 9.91, median 7, min 0, max 89
0.. 4: ####################################################### 1934
5.. 9: ################################## 1202
10.. 14: #################### 727
15.. 19: ############ 452
20.. 24: ######## 284
25.. 29: #### 164
30.. 34: ## 103
35.. 39: # 51
40.. 44: 26
45.. 49: 24
50.. 54: 15
55.. 59: 7
60.. 64: 3
65.. 69: 2
70.. 74: 2
75.. 79: 1
80.. 84: 1
85.. 89: 2
90.. 94: 0
95.. 99: 0

+++ Stats for exponential -10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

stats dist:
num: 5000, avg: -9.56, stddev: 9.91, median -7, min -89, max 0
-89..-85: 2
-84..-80: 1
-79..-75: 1
-74..-70: 2
-69..-65: 2
-64..-60: 3
-59..-55: 7
-54..-50: 15
-49..-45: 24
-44..-40: 26
-39..-35: # 51
-34..-30: ## 103
-29..-25: #### 164
-24..-20: ######## 284
-19..-15: ############ 452
-14..-10: #################### 727
-9.. -5: ################################## 1202
-4.. 0: ####################################################### 1934
1.. 5: 0
6.. 10: 0
================================================================================
1 warning(s)
failure (64 tests failed, 3 tests errored, ran 141 tests)
failure (64 tests failed, 3 tests errored, ran 143 tests)
random seed: 153870556

+++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Expand Down
52 changes: 51 additions & 1 deletion test/core/QCheck2_expect_test.expected.ocaml5.32
Original file line number Diff line number Diff line change
Expand Up @@ -1395,9 +1395,59 @@ stats dist:
751619287.. 858993469: 0
858993470.. 966367652: 0
966367653.. 1073741823: ################# 195

+++ Stats for exponential 10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

stats dist:
num: 5000, avg: 9.45, stddev: 9.82, median 6, min 0, max 79
0.. 3: ####################################################### 1631
4.. 7: ##################################### 1109
8..11: ######################### 747
12..15: ################# 512
16..19: ########## 308
20..23: ######## 251
24..27: ##### 165
28..31: ## 85
32..35: ## 64
36..39: # 43
40..43: 25
44..47: 20
48..51: 20
52..55: 3
56..59: 8
60..63: 3
64..67: 1
68..71: 2
72..75: 2
76..79: 1

+++ Stats for exponential -10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

stats dist:
num: 5000, avg: -9.45, stddev: 9.82, median -6, min -79, max 0
-79..-76: 1
-75..-72: 2
-71..-68: 2
-67..-64: 1
-63..-60: 3
-59..-56: 8
-55..-52: 3
-51..-48: 20
-47..-44: 20
-43..-40: 25
-39..-36: # 43
-35..-32: ## 64
-31..-28: ## 85
-27..-24: ##### 165
-23..-20: ######## 251
-19..-16: ########## 308
-15..-12: ################# 512
-11.. -8: ######################### 747
-7.. -4: ##################################### 1109
-3.. 0: ####################################################### 1631
================================================================================
1 warning(s)
failure (64 tests failed, 3 tests errored, ran 141 tests)
failure (64 tests failed, 3 tests errored, ran 143 tests)
random seed: 153870556

+++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Expand Down
52 changes: 51 additions & 1 deletion test/core/QCheck2_expect_test.expected.ocaml5.64
Original file line number Diff line number Diff line change
Expand Up @@ -1451,9 +1451,59 @@ stats dist:
3228180212899171968.. 3689348814741910783: 0
3689348814741910784.. 4150517416584649599: 0
4150517416584649600.. 4611686018427387903: ################# 195

+++ Stats for exponential 10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

stats dist:
num: 5000, avg: 9.45, stddev: 9.82, median 6, min 0, max 79
0.. 3: ####################################################### 1631
4.. 7: ##################################### 1109
8..11: ######################### 747
12..15: ################# 512
16..19: ########## 308
20..23: ######## 251
24..27: ##### 165
28..31: ## 85
32..35: ## 64
36..39: # 43
40..43: 25
44..47: 20
48..51: 20
52..55: 3
56..59: 8
60..63: 3
64..67: 1
68..71: 2
72..75: 2
76..79: 1

+++ Stats for exponential -10. dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

stats dist:
num: 5000, avg: -9.45, stddev: 9.82, median -6, min -79, max 0
-79..-76: 1
-75..-72: 2
-71..-68: 2
-67..-64: 1
-63..-60: 3
-59..-56: 8
-55..-52: 3
-51..-48: 20
-47..-44: 20
-43..-40: 25
-39..-36: # 43
-35..-32: ## 64
-31..-28: ## 85
-27..-24: ##### 165
-23..-20: ######## 251
-19..-16: ########## 308
-15..-12: ################# 512
-11.. -8: ######################### 747
-7.. -4: ##################################### 1109
-3.. 0: ####################################################### 1631
================================================================================
1 warning(s)
failure (64 tests failed, 3 tests errored, ran 141 tests)
failure (64 tests failed, 3 tests errored, ran 143 tests)
random seed: 153870556

+++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Expand Down
Loading

0 comments on commit 7b6e50c

Please sign in to comment.