{"id":41412127,"url":"https://github.com/fabrice-rossi/blvim","last_synced_at":"2026-01-23T13:36:59.225Z","repository":{"id":281238171,"uuid":"930911464","full_name":"fabrice-rossi/blvim","owner":"fabrice-rossi","description":"Boltzmann–Lotka–Volterra Interaction Model","archived":false,"fork":false,"pushed_at":"2026-01-18T15:14:17.000Z","size":21154,"stargazers_count":2,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-18T21:11:01.225Z","etag":null,"topics":["boltzmann-lotka-volterra","r","r-package","r-stats","spatial-analysis","spatial-interaction-modeling"],"latest_commit_sha":null,"homepage":"https://fabrice-rossi.github.io/blvim/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fabrice-rossi.png","metadata":{"files":{"readme":"README.Rmd","changelog":"NEWS.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":"codemeta.json","zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-02-11T12:19:10.000Z","updated_at":"2026-01-18T15:10:34.000Z","dependencies_parsed_at":"2025-03-07T19:28:29.046Z","dependency_job_id":"cb0a5edb-9eec-4d1f-9acf-f8212db3dba7","html_url":"https://github.com/fabrice-rossi/blvim","commit_stats":null,"previous_names":["fabrice-rossi/blvim"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/fabrice-rossi/blvim","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabrice-rossi%2Fblvim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabrice-rossi%2Fblvim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabrice-rossi%2Fblvim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabrice-rossi%2Fblvim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fabrice-rossi","download_url":"https://codeload.github.com/fabrice-rossi/blvim/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabrice-rossi%2Fblvim/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28693324,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-23T11:01:27.039Z","status":"ssl_error","status_checked_at":"2026-01-23T11:00:26.909Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["boltzmann-lotka-volterra","r","r-package","r-stats","spatial-analysis","spatial-interaction-modeling"],"created_at":"2026-01-23T13:36:59.159Z","updated_at":"2026-01-23T13:36:59.218Z","avatar_url":"https://github.com/fabrice-rossi.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\noutput: \n  github_document\n---\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r, include = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\",\n  out.width = \"100%\"\n)\n```\n\n# blvim: Boltzmann–Lotka–Volterra Interaction Model \u003ca href=\"https://fabrice-rossi.github.io/blvim/\"\u003e\u003cimg src=\"man/figures/logo.svg\" align=\"right\" height=\"139\" alt=\"blvim website\" /\u003e\u003c/a\u003e\n\n\u003c!-- badges: start --\u003e\n\n[![R-CMD-check](https://github.com/fabrice-rossi/blvim/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/fabrice-rossi/blvim/actions/workflows/R-CMD-check.yaml) [![Codecov test coverage](https://codecov.io/gh/fabrice-rossi/blvim/graph/badge.svg)](https://app.codecov.io/gh/fabrice-rossi/blvim)\n[![blvim version](https://fabrice-rossi.r-universe.dev/blvim/badges/version)](https://fabrice-rossi.r-universe.dev/blvim)\n[![blvim status](https://fabrice-rossi.r-universe.dev/blvim/badges/checks)](https://fabrice-rossi.r-universe.dev/blvim)\n\u003c!-- badges: end --\u003e\n\n`blvim` implements A. Wilson's **Boltzmann–Lotka–Volterra (BLV) interaction model**. \nThe model is described in \n[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](http://dx.doi.org/10.1098/rsif.2007.1288).\n\nThe package's primary goal is to provide a fast implementation of the BLV \nmodel, complete with a collection of tools designed to explore the results \nthrough statistical summaries and graphical representations. The secondary goal \nis to facilitate the systematic assessment of how model parameters impact \nthe results, again using summaries and graphical representations \n(see `vignette(\"grid\")` for details on this aspect).\n\n## Installation\n\nYou can install `blvim` from CRAN with:\n\n``` r\ninstall.packages('blvim')\n```\n\nYou can install the development  version from \n[R-universe](https://r-universe.dev/) with:\n\n``` r\ninstall.packages('blvim', repos = c('https://fabrice-rossi.r-universe.dev'))\n```\n\n## Spatial interaction models\n\n**Spatial interaction models** aim to estimate flows between locations, such as \nworkers commuting from residential zones to employment zones. The `blvim` \npackage focuses on the maximum entropy models developed by Alan Wilson. \nSee `vignette(\"theory\")` for the theoretical background.\n\nIn practice, if we have $n$ origin locations and $p$ destination locations, the\ngoal is to compute a flow matrix $(Y_{ij})_{1\\leq i\\leq n, 1\\leq j\\leq p}$, where\n$Y_{ij}$ is the flow from origin $i$ to destination $j$. This computation relies \non characteristics of the origin and destination locations, along with a matrix \nof exchange difficulties, known as a **cost matrix**, \n$(c_{ij})_{1\\leq i\\leq n, 1\\leq j\\leq p}$. For example, $c_{ij}$ can represent \nthe distance between origin $i$ and destination $j$.\n\n## Usage\n\nThe package is loaded in a standard way.\n```{r}\nlibrary(blvim)\n```\n\n### Input data\n\nTo compute a spatial interaction model with `blvim`, you need at least a cost \nmatrix. The package comes with distance data for a selection of large French\ncities. We use the 30 largest ones as origin locations and the 20 smallest ones\nas destination locations. The cost matrix is the distance between the cities \n(in meters).\n\n```{r}\n## 30 largest cities\norigins \u003c- french_cities[1:30, c(\"th_longitude\", \"th_latitude\")]\n## 20 smallest cities\ndestinations \u003c- french_cities[\n  (nrow(french_cities) - 19):nrow(french_cities),\n  c(\"th_longitude\", \"th_latitude\")\n]\n## cost matrix\ncost_matrix \u003c-\n  french_cities_distances[\n    1:30,\n    (nrow(french_cities) - 19):nrow(french_cities)\n  ]\nrownames(cost_matrix) \u003c- french_cities[1:30, \"name\"]\ncolnames(cost_matrix) \u003c-\n  french_cities[(nrow(french_cities) - 19):nrow(french_cities), \"name\"]\n```\n\nAdditionally, since we focus on **production-constrained models**, we must \nspecify the production for each origin location (a vector of positive values \n$(X_i)_{1\\leq i\\leq n}$). Here, we assume a common unitary production.\n\n```{r}\nX \u003c- rep(1, nrow(origins))\n```\n\nFinally, the simple **static** model requires an attractiveness value for each \ndestination location, a vector of positive values $(Z_j)_{1\\leq j\\leq p}$. We \nagain assume a common unitary attractiveness.\n\n```{r}\nZ \u003c- rep(1, nrow(destinations))\n```\n\nWe could use the population of the cities as production constraints for instance. \n\n### Static models\nIn Wilson's production-constrained maximum entropy model, the flows are given\nby\n\n$$\nY_{ij} = \\frac{X_iZ_j^{\\alpha}\\exp(-\\beta c_{ij})}{\\sum_{k=1}^pZ_k^{\\alpha}\\exp(-\\beta c_{ik})},\n$$\n\nwhere $\\alpha$ is a return-to-scale parameter and $\\beta$ is the inverse of a\ncost scale parameter. Note that the flow matrix is **production-constrained**, \nmeaning that the total outgoing flow from any origin location is equals \nthe production of that location:\n\n$$\n\\forall i,\\quad X_i=\\sum_{j=1}^{p}Y_{ij}.\n$$\n\nThe model is obtained using the `static_blvim()` function:\n```{r}\na_model \u003c- static_blvim(cost_matrix, X, alpha = 1.1, beta = 1 / 500000, Z)\na_model\n```\n\nSeveral functions are provided to extract parts of the result. In particular\n`flows()` returns the flow matrix $Y$. \n```{r}\na_model_flows \u003c- flows(a_model)\n```\nwhich can be displayed using, for instance, the `image()` function.\n```{r a_flow}\n#| fig.height: 11\n#| fig.width: 6.5\n#| out.width: 50%\n#| fig.align: center\n#| fig.alt: \u003e\n#|   A matrix representation of the flows. It shows no particular structure\n#|   in the flow apart from a dominating flow from Nice to Cagnes-sur-Mer.\npar(mar = rep(0.1, 4))\nimage(t(a_model_flows)[, 30:1],\n  col = gray.colors(20, start = 1, end = 0),\n  axes = FALSE,\n  frame = TRUE\n)\n```\n\nIn this representation, each row shows the flows from one origin location to all\ndestination locations. The package also provides a `ggplot2::autoplot()` \nfunction, which can be used as follows:\n\n```{r a_flow_ggplot2}\n#| fig.height: 10\n#| fig.width: 8\n#| out.width: 80%\n#| fig.align: center\n#| fig.alt: \u003e\n#|   A matrix representation of the flows. The color scheme is more contrasted\n#|   than in the previous figure, but does not show much more strucutre. The\n#|   dominating flow is Nice to Cagnes-sur-Mer, but the figure shows that there\n#|   are additional important flows.\nlibrary(ggplot2)\nautoplot(a_model, \"full\") +\n  scale_fill_gradient(low = \"white\", high = \"black\") +\n  coord_fixed()\n```\n\n\n\n```{r}\nb_model \u003c- static_blvim(cost_matrix, X, alpha = 1.1, beta = 1 / 100000, Z)\nb_model\n```\n\n```{r b_flow}\n#| fig.height: 10\n#| fig.width: 8\n#| out.width: 80%\n#| fig.align: center\n#| fig.alt: \u003e\n#|   A matrix representation of the flows. The flows are much more concentrated\n#|   than with the previous choice of parameters. Many destination locations\n#|   do not receive any flow. Most of the flow goes to Vaulx-en-Vellin, Arles,\n#|   Albi and Cagnes-sur-mer.\nautoplot(b_model) +\n  scale_fill_gradient(low = \"white\", high = \"black\") +\n  coord_fixed()\n```\n\nAs the two figures above exemplify, different values of the parameters $\\alpha$ \nand $\\beta$ result in more or less concentrated flows.\n\n\n### Dynamic models\n\nA. Wilson's **Boltzmann–Lotka–Volterra (BLV) interaction model** builds upon the\nproduction-constrained maximum entropy model. The core idea is to update the \nattractiveness of the destination locations based on their incoming flows.\n\nIdeally, we aim for the following condition to hold in the limit:\n\n$$\nZ_j =\\sum_{i=1}^{n}Y_{ij}, \n$$\n\nwhere the flows are given by the equations above. The model is estimated using\nthe `blvim()` function as follows.\n\n```{r}\na_blv_model \u003c- blvim(cost_matrix, X, alpha = 1.1, beta = 1 / 500000, Z)\na_blv_model\n```\n\nNotice that we start with some initial values of the attractiveness, but the \nfinal values are different. These final values can be obtained using the \n`attractiveness()` function (and visualised here using a bar plot).\n\n\n```{r a_blv_Z}\n#| fig.height: 4\n#| fig.width: 8\n#| out.width: 80%\n#| fig.align: center\n#| fig.alt: \u003e\n#|   A bar plot representation of the attractivenesses of the destination\n#|   locations. Only one bar is visible: Vaulx-en-Vellin dominates the\n#|   destination locations.\npar(mar = c(0.1, 4, 1, 0))\na_final_Z \u003c- attractiveness(a_blv_model)\nbarplot(a_final_Z)\n```\nIn this particular example, one destination location acts as a global attractor \nof all the flows. This pattern is also visible in the final flow matrix.\n\n```{r a_blv_flow}\n#| fig.height: 10\n#| fig.width: 8\n#| out.width: 80%\n#| fig.align: center\n#| fig.alt: \u003e\n#|   A matrix representation of the flows. The matrix has only one black column,\n#|   showing that all the flow goes to Vaulx-en-Vellin.\nautoplot(a_blv_model) +\n  scale_fill_gradient(low = \"white\", high = \"black\")\n```\n\nThe `autoplot()` function can also be used to show the destination flows or the\nattractivenesses values:\n```{r a_blv_Z_ggplot2}\n#| fig.height: 4\n#| fig.width: 8\n#| fig.alt: \u003e\n#|   A bar plot representation of the attractivenesses of the destination\n#|   locations. Only one bar is visible: Vaulx-en-Vellin dominates the\n#|   destination locations.\nautoplot(a_blv_model, \"attractiveness\", with_names = TRUE) +\n  coord_flip()\n```\n\nNaturally, the results are strongly influenced by the parameters, as shown in \nthis second example.\n\n```{r}\nb_blv_model \u003c- blvim(cost_matrix, X, alpha = 1.1, beta = 1 / 50000, Z)\nb_blv_model\n```\n\n```{r b_blv_Z}\n#| fig.height: 4\n#| fig.width: 8\n#| fig.alt: \u003e\n#|   A bar plot representation of the attractivenesses of the destination\n#|   locations. Nine out of the twenty destination locations remain\n#|   attractive. Vaulx-en-Vellin is still the most attractive location, but\n#|   Cholet and Arles are quite attractive also. They are closely followed\n#|   by Saint-Ouen-sur-Seine and Saint-Quentin. Then the graph shows a set\n#|   of four remaining attractive destinations but with small values (between\n#|   0.5 and 1.5, compared to 4 or more for the other locations). The cities\n#|   are Albi, Cagnes-sur-Mer, Vannes and Bayonne.\nautoplot(b_blv_model, \"attractiveness\", with_names = TRUE) +\n  coord_flip()\n```\n\n```{r b_blv_flow}\n#| fig.height: 10\n#| fig.width: 8\n#| out.width: 80%\n#| fig.align: center\n#| fig.alt: \u003e\n#|   A matrix representation of the flows. The figure shows essentially the\n#|   same things as the previous bar plot. In most of the cases, the flow\n#|   outgoing from a origin location goes to a unique destination location. The\n#|   main exception is the pair Saint-Ouen-sur-Seine and Saint-Quentin who\n#|   share incoming flows.\nautoplot(b_blv_model, with_names = TRUE) +\n  scale_fill_gradient(low = \"white\", high = \"black\") +\n  theme(axis.text.x = element_text(angle = 90))\n```\n\n`bvlim` offers a collection of graphical representations that can leverage\nthe data associated to the origin and destination locations. For instance, \nwe can display the full flows using geographical coordinates of the cities.\n\n```{r b_blv_france}\n#| fig.height: 8\n#| fig.width: 10\n#| fig.alt: \u003e\n#|   A geographical representation of the flows with dots showing the locations\n#|   and arrows between them representation the flows. The figure tells the\n#|   same story of the previous ones. It shows in particular star patterns with\n#|   a central destination location that receives flows for all the surrounding\n#|   origin locations. The figure confirms that flows are organised in a\n#|   geographical way as most of the flow goes from one origin to its closests\n#|   destination. However, the figure shows also destination locations that\n#|   do not receive any flow, emphasizing the concentration effects associated\n#|   to the return to scale parameter.\norigin_positions(b_blv_model) \u003c- as.matrix(origins)\ndestination_positions(b_blv_model) \u003c- as.matrix(destinations)\nautoplot(b_blv_model,\n  with_positions = TRUE,\n  show_destination = TRUE,\n  show_production = TRUE,\n  cut_off = 0\n) +\n  scale_linewidth(range = c(0, 1.5)) +\n  coord_sf(crs = \"epsg:4326\") +\n  scale_color_discrete(type = c(\"darkorange\", \"blueviolet\"))\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffabrice-rossi%2Fblvim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffabrice-rossi%2Fblvim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffabrice-rossi%2Fblvim/lists"}