From f79309a6f259aa1a1df709721988d794bae235d1 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Tue, 5 Sep 2017 08:06:13 +0200 Subject: [PATCH] add `{sum,sumf}` for summation over sequences --- src/Sequence.ml | 27 +++++++++++++++++++++++++++ src/Sequence.mli | 8 ++++++++ 2 files changed, 35 insertions(+) diff --git a/src/Sequence.ml b/src/Sequence.ml index 9afa5de..6ecd54e 100644 --- a/src/Sequence.ml +++ b/src/Sequence.ml @@ -727,6 +727,33 @@ let min_exn ?lt seq = match min ?lt seq with 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 let head seq = diff --git a/src/Sequence.mli b/src/Sequence.mli index 032e7a2..d3effc8 100644 --- a/src/Sequence.mli +++ b/src/Sequence.mli @@ -412,6 +412,14 @@ val min_exn : ?lt:('a -> 'a -> bool) -> 'a t -> 'a @raise Not_found if the sequence is empty @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 (** First element, if any, otherwise [None] @since 0.5.1 *)