An integral \(\int N(w) K(w)\, dw\) is discretised on mizer's
finite-volume grid as \(\sum_j N_j \bar K_j \Delta w_j\), where \(N_j\)
is the cell average of the density over bin \([w_j, w_{j+1}]\). Only the
weight is approximated: \(N_j\) is already a cell average and \(\Delta
w_j\) is exact, so neither the abundance nor the bin widths should ever be
passed through this function.
Whether the point weight \(K(w_j)\) is replaced by the bin average
$$\bar K_j = \frac{1}{\Delta w_j}\int_{w_j}^{w_{j+1}} K(w)\,dw
\approx \tfrac12\big(K(w_j) + K(w_{j+1})\big)$$
is controlled by the bin_average entry of the model's second_order_w()
slot. When it is FALSE (the default) K is returned unchanged, so an
indicator written with this function reproduces the left-edge Riemann sums of
previous mizer versions byte-for-byte. When it is TRUE the trapezoidal bin
average is returned, which is uniformly second order and exact whenever
\(K\) is linear in \(w\) (e.g. the first moment \(K = w\), for which it
equals \((w_{j+1}^2 - w_j^2)/(2\Delta w_j)\)).
Because the gating happens inside, always call this rather than averaging
unconditionally: a hard-coded bin average silently changes the results of
models that are on the default scheme.
If K is a product of several size-dependent factors, average the
product and not the individual factors — the average of a product is not
the product of the averages. Spawning stock biomass, for example, averages
maturity * w as a single weight.
The top bin has no right-hand neighbour on the grid, so its weight is left
unaveraged (one-sided); the density there is negligible, so this does not
affect the second-order accuracy of the totals.