Skip to content

Commit f4e1bce

Browse files
committed
add to reference the reduce_sum_static function ref
1 parent 8fca929 commit f4e1bce

File tree

1 file changed

+32
-14
lines changed

1 file changed

+32
-14
lines changed

src/functions-reference/higher-order_functions.Rmd

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -385,26 +385,41 @@ The gradients of the integral are computed in accordance with the Leibniz integr
385385

386386
## Reduce-Sum Function {#functions-reduce}
387387

388-
Stan provides a higher-order `reduce_sum` function which maps
389-
evaluation of a function `g: U -> real` to a list of type `U[]`, `{
390-
x1, x2, ... }`, and performs as reduction operation a sum over the
391-
results. That is:
388+
Stan provides a higher-order reduce function for summation. A function
389+
`g: U -> real`, which returns a scalar, is mapped to every element of
390+
a list of type `U[]`, `{ x1, x2, ... }` and all the results are
391+
accumulated,
392392

393393
```g(x1) + g(x2) + ...```
394394

395-
`reduce_sum` doesn't work with the element-wise evaluated
396-
function `g` itself, but instead works through evaluating partial
397-
sums, `f: U[] -> real`, where:
395+
For efficiency reasons the reduce function doesn't work with the
396+
element-wise evaluated function `g` itself, but instead works through
397+
evaluating partial sums, `f: U[] -> real`, where:
398398

399399
```
400400
f({ x1 }) = g(x1)
401401
f({ x1, x2 }) = g(x1) + g(x2)
402402
f({ x1, x2, ... }) = g(x1) + g(x2) + ...
403403
```
404404

405+
Mathematically the summation reduction is associative and forming
406+
arbitrary partial sums in an aribitrary order will not change the
407+
result. However, floating point numerics on computers only have
408+
a limited precision such that associativity does not hold
409+
exactly. This implies that the order of summation determines the exact
410+
numerical result. For this reason, the higher-order reduce function is
411+
available in two variants:
412+
413+
* `reduce_sum`: Automatically forms partial sums resulting usually in good
414+
performance without further tuning.
415+
* `reduce_sum_static`: Creates for the same input always the same
416+
call graph resulting in stable numerical evaluation. This version
417+
requires setting a tuning parameter which controls the maximal size of partial
418+
sums formed.
419+
405420
### Specifying the Reduce-sum Function
406421

407-
The `reduce_sum` function takes a partial sum function `f`, an array argument `x`
422+
The higher-order reduce function takes a partial sum function `f`, an array argument `x`
408423
(with one array element for each term in the sum), a recommended
409424
`grainsize`, and a set of shared arguments. This representation allows
410425
to parallelize the resultant sum.
@@ -413,6 +428,7 @@ to parallelize the resultant sum.
413428
\index{{\tt \bfseries reduce\_sum }!{\tt (F f, T[] x, int grainsize, T1 s1, T2 s2, ...): real}|hyperpage}
414429

415430
`real` **`reduce_sum`**`(F f, T[] x, int grainsize, T1 s1, T2 s2, ...)`<br>\newline
431+
`real` **`reduce_sum_static`**`(F f, T[] x, int grainsize, T1 s1, T2 s2, ...)`<br>\newline
416432

417433
Returns the equivalent of `f(1, size(x), x, s1, s2, ...)`, but computes
418434
the result in parallel by breaking the array `x` into independent
@@ -421,7 +437,9 @@ partial sums. `s1, s2, ...` are shared between all terms in the sum.
421437
* *`f`*: function literal referring to a function specifying the
422438
partial sum operation. Refer to the [partial sum function](#functions-partial-sum).
423439
* *`x`*: array of `T`, one for each term of the reduction, `T` can be any type,
424-
* *`grainsize`*: recommended number of terms in each reduce call, set to one to estimate automatically, type `int`,
440+
* *`grainsize`*: recommended number of terms in each reduce call, set
441+
to one to estimate automatically for `reduce_sum` while for
442+
`reduce_sum_static` this determines the maximal size of the partial sums, type `int`,
425443
* *`s1`*: first (optional) shared argument, type `T1`, where `T1` can be any type
426444
* *`s2`*: second (optional) shared argument, type `T2`, where `T2` can be any type,
427445
* *`...`*: remainder of shared arguments, each of which can be any type.
@@ -430,7 +448,7 @@ partial sum operation. Refer to the [partial sum function](#functions-partial-su
430448

431449
The partial sum function must have the following signature where the types `T`, and the
432450
types of all the shared arguments (`T1`, `T2`, ...) match those of the original
433-
`reduce_sum` call.
451+
`reduce_sum` (`reduce_sum_static`) call.
434452

435453
```
436454
(int start, int end, T[] x_subset, T1 s1, T2 s2, ...):real
@@ -443,13 +461,13 @@ calculations. The arguments to the partial sum function are:
443461

444462
* *`end`*, the index of the last term of the partial sum (inclusive), type `int`
445463

446-
* *`x_subset`*, the subset of `x` a given partial sum is responsible for computing, type `T[]`, where `T` matches the type of `x` in `reduce_sum`
464+
* *`x_subset`*, the subset of `x` a given partial sum is responsible for computing, type `T[]`, where `T` matches the type of `x` in `reduce_sum` (`reduce_sum_static`)
447465

448-
* *`s1`*, first shared argument, type `T1`, matching type of `s1` in `reduce_sum`
466+
* *`s1`*, first shared argument, type `T1`, matching type of `s1` in `reduce_sum` (`reduce_sum_static`)
449467

450-
* *`s2`*, second shared argument, type `T2`, matching type of `s2` in `reduce_sum`
468+
* *`s2`*, second shared argument, type `T2`, matching type of `s2` in `reduce_sum` (`reduce_sum_static`)
451469

452-
* *`...`*, remainder of shared arguments, with types matching those in `reduce_sum`
470+
* *`...`*, remainder of shared arguments, with types matching those in `reduce_sum` (`reduce_sum_static`)
453471

454472

455473
## Map-Rect Function {#functions-map}

0 commit comments

Comments
 (0)