CTMC (Continuous Time Markov Chain)

Methods · Configuration · Shared options · All solvers

The CTMC solver analyzes models by first generating the infinitesimal generator of the network and then solving the global balance equations for steady-state analysis. Transient analysis is carried out by numerically solving Kolmogorov's forward equations and value iteration for transient rewards. For models with infinite states, such as open networks, the cutoff option can be used to truncate the state space.

Methods

The method names and defaults below describe the MATLAB interface. Aliases share a row; model-specific restrictions and backend differences are noted. Use solver.listValidMethods() to inspect the names available for your model.

CTMC methods and aliases
MethodAlgorithm and applicabilityReference
defaultGenerate the explicit state space and solve the global balance equations of the full generator.[1]
exactThe same exact solve, asked for by name.
gpuA no-op alias of default in MATLAB: ctmc_solve has a gpuArray case, but the numeric path reaches the solve through the block decomposition, so the name never arrives. Kept for parity with the JAR and python lists.
mddHold the reachable set in a multi-valued decision diagram and solve K coupled level-CTMCs instead of the full generator; exact on product-form models, approximate otherwise.
cftpMonotone coupling-from-the-past perfect sampler of the closed product-form stationary distribution.
cftp.approxThe rapidly-mixing approximate sampler of the same construction, instead of the exact CFTP coupling.

The linear solve is a backend, not a method: options.config.linsolver picks gmres, bicgstab, direct or gpu for the same generator.

Configuration options

The solver-specific fields below belong to options.config. Set them on an options struct, for example opt.config.name = value, and pass that struct to the solver constructor. See shared solver options for all top-level fields, shared configuration, defaults and usage. Options apply only to the methods and model features that consume them.

Relevant top-level options: cutoff, ctmc_max_states, rewardIterations, force, timespan, timestep.

CTMC defaults to cutoff=10 and config.state_space_gen='full'. Open and mixed models need finite truncation. Set config.linsolver to choose a linear backend, independently of the state-space method; gmres and bicgstab are not solver method names.

Solver-specific configuration
OptionDefaultDescription and values
chain_aggregationfalseOpt in to solving the chain-aggregated generator instead of the per-class one.
ctmc_tv_ngrid100Grid points of the piecewise-constant propagator used for a time-inhomogeneous generator.
fau_deltacode defaultFast adaptive uniformization: the mass threshold below which a state is dropped from the active set.
fau_epsilon1e-6Total accumulated defect the marched FAU trajectory is allowed, split evenly over the steps.
fau_ngrid100Output grid points of that trajectory when timestep is not set.
fes_stationsunset1-based indices of the stations to collapse into one flow-equivalent server; needs at least two.
gd_max_entriesbudgetCap on the global-dependence table (states x stations x classes); raise it or lower cutoff when refused.
mdd_maxitersolver defaultIteration cap of the MDD (multi-valued decision diagram) symbolic state-space analyzer.
mdd_tolsolver defaultConvergence tolerance of that analyzer.
passage_method'expm'First-passage-time CDF algorithm used by getCdfFirstPassT.
qrf_alpha[]Load-dependent rate matrix (M x N) handed to the queueing-reduction-with-blocking construction.
qrf_params[]Blocking configuration struct (f, MR, BB, F, MM, MM1, ZZ, ZM) for the same construction.
qrf_maxvarscapRefusal threshold on the number of variables the blocking reduction would generate.
rate_schedunsetPiecewise-constant schedule making the generator time-inhomogeneous over the horizon.
transient_method'ode'Transient integrator: 'ode' integrates the Kolmogorov equations, 'fau' marches fast adaptive uniformization.
linsolver'default'Linear-solve backend for the generated CTMC: 'default' selects by size, 'gmres' and 'bicgstab' request Krylov iteration, 'direct' requests factorization, and 'gpu' enables the GPU branch (with CPU fallback). This is separate from options.method.
gmres_restart[]Restart length for the GMRES linear solve; empty uses the backend default. The outer iter_max also caps its iteration budget.

Example

This example demonstrates a closed queueing network with 3 jobs circulating between two queues. The CTMC solver generates the state space and solves the global balance equations to compute steady-state probabilities.

% Create a closed queueing network (2 queues, 3 jobs)
model = Network('Closed Network');

% Create queues
queue1 = Queue(model, 'Queue1', SchedStrategy.PS);
queue2 = Queue(model, 'Queue2', SchedStrategy.FCFS);

% Closed class with 3 jobs starting at Queue1
jobclass = ClosedClass(model, 'Class1', 3, queue1);

% Set service times
queue1.setService(jobclass, Exp(1.0));
queue2.setService(jobclass, Exp(2.0));

% Set routing probabilities
P = model.initRoutingMatrix();
P.set(jobclass, jobclass, queue1, queue1, 0.4);
P.set(jobclass, jobclass, queue1, queue2, 0.6);
P.set(jobclass, jobclass, queue2, queue1, 1.0);
model.link(P);

% Solve with CTMC
solver = CTMC(model);
CTMC(model).avgTable()

Output:

CTMC analysis [method: default; type: exact, deterministic; lang: matlab; env: 2025a] completed in 0.234s.

ans =
  2×8 table
    Station    JobClass     QLen       Util       RespT     ResidT     ArvR       Tput
    _______    ________    _______    _______    _______    ______    _______    _______
    Queue1      Class1      2.6041    0.98095     2.6547    2.6547    0.98095    0.98095
    Queue2      Class1     0.39591    0.29428    0.67266    0.4036    0.58857    0.58857
import jline.lang.*;
import jline.lang.constant.SchedStrategy;
import jline.lang.nodes.Queue;
import jline.lang.processes.Exp;
import jline.solvers.NetworkAvgTable;
import jline.solvers.ctmc.CTMC;
import java.util.List;

public class CTMCExample {
    public static void main(String[] args) {
        // Create a closed queueing network (2 queues, 3 jobs)
        Network model = new Network("Closed Network");

        Queue queue1 = new Queue(model, "Queue1", SchedStrategy.PS);
        Queue queue2 = new Queue(model, "Queue2", SchedStrategy.FCFS);

        // Closed class with 3 jobs starting at Queue1
        ClosedClass jobclass = new ClosedClass(model, "Class1", 3, queue1);

        queue1.setService(jobclass, Exp.fitRate(1.0));
        queue2.setService(jobclass, Exp.fitRate(2.0));

        // Set routing probabilities
        RoutingMatrix P = new RoutingMatrix(model,
            List.of(jobclass), List.of(queue1, queue2));
        P.addConnection(jobclass, jobclass, queue1, queue1, 0.4);
        P.addConnection(jobclass, jobclass, queue1, queue2, 0.6);
        P.addConnection(jobclass, jobclass, queue2, queue1, 1.0);
        model.link(P);

        // Solve with CTMC
        CTMC solver = new CTMC(model);
        NetworkAvgTable avgTable = solver.avgTable;
        System.out.println(avgTable);
    }
}

Output:

CTMC analysis [method: default; type: exact, deterministic; lang: java; env: 17.0.9] completed.

Station    JobClass     QLen       Util       RespT     ResidT     ArvR       Tput
Queue1     Class1       2.6041     0.98095    2.6547    2.6547     0.98095    0.98095
Queue2     Class1       0.39591    0.29428    0.67266   0.4036     0.58857    0.58857
from line_solver import *

# Create a closed queueing network (2 queues, 3 jobs)
model = Network('Closed Network')

queue1 = Queue(model, 'Queue1', SchedStrategy.PS)
queue2 = Queue(model, 'Queue2', SchedStrategy.FCFS)

# Closed class with 3 jobs starting at Queue1
jobclass = ClosedClass(model, 'Class1', 3, queue1)

queue1.setService(jobclass, Exp(1.0))
queue2.setService(jobclass, Exp(2.0))

# Set routing probabilities
P = model.initRoutingMatrix()
P.set(jobclass, jobclass, queue1, queue1, 0.4)
P.set(jobclass, jobclass, queue1, queue2, 0.6)
P.set(jobclass, jobclass, queue2, queue1, 1.0)
model.link(P)

# Solve with CTMC
solver = CTMC(model)
print(solver.avg_table)

Output:

CTMC analysis [method: default; type: exact, deterministic; lang: python; env: 3.13.7] completed.

  Station  JobClass    QLen      Util      RespT    ResidT    ArvR      Tput
0  Queue1    Class1     2.6041    0.98095   2.6547   2.6547    0.98095   0.98095
1  Queue2    Class1     0.39591   0.29428   0.67266  0.4036    0.58857   0.58857

References

  1. Bolch, G., Greiner, S., de Meer, H., & Trivedi, K. S. (2006). Queueing Networks and Markov Chains: Modeling and Performance Evaluation with Computer Science Applications (2nd ed.). Wiley-Interscience.