net_matrix_ipf {migest} | R Documentation |
Estimate Migration Flows to Match Net Totals via Iterative Proportional Fitting
Description
The net_matrix_ipf
function finds the maximum likelihood estimates for a flow matrix under the multiplicative log-linear model:
\log y_{ij} = \log \alpha_i + \log \alpha_j^{-1} + \log m_{ij}
where y_{ij}
is the estimated migration flow from origin i
to destination j
, and m_{ij}
is the prior flow.
The function iteratively adjusts origin and destination scaling factors (\alpha
) to match directional net migration totals.
Usage
net_matrix_ipf(
net_tot,
m,
zero_mask = NULL,
maxit = 500,
tol = 1e-06,
verbose = FALSE
)
Arguments
net_tot |
A numeric vector of net migration totals for each region. Must sum to zero. |
m |
A square numeric matrix providing prior flow estimates. Must have dimensions |
zero_mask |
A logical matrix of the same dimensions as |
maxit |
Maximum number of iterations to perform. Default is |
tol |
Convergence tolerance based on maximum change in |
verbose |
Logical flag to print progress and |
Details
The function avoids matrix inversion by updating \alpha
using a closed-form solution to a quadratic equation at each step.
Only directional net flows (column sums minus row sums) are matched, not marginal totals. Flows are constrained to be non-negative.
If multiple positive roots are available when solving the quadratic, the smaller root is selected for improved stability.
Value
A named list with components:
n
Estimated matrix of flows satisfying the net constraints.
it
Number of iterations used.
tol
Convergence tolerance used.
value
Sum of squared residuals between actual and target net flows.
convergence
Logical indicator of convergence within tolerance.
message
Text description of convergence result.
Author(s)
Guy J. Abel, Peter W. F. Smith
See Also
net_matrix_entropy()
for entropy-based estimation minimizing KL divergence,
net_matrix_lp()
for L1-loss linear programming,
and net_matrix_optim()
for least-squares (L2) optimization.
Examples
m <- matrix(c(0, 100, 30, 70,
50, 0, 45, 5,
60, 35, 0, 40,
20, 25, 20, 0),
nrow = 4, byrow = TRUE,
dimnames = list(orig = LETTERS[1:4], dest = LETTERS[1:4]))
addmargins(m)
sum_region(m)
net <- c(30, 40, -15, -55)
result <- net_matrix_ipf(net_tot = net, m = m)
result$n |>
addmargins() |>
round(2)
sum_region(result$n)