Flow-based (Infomap / Map Equation) Backend for MONECA Segmentation
Source:R/moneca_flow.R
moneca_flow.RdAlternative to [moneca::moneca_fast()] and [moneca_sbm()] that replaces the clique / SBM step with Infomap (Rosvall & Bergstrom 2008). The Map Equation treats the graph as a stationary random walk and extracts modules that trap flow, which is a natural fit for mobility data where edges are directed transition counts.
Arguments
- mx
A square mobility matrix, optionally with margins as the last row and column (auto-detected via `has_margins = "auto"`). Sparse `dgCMatrix` input is accepted and converted to dense for the igraph call.
- backend
Currently only `"igraph"`. Reserved for a future `"infomap_cpp"` backend that invokes the standalone Infomap C++ binary for true hierarchical optimisation.
- depth
Integer in `1:3`. Number of recursion levels to build. `1` is flat; `2` (default) adds one level of within-module re-clustering; `3` adds a further level.
- nb_trials
Integer. Number of Infomap trials per call, passed through to `igraph::cluster_infomap()`. Higher values reduce stochastic variation at linear cost.
- directed
Logical. If `TRUE` (default), treat the graph as directed (mobility has intrinsic direction). If `FALSE`, the graph is undirected; combine with `symmetric_method = "sum"` or `"min"` to symmetrise the weights explicitly.
- symmetric_method
One of `"none"` (default; keep directed), `"sum"` (`mx + t(mx)`), or `"min"` (`2 * pmin(mx, t(mx))`). Applied to the core before the igraph fit.
- small.cell.reduction
Numeric. Cells in the core matrix below this value are zeroed before the fit. Mirrors [moneca::moneca_fast()].
- zero_diagonal
Logical. If `TRUE` (default), the diagonal of the core is zeroed before the fit (self-loops removed). Set to `FALSE` to preserve self-flows.
- segment.levels
Integer, `NULL`, or the string `"auto"`. If `NULL` (default), all levels produced by the recursion are kept. If an integer, the hierarchy is truncated to that many levels. If `"auto"`, the full hierarchy is fit and then [auto_segment_levels()] picks a single preferred level via `auto_method`; the object is trimmed to that level and carries the picker result under `$auto_level`.
- auto_method
One of `"mdl"` (default) or `"mi_plateau"`. Ignored unless `segment.levels = "auto"`. With `"mdl"` the criterion is applied to the codelength trace under the hood.
- seed
Integer seed for reproducible inference.
- has_margins
One of `"auto"` (default), `TRUE`, or `FALSE`. Controls margin detection and appending.
- verbose
Logical. If `TRUE`, prints per-level progress messages.
- ...
Reserved for forward compatibility.
Value
An object of class `"moneca"` with the same structure as [moneca::moneca_fast()] output, plus an extra slot `$flow_diagnostics` describing the backend used, the number of blocks per level, and the codelength trace. The diagnostics slot also carries `mdl_per_level` as an alias of `codelength_per_level` so downstream tooling that keys on `$mdl_per_level` can consume flow output unchanged.
Details
`igraph::cluster_infomap()` returns a flat partition. To expose a hierarchy compatible with moneca's multi-level segment contract, a recursive wrapper re-runs the flat algorithm on each module's induced subgraph for level 2, and optionally once more for level 3 when `depth = 3L`. This is an *approximate* hierarchy: it does not jointly optimise a single hierarchical map equation. For joint-MDL optimisation use the standalone C++ Infomap binary (planned as an optional backend in a future release).
Input is raw mobility counts. No relative-risk transformation is applied; users who want RR-weighted flow clustering should preprocess the matrix themselves, or use [moneca_sbm()] which consumes RR natively via the DC-SBM bridge.
The codelength per level is computed directly from the map equation on the full graph (PageRank-based stationary distribution plus module exit probabilities), not inferred from the sub-module Infomap runs. This ensures `codelength_per_level` is comparable across levels of the recursive hierarchy.
References
Rosvall, M. and Bergstrom, C. T. (2008). Maps of random walks on complex networks reveal community structure. *PNAS*, 105(4), 1118-1123.
Examples
if (requireNamespace("igraph", quietly = TRUE)) {
# Small planted-community fixture
set.seed(42)
n <- 20
block <- rep(1:4, each = 5)
mx <- matrix(rpois(n * n, 0.2), n, n)
for (k in 1:4) {
idx <- which(block == k)
mx[idx, idx] <- mx[idx, idx] + rpois(length(idx)^2, 3)
}
diag(mx) <- 0
fit <- moneca_flow(mx, depth = 2L, seed = 1L)
fit$flow_diagnostics$codelength_per_level
}
#> [1] 3.766350 3.308539