Creates an aggregation matrix for blockwise aggregation, with optional weighting.
fm_block(
block = NULL,
weights = NULL,
log_weights = NULL,
rescale = FALSE,
n_block = NULL
)fm_block_eval(
block = NULL,
weights = NULL,
log_weights = NULL,
rescale = FALSE,
n_block = NULL,
values = NULL
)
fm_block_logsumexp_eval(
block = NULL,
weights = NULL,
log_weights = NULL,
rescale = FALSE,
n_block = NULL,
values = NULL,
log = TRUE
)
fm_block_weights(
block = NULL,
weights = NULL,
log_weights = NULL,
rescale = FALSE,
n_block = NULL
)
fm_block_log_weights(
block = NULL,
weights = NULL,
log_weights = NULL,
rescale = FALSE,
n_block = NULL
)
fm_block_log_shift(block = NULL, log_weights = NULL, n_block = NULL)
fm_block_prep(
block = NULL,
log_weights = NULL,
weights = NULL,
n_block = NULL,
values = NULL,
n_values = NULL,
force_log = FALSE
)
A (sparse) matrix
integer vector; block information. If NULL,
rep(1L, block_len) is used, where block_len is determined by
length(log_weights))) or length(weights))). A single scalar is also
repeated to a vector of corresponding length to the weights. 'character'
input is converted to integer with as.integer(factor(block)) (from
0.2.0.9017).
Optional weight vector
Optional log(weights) vector. Overrides weights when
non-NULL.
logical; If TRUE, normalise the weights by sum(weights)
or sum(exp(log_weights)) within each block.
Default: FALSE
integer; The number of conceptual blocks. Only needs to be
specified if it's larger than max(block), or to keep the output of
consistent size for different inputs.
Vector to be blockwise aggregated
If TRUE (default), return log-sum-exp. If FALSE,
return sum-exp.
When supplied, used instead of length(values) to determine
the value vector input length.
When FALSE (default),
passes either weights and log_weights on, if provided, with log_weights
taking precedence. If TRUE, forces the computation of log_weights,
whether given in the input or not.
fm_block(): A (sparse) matrix of size n_block times
length(block).
fm_block_eval(): Evaluate aggregation. More efficient alternative to to
as.vector(fm_block(...) %*% values).
fm_block_logsumexp_eval(): Evaluate log-sum-exp aggregation.
More efficient and numerically stable alternative to to
log(as.vector(fm_block(...) %*% exp(values))).
fm_block_weights(): Computes (optionally) blockwise renormalised weights
fm_block_log_weights(): Computes (optionally) blockwise renormalised log-weights
fm_block_log_shift(): Computes shifts for stable blocked log-sum-exp.
To compute \(\log(\sum_{i; \textrm{block}_i=k} \exp(v_i) w_i)\) for
each block k, first compute combined values and weights, and a shift:
w_values <- values + fm_block_log_weights(block, log_weights = log_weights)
shift <- fm_block_log_shift(block, log_weights = w_values)
Then aggregate the values within each block:
agg <- aggregate(exp(w_values - shift[block]),
by = list(block = block),
\(x) log(sum(x)))
agg$x <- agg$x + shift[agg$block]
The implementation uses a faster method:
as.vector(
Matrix::sparseMatrix(
i = block,
j = rep(1L, length(block)),
x = exp(w_values - shift[block]),
dims = c(n_block, 1))
) + shift
fm_block_prep(): Helper function for preparing block, weights, and
log_weights, n_block inputs.
block <- rep(1:2, 3:2)
fm_block(block)
fm_block(block, rescale = TRUE)
fm_block(block, log_weights = -2:2, rescale = TRUE)
fm_block_eval(
block,
weights = 1:5,
rescale = TRUE,
values = 11:15
)
fm_block_logsumexp_eval(
block,
weights = 1:5,
rescale = TRUE,
values = log(11:15),
log = FALSE
)
Run the code above in your browser using DataLab