### 2.3.9 Rank reducing (statistical) range functions

The beauty of Yorick's matrix multiplication syntax is that you "point"
to the dimension which is to be contracted by placing the `+` marker
in the corresponding subscript. In this section and the following
section, I introduce Yorick's range functions, which share the "this
dimension right here" syntax with matrix multiplication. The topic in
this section is the statistical range functions. These functions reduce
the rank of an array, as if they were a simple scalar index, but instead
of selecting a particular element along the dimension, a statistical
range function selects a value based on an examination of all of the
elements along the selected dimension. The statistical function is
repeated separately for each value of any spectator dimensions. The
available functions are:

`min``max`- returns the minimum (or maximum) value. These are also available as
ordinary functions.
`sum`- returns the sum of all the values. This is also available as an
ordinary function.
`avg`- returns the arithmetic mean of all the values. The result will be a
real number, even if the input is an integer array. This is also
available as an ordinary function.
`ptp`- returns the peak-to-peak difference (difference between the maximum
and the minimum) among all the values. The result will be positive
if the maximum occurs at a larger index than the minimum, otherwise
the result will be negative.
`rms`- returns the root mean square deviation from the arithmetic mean of the
values. The result will be a real number, even if the input is an
integer array.
`mnx``mxx`- returns the index of the element with the smallest (or largest) value. The result is always an integer index value, independent of the data type of the array being subscripted. If more than one element reaches the extreme value, the result will be the smallest index.

The `min`, `max`, `sum`, and `avg` functions may also
be applied using ordinary function syntax, which is preferred if you
want the function to be applied across all the dimensions of an array
to yield a single scalar result.

Given the `brightness` array representing the spectrum incident on a
detector or set of detectors, the `mxx` function can be used to find
the photon energy at which the incident light is brightest. Assume that
the final dimension of `brightness` is always the spectral
dimension, and that the 1-D array `gav` of photon energies (with the
same length as the final dimension of `brightness`) is also
given:

max_index_list = brightness(.., mxx); gav_at_max = gav(max_index_list); |

Note that `gav_at_max` would be a scalar if `brightness` were
a 1-D spectrum for a single detector, a 2-D array if `brightness`
were a 3-D array of spectra for each point of an image, and so on.

An arbitrary index range (`start:stop` or `start:stop:step`) may
be specified for any range function, by separating the function name
from the range by another colon. For example, to select only a relative
maximum of `brightness` for photon energies above 1.0, ignoring
possible larger values at smaller energies, you could use:

i = min(where(gav > 1.0)); max_index_list = brightness(.., mxx:i:0); gav_at_max = gav(max_index_list); |

Note the use of `min` invoked as an ordinary function in the first
line of this example. (Recall that `where` returns a list of
indices where some conditional expression is true.) In the second line,
`mxx:i:0` is equivalent to `mxx:i:`. Because of the details of
Yorick's current implementation, the former executes slightly faster.

More than one range function may appear in a single subscript list. If so, they are computed from left to right. In order to execute them in another order, you must explicitly subscript the expression resulting from the first application:

x = [[1, 3, 2], [8, 0, 9]]; max_min = x(max, min); min_max = x(, min)(max); |

The value of `max_min` is 3; the value of `min_max` is 2.