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
plus the sequence of (dwell_time, next_state) jumps; 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.
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, [(dt, s1), (dt, s2),
...]) – the initial state and the observed jumps.
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 ContinuousTimeMarkovChainDistribution(rates, initial_state=0, horizon=10.0, name=None, keys=None)[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 or mass at a single observation.
Concrete default: exponentiate
log_density(the abstract method subclasses must provide). Leaves with a cheaper closed form may override this.
- log_density(x)[source]
Return the log-density or log-mass at a single observation.
- seq_log_density(x)[source]
Return vectorized log-density values for sequence-encoded observations.
- sampler(seed=None)[source]
Return a sampler for drawing observations from this distribution.
- Parameters:
seed (int | None)
- Return type:
ContinuousTimeMarkovChainSampler
- estimator(pseudo_count=None)[source]
Return an estimator for fitting this distribution from data.
- Parameters:
pseudo_count (float | None)
- Return type:
ContinuousTimeMarkovChainEstimator
- dist_to_encoder()[source]
Return the data encoder used by this distribution for 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)
- sample(size=None)[source]
Draw observations.
Combinator samplers (mixture/sequence/…) accept
batched. Withbatched=True(the default) each child stream is drawn in one vectorized call instead of a per-draw Python loop – far faster. Because every child sampler owns an independentRandomState, batching consumes each stream in the same order as the loop, so the draws are identical to the legacy path.batched=Falseforces that legacy per-draw loop as a guaranteed- stable reference. Leaf samplers are already vectorized and ignore the flag.
- 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]
- initialize(x, weight, rng)[source]
- Parameters:
x (Any)
weight (float)
rng (RandomState | None)
- Return type:
None
- seq_update(x, weights, estimate)[source]
- seq_initialize(x, weights, rng)[source]
- Parameters:
x (Any)
weights (ndarray)
rng (RandomState | None)
- Return type:
None
- combine(suff_stat)[source]
- from_value(x)[source]
- scale(c)[source]
Scale linear sufficient statistics in-place by
c.The structural default is correct for ordinary weighted sums, nested tuples/lists/dicts, and numeric arrays. Families whose
value()payload includes non-linear metadata such as support bounds must override this method and leave that metadata unscaled.- Parameters:
c (float)
- Return type:
ContinuousTimeMarkovChainAccumulator
- key_merge(stats_dict)[source]
Pool this accumulator’s statistics into
stats_dictunder its merge key.The structural default implements the common single-key pattern: store the accumulator under
self.keysthe first time the key is seen, elsecombineinto the one already there. Accumulators with several named keys (e.g. an HMM’s init/trans/state keys) or a non-accumulator stats payload override this. AkeysofNone(the default) is a no-op.
- key_replace(stats_dict)[source]
Replace this accumulator’s statistics from the pooled
stats_dictentry (see key_merge).
- acc_to_encoder()[source]
- Return type:
ContinuousTimeMarkovChainDataEncoder
- class ContinuousTimeMarkovChainAccumulatorFactory(num_states, name=None, keys=None)[source]
Bases:
StatisticAccumulatorFactory- make()[source]
- Return type:
ContinuousTimeMarkovChainAccumulator
- class ContinuousTimeMarkovChainEstimator(num_states, pseudo_count=None, name=None, keys=None)[source]
Bases:
ParameterEstimatorClosed-form rate MLE:
q_ij = n_ij / T_i(independent Poisson rates, unique global optimum).- accumulator_factory()[source]
- Return type:
ContinuousTimeMarkovChainAccumulatorFactory