add {sum,sumf} for summation over sequences

This commit is contained in:
Simon Cruanes 2017-09-05 08:06:13 +02:00
parent 5a14ec7233
commit f79309a6f2
2 changed files with 35 additions and 0 deletions

View file

@ -727,6 +727,33 @@ let min_exn ?lt seq = match min ?lt seq with
0 (0 -- 100 |> min_exn ?lt:None) 0 (0 -- 100 |> min_exn ?lt:None)
*) *)
let sum seq =
let n = ref 0 in
seq (fun x -> n := !n + x);
!n
(*$T
(of_list [1;2;3] |> sum) = 6
*)
(* https://en.wikipedia.org/wiki/Kahan_summation_algorithm *)
let sumf seq : float =
let sum = ref 0. in
let c = ref 0. in (* error compensation *)
seq
(fun x ->
let y = x -. !c in
let t = !sum +. y in
c := (t -. !sum) -. y;
sum := t);
!sum
(*$R
let cmp x y = (abs_float (x-.y)) < 0.05 in
let seq = of_list [10000.0; 3.14159; 2.71828] in
assert_equal ~printer:string_of_float ~cmp 10005.9 (sumf seq)
*)
exception ExitHead exception ExitHead
let head seq = let head seq =

View file

@ -412,6 +412,14 @@ val min_exn : ?lt:('a -> 'a -> bool) -> 'a t -> 'a
@raise Not_found if the sequence is empty @raise Not_found if the sequence is empty
@since 0.10 *) @since 0.10 *)
val sum : int t -> int
(** Sum of elements
@since NEXT_RELEASE *)
val sumf : float t -> float
(** Sum of elements, using Kahan summation
@since NEXT_RELEASE *)
val head : 'a t -> 'a option val head : 'a t -> 'a option
(** First element, if any, otherwise [None] (** First element, if any, otherwise [None]
@since 0.5.1 *) @since 0.5.1 *)