Skip to contents

Computes spatial accessibility scores using an iterative floating catchment area method that combines Huff-model based choice probabilities with distance decay effects. This enhanced version supports time-series demand patterns and customizable decay functions.

The iFCA method extends traditional FCA approaches by:

  • Supporting dynamic demand patterns through multi-layer inputs

  • Incorporating flexible distance decay specifications

  • Iteratively balancing supply and demand

  • Using a learning rate to control convergence

Usage

spax_ifca(
  distance_raster,
  demand,
  supply,
  decay_params = list(method = "gaussian", sigma = 30),
  lambda = 0.5,
  max_iter = 100,
  tolerance = 1e-06,
  window_size = 5,
  convergence_type = c("utilization", "ratio"),
  snap = FALSE,
  debug = FALSE
)

Arguments

distance_raster

A multi-layer SpatRaster where each layer represents distances to one facility. All layers must share the same extent and resolution.

demand

SpatRaster of demand distribution. Can be either: - Single layer for static demand - Multiple layers (matching max_iter) for dynamic demand

supply

Numeric vector of facility capacities. Length must match number of layers in distance_raster.

decay_params

List of parameters for decay function:

  • method: "gaussian", "exponential", "power", or custom function

  • sigma: decay parameter controlling spatial interaction strength

  • Additional parameters passed to custom decay functions

lambda

Learning rate between 0 and 1 controlling convergence speed. Lower values provide more stability but slower convergence. Default: 0.5

max_iter

Maximum number of iterations to attempt. For multi-layer demand, this must match the number of demand layers. Default: 100

tolerance

Convergence tolerance threshold. Iteration stops when the rolling average of differences falls below this value. Default: 1e-6

window_size

Size of rolling window for convergence checking. Default: 5

convergence_type

Character string specifying convergence metric, one of: "utilization" (default) or "ratio"

snap

Logical; if TRUE enables fast computation mode returning only utilization vector. Default: FALSE

debug

Logical; if TRUE provides detailed convergence information. Default: FALSE

Value

If snap = TRUE: Numeric vector of predicted utilization for all facilities

If snap = FALSE: A spax object containing:

accessibility

SpatRaster of accessibility scores

type

Character string "iFCA"

parameters

List of model parameters including decay_params, lambda, etc.

facilities

data.frame with columns:

  • id: Facility identifiers

  • utilization: Predicted facility utilization

  • ratio: Supply-to-demand ratios

  • attractiveness: Final facility attractiveness

iterations

List containing:

  • history: Array of historical state values if converged

  • convergence: Convergence details including iterations, status, etc.

call

The original function call

See also

calc_decay for available decay functions

Examples

if (FALSE) { # \dontrun{
# Load example data
library(terra)
library(sf)

# Prepare inputs
pop <- read_spax_example("u5pd.tif")
distance <- read_spax_example("hos_iscr.tif")
hospitals <- st_drop_geometry(hc12_hos)

# Basic usage with default parameters
result <- spax_ifca(
  distance_raster = distance,
  demand = pop,
  supply = hospitals$s_doc,
  decay_params = list(
    method = "gaussian",
    sigma = 30  # 30-minute characteristic distance
  )
)

# Plot accessibility surface
plot(result$accessibility, main = "Doctor Accessibility (iFCA)")

# Examine facility-level results
head(result$facilities)

# Check convergence information
print(result$iterations$convergence)

# Fast computation mode - returns only utilization
util <- spax_ifca(
  distance_raster = distance,
  demand = pop,
  supply = hospitals$s_doc,
  decay_params = list(method = "gaussian", sigma = 30),
  snap = TRUE
)

# Compare predicted utilization with facility capacity
data.frame(
  id = hospitals$id,
  capacity = hospitals$s_doc,
  predicted = util
)

# Using custom decay function
custom_decay <- function(distance, sigma = 30, threshold = 60) {
  weights <- exp(-distance^2 / (2 * sigma^2))
  weights[distance > threshold] <- 0
  return(weights)
}

result_custom <- spax_ifca(
  distance_raster = distance,
  demand = pop,
  supply = hospitals$s_doc,
  decay_params = list(
    method = custom_decay,
    sigma = 30,
    threshold = 60
  )
)

} # }