mixle.stats.processes.ctmc module¶
Continuous-time Markov chain (CTMC) over fully observed trajectories.
A CTMC on K states is governed by a generator matrix Q: off-diagonal q_ij >= 0 is the rate
of jumping i -> j, and q_ii = -sum_{j!=i} q_ij. A fully-observed trajectory is the initial state,
the total observation horizon, and the sequence of (dwell_time, next_state) jumps up to that
horizon; its log-likelihood is
log L = sum_{i!=j} n_ij * log q_ij - sum_i q_i * T_i, q_i = -q_ii = sum_{j!=i} q_ij,
where n_ij is the number of observed i->j transitions and T_i the total time spent in i
including the final, right-censored dwell – from the last jump (or from time 0, if there were no
jumps at all) out to the observation horizon. That final interval is real exposure with no observed
exit, exactly like the tail of a birth-death or renewal-process trajectory censored at its own window
(see mixle.stats.processes.birth_death): a chain that dwells in a state for the whole horizon without
jumping still contributes -q_i * horizon to the log-likelihood, it just contributes no transition
count. Omitting it (as an earlier version of this module did) understates every T_i by the length of
each trajectory’s final interval and biases the closed-form rate MLE upward.
This is a collection of independent Poisson-rate likelihoods, so the MLE is closed form and unique:
q_ij = n_ij / T_i. The estimator therefore certifies GLOBAL_UNIQUE (see
mixle.inference.certify(), which classifies this family). Data type: (s0, horizon, [(dt, s1),
(dt, s2), ...]) – the initial state, the total observation window length, and the observed jumps
(each dt > 0, and the jumps’ dwell times may not sum to more than horizon). The horizon travels
with each trajectory rather than living only on the distribution, matching BirthDeathSamplingDistribution’s
(n0, T, events) convention: different trajectories in one dataset are free to have been observed for
different lengths of time. The distribution’s own initial_state/horizon constructor parameters
are sampling-time defaults (where sample() starts a fresh chain, and for how long) and are round-
tripped through .estimator(); they are not constraints on what a trajectory being scored is allowed
to contain – log_density scores whatever s0 and horizon the trajectory itself declares.
The family follows the standard Mixle distribution contract (Distribution / Sampler / Accumulator / Factory /
Estimator / DataEncoder) so it composes with optimize / seq_log_density / the PPL surface like
every other family.
- class ContinuousTimeMarkovChainStatistics(transition_counts, dwell_times)[source]
Bases:
NamedTupleVersioned, tuple-compatible aggregate CTMC statistics.
- transition_counts: ndarray
Alias for field number 0
- dwell_times: ndarray
Alias for field number 1
- property schema_version: int
Return the serialized statistic schema version.
- class ContinuousTimeMarkovChainDistribution(rates, initial_state=0, horizon=10.0, name=None, keys=None, prior_shape=1.0, prior_rate=0.0)[source]
Bases:
SequenceEncodableProbabilityDistributionCTMC on
Kstates with generatorQ(off-diagonal rates); MLE is closed form (GLOBAL_UNIQUE).- Parameters:
- property generator: ndarray
The generator matrix
Q(off-diagonal rates, diagonal = -exit rate).
- density(x)[source]
Return the probability density of one fully observed trajectory.
- log_density(x)[source]
Return the log-likelihood of one fully observed CTMC trajectory.
- seq_log_density(x)[source]
Return vectorized log-likelihoods for encoded trajectory statistics.
- sampler(seed=None)[source]
Return a Gillespie sampler for trajectories from this CTMC.
- Parameters:
seed (int | None)
- Return type:
ContinuousTimeMarkovChainSampler
- estimator(pseudo_count=None)[source]
Return the closed-form rate estimator for this state space.
pseudo_count=cis the compatibility shorthand for independent off-diagonalGamma(shape=1+c, rate=c)priors. With no override, the distribution’s explicit edgewise priors are preserved.- Parameters:
pseudo_count (float | None)
- Return type:
ContinuousTimeMarkovChainEstimator
- dist_to_encoder()[source]
Return the trajectory-statistics encoder used by vectorized methods.
- Return type:
ContinuousTimeMarkovChainDataEncoder
- class ContinuousTimeMarkovChainSampler(dist, seed=None)[source]
Bases:
DistributionSamplerExact Gillespie simulation of CTMC trajectories on
[0, horizon].- Parameters:
dist (ContinuousTimeMarkovChainDistribution)
seed (int | None)
- class ContinuousTimeMarkovChainAccumulator(num_states, name=None, keys=None)[source]
Bases:
SequenceEncodableStatisticAccumulatorAccumulate the CTMC sufficient statistics: transition counts
n_ijand dwell timesT_i.- update(x, weight, estimate)[source]
Update transition-count and dwell-time statistics from one trajectory.
- initialize(x, weight, rng)[source]
Initialize sufficient statistics from one trajectory.
- Parameters:
x (Any)
weight (float)
rng (RandomState | None)
- Return type:
None
- seq_update(x, weights, estimate)[source]
Update sufficient statistics from encoded trajectory statistics.
- seq_initialize(x, weights, rng)[source]
Initialize sufficient statistics from encoded trajectory statistics.
- Parameters:
x (Any)
weights (ndarray)
rng (RandomState | None)
- Return type:
None
- combine(suff_stat)[source]
Merge transition-count and dwell-time sufficient statistics.
- value()[source]
Return copies of transition counts and dwell times.
- from_value(x)[source]
Restore transition-count and dwell-time sufficient statistics.
- scale(c)[source]
Scale accumulated sufficient statistics by a constant.
- Parameters:
c (float)
- Return type:
ContinuousTimeMarkovChainAccumulator
- key_merge(stats_dict)[source]
Merge this accumulator into its configured shared statistic.
- key_replace(stats_dict)[source]
Replace this accumulator with its configured shared statistic.
- acc_to_encoder()[source]
Return the encoder compatible with CTMC sufficient statistics.
- Return type:
ContinuousTimeMarkovChainDataEncoder
- class ContinuousTimeMarkovChainAccumulatorFactory(num_states, name=None, keys=None)[source]
Bases:
StatisticAccumulatorFactoryCreate accumulators for CTMC transition-count and dwell-time statistics.
- make()[source]
Create an empty CTMC accumulator.
- Return type:
ContinuousTimeMarkovChainAccumulator
- class ContinuousTimeMarkovChainEstimator(num_states, pseudo_count=None, initial_state=0, horizon=10.0, name=None, keys=None, prior_shape=None, prior_rate=None)[source]
Bases:
ParameterEstimatorClosed-form independent-edge CTMC MLE or Gamma-prior MAP estimator.
For edge
i -> j, an explicitGamma(shape_ij, rate_ij)prior givesq_ij = (n_ij + shape_ij - 1) / (T_i + rate_ij). Shapes must be at least one so the finite non-negative MAP is well defined. The defaultshape=1, rate=0recovers the MLE. The legacypseudo_count=cspelling maps coherently toshape=1+c, rate=con every off-diagonal edge; it cannot be mixed with explicit priors.- Parameters:
- accumulator_factory()[source]
Return a factory for CTMC sufficient-statistic accumulators.
- Return type:
ContinuousTimeMarkovChainAccumulatorFactory
- class ContinuousTimeMarkovChainDataEncoder(num_states)[source]
Bases:
DataSequenceEncoderEncode
(s0, horizon, jumps)trajectories into per-trajectory(counts, dwell)sufficient statistics,dwellincluding each trajectory’s final right-censored interval out to its horizon.- Parameters:
num_states (int)
- seq_encode(x)[source]
Encode trajectories as per-trajectory transition counts and dwell times.