Neutral landscape models¶
Simulated landscapes that follow a known rule (complete randomness, a
gradient, clustering, fractal roughness) and nothing else: the null models of
landscape ecology, to test whether a pattern or a process differs from what
chance alone would give. They live in the ls.nlm module. Tutorial:
neutral landscapes.
With the same seed every model gives the same landscape as the R package
NLMR, value for value: the random number generators of R and of the C++
library NLMR is built with are reproduced, so studies done in R can be
repeated and extended here.
import landschaft as ls
r = ls.nlm.random(200, 200, seed=42) # a DataArray of values in 0-1
habitat = ls.nlm.classify(r, weighting=[0.7, 0.3])
Random and percolation¶
random
¶
random(
ncol: int,
nrow: int,
resolution: float = 1.0,
seed: int | None = None,
rescale: bool = True,
*,
n_threads: int | None = None,
) -> DataArray
Spatially random neutral landscape model (NLMR's nlm_random).
Every cell gets an independent uniform value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ncol
|
int
|
Columns and rows. |
required |
nrow
|
int
|
Columns and rows. |
required |
resolution
|
float
|
Cell size. |
1
|
seed
|
int
|
Seed of R's generator (NLMR's |
None
|
rescale
|
bool
|
Rescale the values to 0-1 ( |
True
|
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray
|
float64 values on a grid with origin (0, 0) and the given resolution. |
Examples:
percolation
¶
percolation(
ncol: int,
nrow: int,
resolution: float = 1.0,
prob: float = 0.5,
seed: int | None = None,
*,
n_threads: int | None = None,
) -> DataArray
Percolation neutral landscape model (NLMR's nlm_percolation).
Each cell is 1 with probability prob (a Bernoulli draw), else 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ncol
|
int
|
Columns and rows. |
required |
nrow
|
int
|
Columns and rows. |
required |
resolution
|
float
|
Cell size. |
1
|
prob
|
float
|
Probability of a cell being 1. |
0.5
|
seed
|
int
|
Seed of R's generator (NLMR's |
None
|
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray
|
uint8 0/1 values. |
Examples:
Gradients¶
planar_gradient
¶
planar_gradient(
ncol: int,
nrow: int,
resolution: float = 1.0,
direction: float | None = None,
seed: int | None = None,
rescale: bool = True,
*,
n_threads: int | None = None,
) -> DataArray
Planar gradient neutral landscape model (NLMR's nlm_planargradient).
Values increase linearly in one direction across the landscape.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ncol
|
int
|
Columns and rows. |
required |
nrow
|
int
|
Columns and rows. |
required |
resolution
|
float
|
Cell size. |
1
|
direction
|
float
|
Direction of the gradient in degrees, clockwise from north: the values
grow northwards with 0 and eastwards with 90. |
None
|
seed
|
int
|
Seed of R's generator, used only when |
None
|
rescale
|
bool
|
Rescale the values to 0-1. |
True
|
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray
|
float64 values; |
Examples:
edge_gradient
¶
edge_gradient(
ncol: int,
nrow: int,
resolution: float = 1.0,
direction: float | None = None,
seed: int | None = None,
rescale: bool = True,
*,
n_threads: int | None = None,
) -> DataArray
Edge gradient neutral landscape model (NLMR's nlm_edgegradient).
A planar gradient folded around its middle: values peak along a central
band and fall to both edges (1 - 2 |0.5 - g| of the rescaled planar
gradient g).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ncol
|
int
|
Columns and rows. |
required |
nrow
|
int
|
Columns and rows. |
required |
resolution
|
float
|
Cell size. |
1
|
direction
|
float
|
Direction of the gradient in degrees; |
None
|
seed
|
int
|
Seed of R's generator, used only when |
None
|
rescale
|
bool
|
Rescale the values to 0-1. |
True
|
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray
|
float64 values; |
Examples:
distance_gradient
¶
distance_gradient(
ncol: int,
nrow: int,
origin,
resolution: float = 1.0,
rescale: bool = True,
nlmr_compat: bool = True,
*,
n_threads: int | None = None,
) -> DataArray
Distance gradient neutral landscape model (NLMR's nlm_distancegradient).
The distance of every cell to a rectangular origin.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ncol
|
int
|
Columns and rows. |
required |
nrow
|
int
|
Columns and rows. |
required |
origin
|
sequence of 4 ints
|
The origin rectangle, 1-based and inclusive. With |
required |
resolution
|
float
|
Cell size. |
1
|
rescale
|
bool
|
Rescale the values to 0-1. |
True
|
nlmr_compat
|
bool
|
Reproduce NLMR exactly: |
True
|
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray
|
float64 distances (rescaled to 0-1 by default). |
Examples:
Fractal surfaces and random fields¶
mpd
¶
mpd(
ncol: int,
nrow: int,
resolution: float = 1.0,
roughness: float = 0.5,
rand_dev: float = 1.0,
seed: int | None = None,
torus: bool = False,
rescale: bool = True,
nlmr_compat: bool = True,
*,
n_threads: int | None = None,
) -> DataArray
Midpoint displacement neutral landscape model (NLMR's nlm_mpd).
The diamond-square algorithm: a fractal surface whose spatial autocorrelation
is set by roughness (the random deviation shrinks by this factor at every
halving of the grid).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ncol
|
int
|
Columns and rows asked for. |
required |
nrow
|
int
|
Columns and rows asked for. |
required |
resolution
|
float
|
Cell size. |
1
|
roughness
|
float
|
Between 0 and 1: low values give smooth, strongly autocorrelated surfaces, high values rough ones. |
0.5
|
rand_dev
|
float
|
Standard deviation of the displacement at the first step. |
1
|
seed
|
int
|
Seed of NLMR's |
None
|
torus
|
bool
|
Wrap the square steps around the edges (a periodic surface). |
False
|
rescale
|
bool
|
Rescale the values to 0-1. |
True
|
nlmr_compat
|
bool
|
Reproduce NLMR: its grid is a square of side |
True
|
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray
|
float64 values. |
Examples:
fbm
¶
fbm(
ncol: int,
nrow: int,
resolution: float = 1.0,
fract_dim: float = 1.0,
seed: int | None = None,
rescale: bool = True,
*,
n_threads: int | None = None,
) -> DataArray
Fractional Brownian motion neutral landscape model (NLMR's nlm_fbm).
A fractal surface from a power-law spectrum |k|^-(fract_dim + 1) with
random phases (inverse FFT), centred and scaled to unit standard deviation
of the steps between neighbouring cells. fract_dim is the Hurst-like
exponent alpha of NLMR (0 < alpha <= 2): small values give rough surfaces,
large ones smooth ones; alpha = 2 is a random plane.
NLMR 1.4 disabled nlm_fbm when RandomFields left CRAN and ships this
method as its internal simulate_fbm; the results here are that
function's, rescaled as NLMR's previous nlm_fbm did.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ncol
|
int
|
Columns and rows. |
required |
nrow
|
int
|
Columns and rows. |
required |
resolution
|
float
|
Cell size. |
1
|
fract_dim
|
float
|
The exponent alpha, in (0, 2]. |
1
|
seed
|
int
|
Seed of R's generator: the same seed gives NLMR's surface. |
None
|
rescale
|
bool
|
Rescale the values to 0-1. |
True
|
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray
|
float64 values. |
Examples:
gaussian_field
¶
gaussian_field(
ncol: int,
nrow: int,
resolution: float = 1.0,
autocorr_range: float = 10,
mag_var: float = 5,
nug: float = 0.2,
mean: float = 0.5,
seed: int | None = None,
rescale: bool = True,
*,
n_threads: int | None = None,
) -> DataArray
Gaussian random field neutral landscape model (NLMR's nlm_gaussianfield).
A stationary Gaussian field with an exponential covariance
mag_var * exp(-d / autocorr_range), simulated exactly by circulant
embedding (FFT on a grid twice as large in each direction), plus a nugget
(white noise of variance nug) and a mean.
NLMR 1.4 disabled nlm_gaussianfield when RandomFields left CRAN and ships
this method as its internal simulate_gaussian_field; the results here are
that function's, rescaled as NLMR's previous nlm_gaussianfield did.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ncol
|
int
|
Columns and rows. |
required |
nrow
|
int
|
Columns and rows. |
required |
resolution
|
float
|
Cell size. |
1
|
autocorr_range
|
float
|
Range of the spatial autocorrelation, in cells. |
10
|
mag_var
|
float
|
Variance of the autocorrelated part. |
5
|
nug
|
float
|
Variance of the nugget (uncorrelated noise); 0 for none. |
0.2
|
mean
|
float
|
Mean of the field. |
0.5
|
seed
|
int
|
Seed of R's generator: the same seed gives NLMR's field. |
None
|
rescale
|
bool
|
Rescale the values to 0-1. |
True
|
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray
|
float64 values. |
Examples:
Mosaics¶
mosaic_field
¶
mosaic_field(
ncol: int,
nrow: int,
resolution: float = 1.0,
n: int | None = 20,
mosaic_mean: float = 0.5,
mosaic_sd: float = 0.5,
seed: int | None = None,
collect: bool = False,
infinit: bool = False,
rescale: bool = True,
nlmr_compat: bool = True,
*,
n_threads: int | None = None,
)
Mosaic random field neutral landscape model (NLMR's nlm_mosaicfield, Schlather 1999).
The sum of n mosaic fields: each splits the landscape by a Poisson line
tessellation (intensity 4 on the unit square, spatstat's rpoislinetess)
and gives every tile a normal value (rMosaicField). As n grows the sum
tends to a Gaussian random field; infinit=True also returns that limit, a
Gaussian field with exponential covariance (the log intensity of spatstat's
rLGCP("exp", 4, var = 1, scale = 0.2)).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ncol
|
int
|
Columns and rows. |
required |
nrow
|
int
|
Columns and rows. |
required |
resolution
|
float
|
Cell size. |
1
|
n
|
int or None
|
Number of mosaic fields summed; |
20
|
mosaic_mean
|
float
|
Mean and standard deviation of the tile values. |
0.5
|
mosaic_sd
|
float
|
Mean and standard deviation of the tile values. |
0.5
|
seed
|
int
|
Seed of R's generator (NLMR's |
None
|
collect
|
bool
|
Also return every field, the i-th divided by sqrt(i), as NLMR's |
False
|
infinit
|
bool
|
Also return the limiting Gaussian field. |
False
|
rescale
|
bool
|
Rescale to 0-1 (the |
True
|
nlmr_compat
|
bool
|
Reproduce NLMR's quirks described above. |
True
|
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray or dict
|
The summed field; with |
Examples:
mosaic_tess
¶
mosaic_tess(
ncol: int,
nrow: int,
germs: int,
resolution: float = 1.0,
seed: int | None = None,
rescale: bool = True,
nlmr_compat: bool = True,
*,
n_threads: int | None = None,
) -> DataArray
Polygonal (Voronoi) mosaic neutral landscape model (NLMR's nlm_mosaictess, Gaucherel 2008).
germs uniform random points split the landscape into Voronoi tiles, each
with a uniform random value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ncol
|
int
|
Columns and rows. |
required |
nrow
|
int
|
Columns and rows. |
required |
germs
|
int
|
Number of germs (tiles). |
required |
resolution
|
float
|
Cell size. |
1
|
seed
|
int
|
Seed of R's generator (NLMR's |
None
|
rescale
|
bool
|
Rescale the values to 0-1. |
True
|
nlmr_compat
|
bool
|
Reproduce NLMR: the k-th value goes to the k-th tile in the order GEOS
returns the Voronoi cells (found with shapely; without it a warning and
the other assignment), and values are rounded to float32 as
|
True
|
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray
|
float64 values. |
Examples:
mosaic_gibbs
¶
mosaic_gibbs(
ncol: int,
nrow: int,
germs: int,
R: float,
patch_classes: int,
resolution: float = 1.0,
seed: int | None = None,
rescale: bool = True,
nlmr_compat: bool = True,
*,
n_threads: int | None = None,
) -> DataArray
Gibbs-process Voronoi mosaic (NLMR's nlm_mosaicgibbs, Gauchel et al. 2008).
germs points from a simple sequential inhibition process (spatstat's
rSSI: no two points closer than R) split the landscape into Voronoi
tiles; the classes 1..patch_classes, repeated to germs values and
shuffled, are given to the tiles.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ncol
|
int
|
Columns and rows. |
required |
nrow
|
int
|
Columns and rows. |
required |
germs
|
int
|
Number of germs. |
required |
R
|
float
|
Minimum distance between germs, in cells. |
required |
patch_classes
|
int
|
Number of classes. |
required |
resolution
|
float
|
Cell size. |
1
|
seed
|
int
|
Seed of R's generator (NLMR's |
None
|
rescale
|
bool
|
Rescale the classes to 0-1. |
True
|
nlmr_compat
|
bool
|
Reproduce NLMR, which gives the k-th germ's class to the k-th Voronoi polygon in GEOS's order (not to the germ's own tile; found with shapely, without it a warning and the other assignment). With False each germ's tile takes its own class. |
True
|
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray
|
float64 values (classes before rescaling). |
Examples:
Voronoi mosaics and shapely
NLMR gives the tile values in the order in which GEOS returns the Voronoi cells. Landschaft asks GEOS for that order through shapely (installed with it); without shapely the models warn and give each germ its own value. GEOS 3.11 or later is needed for NLMR's order (older versions return the cells in another order, with a warning).
Clusters¶
random_cluster
¶
random_cluster(
ncol: int,
nrow: int,
p: float,
ai: Sequence[float] = (0.5, 0.5),
neighbourhood: int = 4,
resolution: float = 1.0,
seed: int | None = None,
rescale: bool = True,
*,
n_threads: int | None = None,
) -> DataArray
Random cluster neutral landscape model (NLMR's nlm_randomcluster, Saura & Martínez-Millán 2000).
A percolation map with probability p is split into clusters of adjacent
cells, each cluster gets a type drawn with the weights ai, and every
remaining cell takes the most frequent type among its 8 neighbours (a random
one of the tied types; a type drawn with ai when no neighbour has one).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ncol
|
int
|
Columns and rows. |
required |
nrow
|
int
|
Columns and rows. |
required |
p
|
float
|
Share of the cells in the initial percolation map (up to 1). |
required |
ai
|
sequence of float
|
Weights of the types (their share of the clusters). |
(0.5, 0.5)
|
neighbourhood
|
(4, 8)
|
Adjacency of the cells of a cluster. |
4
|
resolution
|
float
|
Cell size. |
1
|
seed
|
int
|
Seed of R's generator (NLMR's |
None
|
rescale
|
bool
|
Rescale the types to 0-1; else the types 1, 2, ... as int32. |
True
|
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray
|
float64 (rescaled) or int32 types. |
Examples:
neigh
¶
neigh(
ncol: int,
nrow: int,
p_neigh: float,
p_empty: float,
resolution: float = 1.0,
categories: int = 3,
neighbourhood: int = 4,
proportions: Sequence[float] | None = None,
seed: int | None = None,
rescale: bool = True,
*,
n_threads: int | None = None,
) -> DataArray
Neighbourhood-based clusters (NLMR's nlm_neigh, Scherer et al. 2016).
Cells are visited in a random order and take the current category with
probability p_neigh when a neighbour already holds one, p_empty
otherwise, which grows clusters of adjustable compactness. The edges wrap
around.
As in NLMR, categories are filled from categories - 1 down to 0 and
"holds one" means a neighbour with a non-zero category.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ncol
|
int
|
Columns and rows. |
required |
nrow
|
int
|
Columns and rows. |
required |
p_neigh
|
float
|
Probability of a cell joining the category when a neighbour holds one. |
required |
p_empty
|
float
|
Probability when no neighbour does. |
required |
resolution
|
float
|
Cell size. |
1
|
categories
|
int
|
Number of categories (values 0 .. categories - 1). |
3
|
neighbourhood
|
(4, 8)
|
Neighbours looked at (8 adds the diagonals when the 4 are empty). |
4
|
proportions
|
sequence of float
|
Share of the cells of each category (summing to 1); by default equal
shares, |
None
|
seed
|
int
|
Seed of NLMR's |
None
|
rescale
|
bool
|
Rescale the values to 0-1; else the categories as int32. |
True
|
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray
|
float64 (rescaled) or int32 categories. |
Examples:
random_rectangular_cluster
¶
random_rectangular_cluster(
ncol: int,
nrow: int,
minl: int,
maxl: int,
resolution: float = 1.0,
seed: int | None = None,
rescale: bool = True,
*,
n_threads: int | None = None,
) -> DataArray
Random rectangular clusters (NLMR's nlm_randomrectangularcluster, Gaucherel 2008).
Rectangles with random sides between minl and maxl cells and a random
value are laid over each other (wrapping around the edges) until every cell is
covered.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ncol
|
int
|
Columns and rows. |
required |
nrow
|
int
|
Columns and rows. |
required |
minl
|
int
|
Smallest and largest side of the rectangles, in cells (at most |
required |
maxl
|
int
|
Smallest and largest side of the rectangles, in cells (at most |
required |
resolution
|
float
|
Cell size. |
1
|
seed
|
int
|
Seed of NLMR's |
None
|
rescale
|
bool
|
Rescale the values to 0-1. |
True
|
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray
|
float64 values. |
Examples:
curds
¶
curds(
curds: Sequence[float],
recursion_steps: Sequence[int],
wheyes: Sequence[float] | None = None,
resolution: float = 1.0,
seed: int | None = None,
*,
n_threads: int | None = None,
) -> DataArray
Hierarchical curdling (NLMR's nlm_curds, Keitt 2000).
Starting from one cell, each step splits every cell into
recursion_steps[i] x recursion_steps[i] cells and turns a share
1 - curds[i] of the habitat cells into matrix; with wheyes, a share
wheyes[i] of the matrix cells goes back to habitat (the "wheyed curds"
model). The raster has prod(recursion_steps) cells a side.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
curds
|
sequence of float
|
Share of the habitat kept at each step. |
required |
recursion_steps
|
sequence of int
|
Subdivision of the cells at each step (same length as |
required |
wheyes
|
sequence of float
|
Share of the matrix turned back into habitat at each step. |
None
|
resolution
|
float
|
Cell size. |
1
|
seed
|
int
|
Seed of R's generator (NLMR's |
None
|
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray
|
uint8: 1 habitat (curds), 0 matrix. |
Examples:
Classification and rescaling¶
classify
¶
classify(
x,
n: int | None = None,
weighting: Sequence[float] | None = None,
level_names: Sequence[str] | None = None,
real_land=None,
mask_val: float | None = None,
*,
n_threads: int | None = None,
)
Classify a continuous landscape into categories (NLMR's landscape_classify).
Three ways, as NLMR:
weighting: class proportions (cumulative, relative to their sum;Noneentries share what is left of 1); the class boundaries are the values at those proportions of the sorted cells, the first class starting at 0 (values below 0 are left out);real_land: the proportions of the classes of a real landscape (after removingmask_val, whose cells are also removed fromx);n: Jenks natural breaks intonclasses (at most the number of unique values). Jenks' algorithm costs O(n_classes x cells^2): keep it to small maps.
weighting wins over n when both are given.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
DataArray or ndarray
|
Continuous values (NaN or the nodata value are missing). |
required |
n
|
int
|
Number of classes for Jenks' breaks. |
None
|
weighting
|
sequence of float
|
Class proportions. |
None
|
level_names
|
sequence of str
|
Class names, stored in |
None
|
real_land
|
DataArray or ndarray
|
A categorical landscape of the same shape whose class proportions are used. |
None
|
mask_val
|
float
|
Value of |
None
|
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray or ndarray
|
int32 classes 1, 2, ...; 0 where |
Examples:
binarize
¶
Habitat / matrix maps at given habitat shares (landscapetools' util_binarize).
Each break b classifies x with classify() into the proportions
1 - b (class 1, "Matrix", the lowest values) and b (class 2,
"Habitat").
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
DataArray or ndarray
|
A continuous landscape. |
required |
breaks
|
float or sequence of float
|
Habitat shares, between 0 and 1. |
required |
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray or ndarray
|
int32 classes 1 (matrix) and 2 (habitat); with several breaks, stacked
along a new first dimension |
Examples:
rescale
¶
Linearly rescale values to 0-1 (NLMR's util_rescale).
(x - min) / (max - min) over the non-missing cells; a raster whose minimum
and maximum are equal within all.equal's tolerance (1.5e-8) becomes 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
DataArray or ndarray
|
Values; NaN (or the DataArray's nodata value) is missing and stays NaN. |
required |
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray or ndarray
|
The rescaled values (float64), of the same kind as |
Examples:
merge
¶
merge(
primary,
secondary,
scaling: float = 1.0,
rescale: bool = True,
*,
n_threads: int | None = None,
)
Merge neutral landscapes (landscapetools' util_merge).
primary + scaling * sum(secondary): a coarse structure (say a gradient)
with finer ones laid over it (say a random field), with scaling setting
their weight.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
primary
|
DataArray or ndarray
|
The primary landscape. |
required |
secondary
|
DataArray, ndarray or sequence of them
|
One or more landscapes of the same shape. |
required |
scaling
|
float
|
Weight of the secondary landscapes. |
1
|
rescale
|
bool
|
Rescale the result to 0-1. |
True
|
n_threads
|
int
|
Threads (default: all cores but one). |
None
|
Returns:
| Type | Description |
|---|---|
DataArray or ndarray
|
The merged landscape, of the same kind as |
Examples: