blvim implements A. Wilson’s Boltzmann–Lotka–Volterra (BLV)
interaction model. The model is described in Wilson, A. (2008),
“Boltzmann, Lotka and Volterra and spatial structural evolution: an
integrated methodology for some dynamical systems”, J. R. Soc.
Interface, 5:865–871.
The package’s primary goal is to provide a fast implementation of the
BLV model, complete with a collection of tools designed to explore the
results through statistical summaries and graphical representations. The
secondary goal is to facilitate the systematic assessment of how model
parameters impact the results, again using summaries and graphical
representations (see vignette("grid") for details on this aspect).
You can install blvim from CRAN with:
install.packages('blvim')
You can install the development version from R-universe with:
install.packages('blvim', repos = c('https://fabrice-rossi.r-universe.dev'))
Spatial interaction models aim to estimate flows between locations,
such as workers commuting from residential zones to employment zones.
The blvim package focuses on the maximum entropy models developed by
Alan Wilson. See vignette("theory") for the theoretical background.
In practice, if we have
The package is loaded in a standard way.
library(blvim)
To compute a spatial interaction model with blvim, you need at least a
cost matrix. The package comes with distance data for a selection of
large French cities. We use the 30 largest ones as origin locations and
the 20 smallest ones as destination locations. The cost matrix is the
distance between the cities (in meters).
## 30 largest cities
origins <- french_cities[1:30, c("th_longitude", "th_latitude")]
## 20 smallest cities
destinations <- french_cities[
(nrow(french_cities) - 19):nrow(french_cities),
c("th_longitude", "th_latitude")
]
## cost matrix
cost_matrix <-
french_cities_distances[
1:30,
(nrow(french_cities) - 19):nrow(french_cities)
]
rownames(cost_matrix) <- french_cities[1:30, "name"]
colnames(cost_matrix) <-
french_cities[(nrow(french_cities) - 19):nrow(french_cities), "name"]
Additionally, since we focus on production-constrained models, we
must specify the production for each origin location (a vector of
positive values
X <- rep(1, nrow(origins))
Finally, the simple static model requires an attractiveness value
for each destination location, a vector of positive values
Z <- rep(1, nrow(destinations))
We could use the population of the cities as production constraints for instance.
In Wilson’s production-constrained maximum entropy model, the flows are given by
where
The model is obtained using the static_blvim() function:
a_model <- static_blvim(cost_matrix, X, alpha = 1.1, beta = 1 / 500000, Z)
a_model
#> Spatial interaction model with 30 origin locations and 20 destination locations
#> • Model: Wilson's production constrained
#> • Parameters: return to scale (alpha) = 1.1 and inverse cost scale (beta) =
#> 2e-06
Several functions are provided to extract parts of the result. In
particular flows() returns the flow matrix
a_model_flows <- flows(a_model)
which can be displayed using, for instance, the image() function.
par(mar = rep(0.1, 4))
image(t(a_model_flows)[, 30:1],
col = gray.colors(20, start = 1, end = 0),
axes = FALSE,
frame = TRUE
)
In this representation, each row shows the flows from one origin
location to all destination locations. The package also provides a
ggplot2::autoplot() function, which can be used as follows:
library(ggplot2)
autoplot(a_model, "full") +
scale_fill_gradient(low = "white", high = "black") +
coord_fixed()
b_model <- static_blvim(cost_matrix, X, alpha = 1.1, beta = 1 / 100000, Z)
b_model
#> Spatial interaction model with 30 origin locations and 20 destination locations
#> • Model: Wilson's production constrained
#> • Parameters: return to scale (alpha) = 1.1 and inverse cost scale (beta) =
#> 1e-05
autoplot(b_model) +
scale_fill_gradient(low = "white", high = "black") +
coord_fixed()
As the two figures above exemplify, different values of the parameters
A. Wilson’s Boltzmann–Lotka–Volterra (BLV) interaction model builds upon the production-constrained maximum entropy model. The core idea is to update the attractiveness of the destination locations based on their incoming flows.
Ideally, we aim for the following condition to hold in the limit:
where the flows are given by the equations above. The model is estimated
using the blvim() function as follows.
a_blv_model <- blvim(cost_matrix, X, alpha = 1.1, beta = 1 / 500000, Z)
a_blv_model
#> Spatial interaction model with 30 origin locations and 20 destination locations
#> • Model: Wilson's production constrained
#> • Parameters: return to scale (alpha) = 1.1 and inverse cost scale (beta) =
#> 2e-06
#> ℹ The BLV model converged after 4800 iterations.
Notice that we start with some initial values of the attractiveness, but
the final values are different. These final values can be obtained using
the attractiveness() function (and visualised here using a bar plot).
par(mar = c(0.1, 4, 1, 0))
a_final_Z <- attractiveness(a_blv_model)
barplot(a_final_Z)
autoplot(a_blv_model) +
scale_fill_gradient(low = "white", high = "black")
The autoplot() function can also be used to show the destination flows
or the attractivenesses values:
autoplot(a_blv_model, "attractiveness", with_names = TRUE) +
coord_flip()
Naturally, the results are strongly influenced by the parameters, as shown in this second example.
b_blv_model <- blvim(cost_matrix, X, alpha = 1.1, beta = 1 / 50000, Z)
b_blv_model
#> Spatial interaction model with 30 origin locations and 20 destination locations
#> • Model: Wilson's production constrained
#> • Parameters: return to scale (alpha) = 1.1 and inverse cost scale (beta) =
#> 2e-05
#> ℹ The BLV model converged after 5700 iterations.
autoplot(b_blv_model, "attractiveness", with_names = TRUE) +
coord_flip()
autoplot(b_blv_model, with_names = TRUE) +
scale_fill_gradient(low = "white", high = "black") +
theme(axis.text.x = element_text(angle = 90))
bvlim offers a collection of graphical representations that can
leverage the data associated to the origin and destination locations.
For instance, we can display the full flows using geographical
coordinates of the cities.
origin_positions(b_blv_model) <- as.matrix(origins)
destination_positions(b_blv_model) <- as.matrix(destinations)
autoplot(b_blv_model,
with_positions = TRUE,
show_destination = TRUE,
show_production = TRUE,
cut_off = 0
) +
scale_linewidth(range = c(0, 1.5)) +
coord_sf(crs = "epsg:4326") +
scale_color_discrete(type = c("darkorange", "blueviolet"))








