A worked example: what the constraint does to one destination

Portugal, 2019, five endemic origins. Reproduced from the model’s own inputs by LCD_mobility/worked_example_v1_v2.py, which reimplements distanceMatrixgetsMatrixtravelProbMattravelRateMatconstrain_travel_matrix in Python.

Status of the numbers. The constrained side (A_obs, φ, the constrained pair totals) is exact: it comes from UN Tourism and arithmetic, and needs no kernel. The kernel side is a faithful reimplementation, not a bit-identical copy of a MATLAB run — the reconstructed 2019 panel holds 1,667 rows (170 countries + 1,497 NUTS3) against MATLAB’s 1,634, so kernel figures should be read to two significant figures, and the ratios rather than the last digits are the point.


1. The travel input

v1 carries one number per origin per year — TravProp, total outbound trips per head, with no destination dimension. Where those trips land is decided entirely by the radiation kernel.

v2 carries the same TravProp plus the observed bilateral total A_obs(O,J,y) from UN Tourism, and rescales the kernel’s pair total onto it.

origin tProp (trips/head) population A_obs → Portugal T_ker (kernel pair total) φ = A_obs/T_ker
Brazil 0.0523 211,782,878 1,298,714 2,967.0 437.7
Thailand 0.1728 71,307,763 15,683 184.4 85.0
India 0.0144 1,383,112,050 73,123 16,494.2 4.4
Mexico 0.1805 125,085,311 47,926 1,245.9 38.5
Philippines 0.0719 110,380,804 15,832 165.4 95.7

The first column is identical in v1 and v2. Everything to the right of it exists only in v2.

Read the last column as the size of the error the submitted model was carrying. The kernel put 2,967 Brazilians into Portugal in 2019; UN Tourism counts 1.3 million. The kernel is not wrong by a percentage, it is wrong by a factor of 438 on this pair — and by only 4.4 on India, which is the more damaging fact, because it means the error is not a constant the incidence term could absorb. It is a reallocation between origins. The radiation model has no colonial history, no language, no diaspora; Brazil→Portugal is exactly the pair it cannot see.

2. The rate matrix

travelRateMat returns rates, not probabilities: r(a,b) = tp(b)·N(b) · p(a,b), where b is the column and the origin. Rates into Portugal’s NUTS3 regions, six largest by population:

NUTS3 region v1 (kernel) v2 (constrained) within-country share
PT170 Área Metropolitana de Lisboa 812.0 355,410 0.2737
PT11A Área Metropolitana do Porto 395.8 173,235 0.1334
PT150 Algarve 139.2 60,925 0.0469
PT16E Região de Coimbra 124.0 54,282 0.0418
PT11C Tâmega e Sousa 96.0 42,003 0.0323
PT119 Ave 94.9 41,540 0.0320

(Brazil column. The full five-origin table is worked_example_v1_v2_nuts3.csv.)

Every v2 entry is its v1 entry times the single scalar φ(BRA,PRT) = 437.7. The share column is therefore identical in v1 and v2, and sums to 1 in both. The constraint takes the allocation between countries away from the kernel and leaves the allocation within a country entirely to it.

Pair totals, as a check on the whole operation:

origin v1 kernel total v2 constrained total A_obs difference
BRA 2,967.006 1,298,714.000 1,298,714 0.0000
THA 184.433 15,683.000 15,683 0.0000
IND 16,494.213 73,123.000 73,123 0.0000
MEX 1,245.887 47,926.000 47,926 0.0000
PHL 165.398 15,832.000 15,832 0.0000

Binding to machine precision, by construction, on every observed pair.

3. The p matrix

travelProbMat — p(a,b) = (nᵢnⱼ)/((nᵢ+s)(nᵢ+nⱼ+s)) — is unchanged between v1 and v2. The constraint multiplies the rate matrix, never the probability kernel:

NUTS3 region BRA THA IND MEX PHL
PT170 A. M. de Lisboa 7.333e-05 4.131e-06 2.268e-04 1.379e-05 5.773e-06
PT11A A. M. do Porto 3.574e-05 2.514e-06 1.395e-04 8.529e-06 3.494e-06
PT150 Algarve 1.257e-05 6.469e-07 3.500e-05 2.106e-06 8.906e-07
PT16E Região de Coimbra 1.120e-05 6.338e-07 3.547e-05 2.140e-06 8.809e-07
PT11C Tâmega e Sousa 8.666e-06 6.093e-07 3.410e-05 2.067e-06 8.469e-07

This is the sentence to give a referee: the radiation model is retained in full and unmodified; what changed is that its country-pair totals are now anchored to observed bilateral arrivals rather than left to a kernel calibrated on U.S. county commuting.

4. What this means for the paper

Three points worth carrying into the Methods.

  1. The constraint is one scalar per (origin, destination, year). It has no free parameters and nothing in it is fitted to the ECDC/CDC validation series.
  2. It cannot change the sub-national pattern of any figure, because within-country shares are algebraically invariant under it. Every sub-national result in the paper is still the radiation model’s.
  3. It changes the between-country composition by up to two orders of magnitude on individual pairs, and unequally across origins — which is why the resident channel moved from 3–5% of importations to the majority. That was not a bug; it was the kernel’s misallocation being removed.

Files

  • LCD_mobility/worked_example_v1_v2.py
  • LCD_mobility/worked_example_v1_v2_summary.csv — the φ table
  • LCD_mobility/worked_example_v1_v2_nuts3.csv — per-NUTS3, all five origins
  • LCD_mobility/worked_example_v1_v2_pmatrix.csv — the unchanged p matrix

Written 26 August 2026.