Small changes to std/sums (#16797)

This commit is contained in:
konsumlamm 2021-01-25 12:15:36 +01:00 • committed by GitHub
commit 8395abab5f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 14 deletions

View file

@ -271,7 +271,7 @@ Math libraries
Statistical analysis Statistical analysis
* `std/sums <sums.html>`_ * `std/sums <sums.html>`_
Fast summation functions. Accurate summation functions.
Internet Protocols and Support Internet Protocols and Support

View file

@ -6,12 +6,37 @@
# See the file "copying.txt", included in this # See the file "copying.txt", included in this
# distribution, for details about the copyright. # distribution, for details about the copyright.
## Fast sumation functions. ## Accurate summation functions.
runnableExamples:
import std/math
template `~=`(x, y: float): bool = abs(x - y) < 1e-4
let
n = 1_000_000
first = 1e10
small = 0.1
var data = @[first]
for _ in 1 .. n:
data.add(small)
let result = first + small * n.float
doAssert abs(sum(data) - result) > 0.3
doAssert sumKbn(data) ~= result
doAssert sumPairs(data) ~= result
## See also
## ========
## * `math module <math.html>`_ for a standard `sum proc <math.html#sum,openArray[T]>`_
func sumKbn*[T](x: openArray[T]): T = func sumKbn*[T](x: openArray[T]): T =
## Kahan-Babuška-Neumaier summation: O(1) error growth, at the expense ## Kahan-Babuška-Neumaier summation: O(1) error growth, at the expense
## of a considerable increase in computational expense. ## of a considerable increase in computational cost.
##
## See:
## * https://en.wikipedia.org/wiki/Kahan_summation_algorithm#Further_enhancements
if len(x) == 0: return if len(x) == 0: return
var sum = x[0] var sum = x[0]
var c = T(0) var c = T(0)
@ -40,8 +65,8 @@ func sumPairs*[T](x: openArray[T]): T =
## the base case is large enough. ## the base case is large enough.
## ##
## See, e.g.: ## See, e.g.:
## * http://en.wikipedia.org/wiki/Pairwise_summation ## * https://en.wikipedia.org/wiki/Pairwise_summation
## Higham, Nicholas J. (1993), "The accuracy of floating point ## * Higham, Nicholas J. (1993), "The accuracy of floating point
## summation", SIAM Journal on Scientific Computing 14 (4): 783–799. ## summation", SIAM Journal on Scientific Computing 14 (4): 783–799.
## ##
## In fact, the root-mean-square error growth, assuming random roundoff ## In fact, the root-mean-square error growth, assuming random roundoff
@ -49,14 +74,5 @@ func sumPairs*[T](x: openArray[T]): T =
## in practice. See: ## in practice. See:
## * Manfred Tasche and Hansmartin Zeuner, Handbook of ## * Manfred Tasche and Hansmartin Zeuner, Handbook of
## Analytic-Computational Methods in Applied Mathematics (2000). ## Analytic-Computational Methods in Applied Mathematics (2000).
##
let n = len(x) let n = len(x)
if n == 0: T(0) else: sumPairwise(x, 0, n) if n == 0: T(0) else: sumPairwise(x, 0, n)
runnableExamples:
static:
block:
const data = [1, 2, 3, 4, 5, 6, 7, 8, 9]
doAssert sumKbn(data) == 45
doAssert sumPairs(data) == 45