Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an exponential generator #298

Merged
merged 6 commits into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading