#### 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.