Namespace with algorithms for aggregating sequences in various ways.
Namespace with algorithms for aggregating sequences in various ways.
Dynamically bindable size below which pairwise-sum will defer
to sum to aggregate values.
Dynamically bindable size below which [[pairwise-sum]] will defer to [[sum]] to aggregate values.
Fold used to aggregate values encountered by sum or [[fold]].
Rebind this value to change the behavior of sum or [[fold]].
Defaults to [[sicmutils.algebra.fold/kahan-babushka-neumaier-fold]].
Fold used to aggregate values encountered by [[sum]] or [[fold]]. Rebind this value to change the behavior of [[sum]] or [[fold]]. Defaults to [[sicmutils.algebra.fold/kahan-babushka-neumaier-fold]].
(generic-sum xs)(generic-sum f low high)Sums either:
xs of numbers, orf to (range low high)Using the generic sicmutils.generic/+ function.
Sums either: - a series `xs` of numbers, or - the result of mapping function `f` to `(range low high)` Using the generic [[sicmutils.generic/+]] function.
(group minus plus invert id)(group minus plus invert id annihilate?)Similar to monoid for types with invertible elements. Accepts:
minus and (associative) plus functionsnegate functionid that obeys (plus id other) == (plus other id) == otherannihilate? function that should return true for any x
such that (plus x <any>) == x.And returns a function that will SUBTRACT elements. Given x, y, z, for
example, the returned function will return (- x y z), implemented as (minus x (plus y z))
If the annihilate? function is supplied, then if the aggregation produces a
value that returns (annihilate? true) at any point, the reduction will
return immediately.
Similar to [[monoid]] for types with invertible elements. Accepts: - binary `minus` and (associative) `plus` functions - a unary `negate` function - an element `id` that obeys `(plus id other) == (plus other id) == other` - optionally, an `annihilate?` function that should return true for any `x` such that `(plus x <any>) == x`. And returns a function that will SUBTRACT elements. Given `x`, `y`, `z`, for example, the returned function will return `(- x y z)`, implemented as `(minus x (plus y z))` If the `annihilate?` function is supplied, then if the aggregation produces a value that returns `(annihilate? true)` at any point, the reduction will return immediately.
(merge-fn compare add zero? make)NOTE that the returned function recurs on increasing indices internally instead of walking through the lists directly. This method of traversing vectors is more efficient, and this function is called so often that the performance gain is worth it, and reads almost like the explicit sequence traversal.
NOTE that the returned function recurs on increasing indices internally instead of walking through the lists directly. This method of traversing vectors is more efficient, and this function is called so often that the performance gain is worth it, and reads almost like the explicit sequence traversal.
(monoid plus id)(monoid plus id annihilate?)Accepts a binary (associative) aggregation function plus and an identity
element id and returns a multi-arity function that will combine its
arguments via plus. A 0-arity call returns id.
optionally takes an annihilate? function that should return true for any x
such that (plus x <any>) == x.
If the annihilate? function is supplied, then if the aggregation produces a
value that returns (annihilate? true) at any point, the reduction will
return immediately.
Accepts a binary (associative) aggregation function `plus` and an identity element `id` and returns a multi-arity function that will combine its arguments via `plus`. A 0-arity call returns `id`. optionally takes an `annihilate?` function that should return true for any `x` such that `(plus x <any>) == x`. If the `annihilate?` function is supplied, then if the aggregation produces a value that returns `(annihilate? true)` at any point, the reduction will return immediately.
(pairwise-sum xs)(pairwise-sum f low high)Given a vector of numbers, returns the pairwise summation of the vector generated by arranging the vector into a binary tree and summing leaves together all the way up to the root.
If xs is /not/ a vector, pairwise-sum will realize all elements into a
vector before operating.
If the initial vector, or some recursive slice, reaches a count
<= *cutoff*, pairwise-sum defers to (reduce + xs).
pairwise-sum is perhaps 10% faster than sum
with sicmutils.algebra.fold/kbn bound to *fold*, but has poorer bounds
on its error growth. Instead of having roughly constant error regardless of
the size of the input, in the worst case its accumulated error grows with
$O(\log n)$.
This improvement is due to the fact that pairwise-sum tends to add up
numbers of similar magnitude, instead of adding deltas into a progressively
larger sum.
This implementation was inspired by the pairwiseSum implementation in
the math-functions
Haskell package. The notes above were adapted from that function's docs.
Given a vector of numbers, returns the [pairwise summation](https://en.wikipedia.org/wiki/Pairwise_summation) of the vector generated by arranging the vector into a binary tree and summing leaves together all the way up to the root. If `xs` is /not/ a vector, [[pairwise-sum]] will realize all elements into a vector before operating. If the initial vector, or some recursive slice, reaches a count <= [[*cutoff*]], [[pairwise-sum]] defers to `(reduce + xs)`. ### Performance Discussion [[pairwise-sum]] is perhaps 10% faster than [[sum]] with [[sicmutils.algebra.fold/kbn]] bound to [[*fold*]], but has poorer bounds on its error growth. Instead of having roughly constant error regardless of the size of the input, in the worst case its accumulated error grows with $O(\log n)$. This improvement is due to the fact that [[pairwise-sum]] tends to add up numbers of similar magnitude, instead of adding deltas into a progressively larger sum. This implementation was inspired by the `pairwiseSum` implementation in the [`math-functions`](https://hackage.haskell.org/package/math-functions-0.3.4.2/docs/src/Numeric.Sum.html#pairwiseSum) Haskell package. The notes above were adapted from that function's docs.
(scan xs)(scan f low high)Takes either:
xs of numbersf, an inclusive-lower bound low and
exclusive-upper bound upperAnd returns a lazy sequence of all intermediate values seen while aggregating
either xs or (map f (range low high)) using the fold dynamically bound
to *fold*.
Use binding to substitute in a different fold:
(require '[sicmutils.algebra.fold :as af])
(binding [*fold* (af/join af/kahan af/min af/max)]
(scan inc 0 3))
;;=> ([1.0 1 1] [3.0 1 2] [6.0 1 3])
Takes either: - a series `xs` of numbers - A transformation function `f`, an inclusive-lower bound `low` and exclusive-upper bound `upper` And returns a lazy sequence of all intermediate values seen while aggregating either `xs` or `(map f (range low high))` using the fold dynamically bound to [[*fold*]]. Use `binding` to substitute in a different fold: ```clj (require '[sicmutils.algebra.fold :as af]) (binding [*fold* (af/join af/kahan af/min af/max)] (scan inc 0 3)) ;;=> ([1.0 1 1] [3.0 1 2] [6.0 1 3]) ```
(sum xs)(sum f low high)Takes either:
xs of numbersf, an inclusive-lower bound low and
exclusive-upper bound upperAnd returns the result of aggregating either xs or (map f (range low high)) using the fold dynamically bound to *fold*.
Use binding to substitute in a different fold:
(require '[sicmutils.algebra.fold :as af])
(binding [*fold* (af/join af/kahan af/min af/max)]
(sum inc 0 10))
;;=> [55.0 1 10]
Takes either: - a series `xs` of numbers - A transformation function `f`, an inclusive-lower bound `low` and exclusive-upper bound `upper` And returns the result of aggregating either `xs` or `(map f (range low high))` using the fold dynamically bound to [[*fold*]]. Use `binding` to substitute in a different fold: ```clj (require '[sicmutils.algebra.fold :as af]) (binding [*fold* (af/join af/kahan af/min af/max)] (sum inc 0 10)) ;;=> [55.0 1 10] ```
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |