Population histories¤
Population histories specify effective population sizes and interval durations. A demographic transition combines a history, frequency map, backend, and evolution method to propagate distributions across the history.
drifft.Demography(equinox.Module)
[source]
¤
A population history specified at successive generation boundaries.
Sizes run from oldest to newest. Each interval holds the source size for
generations[i] - 1 generations, then changes size on the final generation.
Repeated sizes are valid; a single size with no durations is an identity
history. No equilibrium initialization is implied.
initial_ne
property
¤
Initial diploid effective population size, ne[0], as a Python integer.
final_ne
property
¤
Final diploid effective population size, ne[-1], as a Python integer.
total_generations
property
¤
Total interval duration as a Python integer; zero for an identity history.
__init__(self, ne: collections.abc.Iterable[int] | jax.Array, generations: collections.abc.Iterable[int] | jax.Array) -> None
¤
Initialize Demography.
Arguments:
ne: Nonempty sequence of positive integer diploid effective population sizes, ordered oldest to newest. Each size represents2 * negene copies.generations: Positive integer durations between successive sizes, with exactly one fewer entry thanne.
Lists and concrete one-dimensional integer arrays are converted to host tuples. Construct outside JIT.
Returns:
None.
Raises:
ValueError for invalid lengths, noninteger entries, or nonpositive entries.
Population sizes and durations are structural, not differentiable parameters.
drifft.DemographicTransition(equinox.Module)
[source]
¤
Compose constant-size evolution and rectangular boundary transitions.
An interval of g generations holds its source size for g-1 generations, then changes size on its last generation. Sequential provides a matched expectation transpose. Both Krylov methods support all backends for forward evolution only. Frequency-map parameters remain differentiable array leaves.
__init__(self, demography: Demography, *, backend: collections.abc.Callable[[int], drifft._backend._base.AbstractTransitionBackend], frequency_map: AbstractFrequencyMap, boundary_backend: collections.abc.Callable[[int], drifft._backend._base.AbstractTransitionBackend] | None = None, method: drifft._evolution.methods.AbstractEpochMethod | None = None) -> None
¤
Prepare reusable geometry outside JIT.
Arguments:
demography: Population history, oldest to newest.backend: Factory receiving a gene-copy count for constant-size geometry.frequency_map: Process shared by every generation.boundary_backend: Factory for rectangular transitions; defaults to the hold geometry for all backends.method: Geometry-free epoch algorithm; defaults toSequential().
Returns:
None. Prepares one geometry per distinct size, sharing hold and boundary
geometry when the same factory is used.
Raises:
TypeError for unsupported combinations, including histories without holds;
ValueError for incorrect backend sizes. RationalKrylov selects dense LU
for Jacobi and GMRES for other transition backends. Dense is intended for
small reference calculations; optimized backends avoid a dense population
matrix.
advance(self, distribution: Array, *, throw: bool = True) -> DemographicResult
¤
Propagate full population mass to the final generation boundary.
Arguments:
distribution: Real vector of length2 * initial_ne + 1, converted to float64.throw: Raise on numerical failure; False returns status and diagnostics. Under vmap a failure with True may fail the whole batch.
Returns:
DemographicResult containing final mass and each interval's outcome.
Raises:
ValueError for incompatible shapes; runtime errors for invalid process
domains or, with throw=True, numerical failure. No mass normalization occurs.
advance_segregating(self, distribution: Array, *, mutation_rate: float | jax.Array = 0.0, throw: bool = True) -> DemographicResult
¤
Evolve interior mass with singleton immigration after every generation.
Arguments:
distribution: Real interior mass of length2 * initial_ne - 1.mutation_rate: Finite nonnegative scalar per-copy rate. Each generation adds2 * destination_ne * mutation_rateat count one.throw: Raise on numerical failure; under vmap may fail the whole batch.
Returns:
DemographicResult; the distribution has length 2 * final_ne - 1.
Raises:
ValueError for invalid shapes. Invalid mutation rates and process domains
raise even with throw=False; numerical failures otherwise return status.
expect(self, values: Array) -> Array
¤
Compute the matched expectation transpose for Sequential histories.
Arguments:
values: Real vector of length2 * final_ne + 1, converted to float64.
Returns:
Float64 expectations of length 2 * initial_ne + 1.
Raises:
ValueError for incompatible shapes or a non-Sequential method, which
does not provide a matched transpose of its input-dependent approximation.
drifft.DemographicResult(builtins.tuple)
[source]
¤
Final mass and per-interval numerical outcomes, without a total error certificate.
status retains the first numerical failure. Identity histories have empty
diagnostics and still check mass finiteness. No factorization or basis is retained.
Fields:
distribution: Float64 mass of length2 * final_ne + 1, or2 * final_ne - 1for segregating evolution; not normalized.converged: Scalar boolean, true when the entire history succeeded.status: First numerical failure in chronological order, or success.diagnostics: Tuple ofIntervalDiagnostics, one per interval in order. Local error estimates are not a bound on the total propagated error.
drifft.IntervalDiagnostics(builtins.tuple)
[source]
¤
Numerical outcome for one complete demographic interval.
source_ne and destination_ne are diploid population sizes; generations
includes both the hold and final boundary generation. error_estimate
covers only the hold power approximation, while converged and status
also account for nonfinite boundary output.
Fields:
source_ne,destination_ne: Python integers giving diploid sizes.generations: Interval duration, including its final boundary generation.error_estimate: Scalar absolute L1 hold-power estimate, zero without a hold.converged: Scalar boolean for the complete interval.status: First hold or boundary failure, or successfulEvolutionStatus.