Add sample.

This commit is contained in:
Drup 2016-01-16 15:43:43 +01:00
parent cd32539fea
commit be57b29f84
3 changed files with 40 additions and 0 deletions

View file

@ -698,6 +698,28 @@ let random_array a k =
let random_list l = random_array (Array.of_list l) let random_list l = random_array (Array.of_list l)
(** {2 Sampling} *)
(** See https://en.wikipedia.org/wiki/Reservoir_sampling#Algorithm_R *)
let sample n seq =
match head seq with
| None -> [||]
| Some x ->
let a = Array.make n x in
let i = ref (-1) in
let f x =
incr i ;
if !i < n then
a.(!i) <- x
else
let j = Random.int n in
if j <= n then a.(!i) <- x
else ()
in
seq f ;
if !i < n then Array.sub a 0 !i
else a
(** {2 Infix functions} *) (** {2 Infix functions} *)
module Infix = struct module Infix = struct

View file

@ -498,6 +498,15 @@ val random_list : 'a list -> 'a t
(** Infinite sequence of random elements of the list. Basically the (** Infinite sequence of random elements of the list. Basically the
same as {!random_array}. *) same as {!random_array}. *)
(** {2 Sampling} *)
val sample : int -> 'a t -> 'a array
(** [sample n seq] returns k samples of [seq], with uniform probability.
It will consume the sequence and use O(n) memory.
It returns an array of size [min (length seq) n].
@since NEXT_RELEASE *)
(** {2 Infix functions} *) (** {2 Infix functions} *)
module Infix : sig module Infix : sig

View file

@ -446,6 +446,15 @@ val random_list : 'a list -> 'a t
(** Infinite sequence of random elements of the list. Basically the (** Infinite sequence of random elements of the list. Basically the
same as {!random_array}. *) same as {!random_array}. *)
(** {2 Sampling} *)
val sample : n:int -> 'a t -> 'a array
(** [sample n seq] returns k samples of [seq], with uniform probability.
It will consume the sequence and use O(n) memory.
It returns an array of size [min (length seq) n].
@since NEXT_RELEASE *)
(** {2 Infix functions} *) (** {2 Infix functions} *)
module Infix : sig module Infix : sig