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