laser.core.migration
laser.core.migration
This module provides various functions to calculate migration networks based on different models, including the gravity model, competing destinations model, Stouffer's model, and the radiation model.
Additionally, it includes a utility function to calculate the great-circle distance between two points on the Earth's surface using the Haversine formula.
Functions:
| Name | Description |
|---|---|
gravity |
np.ndarray, distances: np.ndarray, k: float, a: float, b: float, c: float, max_frac: Union[float, None]=None, kwargs) -> np.ndarray: Compute a gravity-model migration network based on origin and destination populations and pairwise distances. |
row_normalizer |
np.ndarray, max_rowsum: float) -> np.ndarray: Normalize the rows of a given network matrix such that no row sum exceeds a specified maximum value. |
competing_destinations |
np.ndarray, distances: np.ndarray, b: float, c: float, delta: float, params) -> np.ndarray: Compute a migration network using the competing-destinations model, incorporating the influence of alternative destination nodes. |
stouffer |
np.ndarray, distances: np.ndarray, k: float, a: float, b: float, include_home: bool, params) -> np.ndarray: Compute a migration network using a modified Stouffer's model. |
radiation |
np.ndarray, distances: np.ndarray, k: float, include_home: bool, params) -> np.ndarray: Compute a migration network using the radiation model, which models flows based on intervening population rather than physical distance. |
distance |
float, lon1: float, lat2: float, lon2: float) -> float: Calculate the great-circle distance between two points on the Earth's surface using the Haversine formula. |
laser.core.migration.competing_destinations(pops, distances, k, a, b, c, delta, **params)
Calculate the competing destinations model for a given set of populations and distances. (Fotheringham AS. Spatial flows and spatial patterns. Environment and planning A. 1984;16(4):529-543)
This function computes a network matrix based on the gravity model and then adjusts it using the competing destinations model. The adjustment is done by considering the interference from other destinations.
Mathematical formula
Element-by-element: $$ network_{i,j} = k \times p_i^a \times p_j^b / distance_{i,j}^c \times \sum_k {(p_k^b / distance_{j,k}^c \text {\small for k not in [i,j]})^{delta} } $$
As-implemented numpy math:
- Compute all terms up to the sum_k using the gravity model
- Construct the matrix inside the sum:
p**b * distances**(1-c) - Sum on the second axis (k), and subtract off the diagonal (j=k terms):
row_sums = np.sum(competition_matrix, axis=1) - np.diag(competition_matrix) - Now element-by-element, subtract k=i terms off the sum, exponentiate, and multiply the original network term:
network[i][j] = network[i][j] * (row_sums[i] - competition_matrix[i][j]) ** delta
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pops
|
ndarray
|
Array of populations. |
required |
distances
|
ndarray
|
Array of distances between locations. |
required |
k
|
float
|
Scaling constant. |
required |
a
|
float
|
Exponent for the population of the origin. |
required |
b
|
float
|
Exponent parameter for populations in the gravity model. |
required |
c
|
float
|
Exponent parameter for distances in the gravity model. |
required |
delta
|
float
|
Exponent parameter for the competing destinations adjustment. |
required |
params
|
dict
|
Additional parameters to be passed to the gravity model. |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
network |
ndarray
|
Adjusted network matrix based on the competing destinations model. |
laser.core.migration.distance(lat1, lon1, lat2=None, lon2=None)
Calculate the great-circle distance between two points on the Earth's surface. This function uses the Haversine formula to compute the distance between two points specified by their latitude and longitude in decimal degrees.
- If
lat2andlon2are not provided, they default tolat1andlon1, respectively. This supports the default case of calculating the NxN matrix of distances between all pairs of points in (lat1,lon1). - If all arguments are scalars, will return a single scalar distance, (
lat1,lon1) to (lat2,lon2). - If
lat2,lon2are vectors, will return a vector of distances, (lat1,lon1) to each lat/lon inlat2,lon2. - If
lat1,lon1andlat2,lon2are vectors, will return a matrix with shape (N, M) of distances where N is the length oflat1/lon1and M is the length oflat2/lon2.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lat1
|
float
|
Latitude of the first point(s) in decimal degrees [-90, 90]. |
required |
lon1
|
float
|
Longitude of the first point(s) in decimal degrees [-180, 180]. |
required |
lat2
|
float
|
Latitude of the second point(s) in decimal degrees [-90, 90]. |
None
|
lon2
|
float
|
Longitude of the second point(s) in decimal degrees [-180, 180]. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
distance |
float
|
The distance between the points in kilometers. |
laser.core.migration.gravity(pops, distances, k, a, b, c, **kwargs)
Calculate a gravity model network.
This function computes a gravity model network based on the provided populations and distances. The gravity model estimates migration or interaction flows between populations using a mathematical formula that incorporates scaling, population sizes, and distances.
Mathematical formula:: $$ network_{i,j} = k \cdot \frac{p_i^a \cdot p_j^b}{distance_{i,j}^c} $$
As implemented in NumPy::
1 | |
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pops
|
ndarray
|
1D array of population sizes for each node. |
required |
distances
|
ndarray
|
2D array of distances between nodes. Must be symmetric, with self-distances (diagonal) handled. |
required |
k
|
float
|
Scaling constant to adjust the overall magnitude of interaction flows. |
required |
a
|
float
|
Exponent for the population size of the origin node. |
required |
b
|
float
|
Exponent for the population size of the destination node. |
required |
c
|
float
|
Exponent for the distance between nodes, controlling how distance impacts flows. |
required |
kwargs
|
dict
|
Additional keyword arguments (not used in the current implementation). |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
network |
ndarray
|
A 2D matrix representing the interaction network, where each element |
Example usage::
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Notes
- The diagonal of the distances matrix is set to 1 internally to avoid division by zero.
- The diagonal of the output network is set to 0 to represent no self-loops.
- Ensure the distances matrix is symmetric and non-negative.
laser.core.migration.radiation(pops, distances, k, include_home, **params)
Calculate the migration network using the radiation model.
(Simini F, González MC, Maritan A, Barabási AL. A universal model for mobility and migration patterns. Nature. 2012;484(7392):96-100.)
Mathematical formula
Element-by-element:
$$
network_{i,j} = k \times p_i^a \times (p_j / \sum_k {p_k} )^b,
$$
where the sum proceeds over all \(k\) such that \(distances_{i,k} \leq distances_{i,j}\)
the parameter include_home determines whether \(p_i\) is included or excluded from the sum.
As-implemented numpy math:
- Sort each row of the distance matrix (we'll use \' below to indicate distance-sorted vectors)
-
Loop over "source nodes" i
- Cumulative sum the sorted populations, ensuring appropriate handling when there are multiple destinations equidistant from the source
- Subtract the source node population if
include_homeisFalse - Construct the row of the network matrix as $$ k \times p_i \times p_{j'} / (p_i + \sum_{k'} {p_{k'}}) / (p_i + p_{j'} + \sum_{k'} {p_{k'}}) $$
-
Unsort the rows of the network
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pops
|
ndarray
|
Array of population sizes for each node. |
required |
distances
|
ndarray
|
2D array of distances between nodes. |
required |
k
|
float
|
Scaling factor for the migration rates. |
required |
include_home
|
bool
|
Whether to include the home population in the calculations. |
required |
params
|
dict
|
Additional parameters (currently not used). |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
network |
ndarray
|
2D array representing the migration network. |
laser.core.migration.row_normalizer(network, max_rowsum)
Normalizes the rows of a given network matrix such that no row sum exceeds a specified maximum value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
network
|
ndarray
|
A 2D array representing the network matrix. |
required |
max_rowsum
|
float
|
The maximum allowable sum for any row in the network matrix. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
network |
ndarray
|
The normalized network matrix where no row sum exceeds the specified maximum value. |
laser.core.migration.stouffer(pops, distances, k, a, b, include_home, **params)
Computes a migration network using a modified Stouffer's model.
(Stouffer SA. Intervening opportunities: a theory relating mobility and distance. American sociological review. 1940;5(6):845-867)
Mathematical formula
Element-by-element:
$$
network_{i,j} = k \times p_i \times p_j / ( (p_i + \sum_k {p_k}) (p_i + p_j + \sum_k {p_k}) )
$$
the parameter include_home determines whether \(p_i\) is included or excluded from the sum
As-implemented numpy math:
- Sort each row of the distance matrix (we'll use \' below to indicate distance-sorted vectors)
-
Loop over "source nodes" i:
- Cumulative sum the sorted populations, ensuring appropriate handling when there are multiple destinations equidistant from the source
- Subtract the source node population if
include_homeisFalse - Construct the row of the network matrix as \(k \times p_i^a \times (p_{j'} / \sum_{k'} {p_{k'}})^b\)
-
Unsort the rows of the network
Parameters:
1 2 3 4 5 6 7 | |
Returns:
| Name | Type | Description |
|---|---|---|
network |
ndarray
|
A 2D array representing the migration network, where |