Solver Reference

This reference describes the main solver methods available in LINE. All solvers inherit from the NetworkSolver base class and share common methods for obtaining performance metrics. Each solver also provides specialized methods and algorithm options tailored to its solution approach.

Common NetworkSolver Methods

The following methods are available for all LINE solvers (AUTO, CTMC, FLUID, JMT, LN, LQNS, MAM, MVA, NC, SSA). These methods provide standard steady-state performance metrics.

Note

Not all solvers support all advanced methods (distributions, transient analysis, state probabilities). See solver-specific sections below for details.

Steady-State Average Metrics

Basic Performance Metrics

getAvg()

Returns mean performance metrics (queue length, utilization, response time, throughput) for each station and class.

Parameters: None

Returns:

Tuple of 5 matrices: [QN, UN, RN, TN, AN]

  • QN - Queue length matrix [num_stations x num_classes]

  • UN - Utilization matrix [num_stations x num_classes]

  • RN - Response time matrix [num_stations x num_classes]

  • TN - Throughput matrix [num_stations x num_classes]

  • AN - Arrival rate matrix [num_stations x num_classes]

Example:

solver = MVA(model);
[QN, UN, RN, TN, AN] = solver.getAvg();

% Access queue length at station 1, class 1
qlen = QN(1, 1);

getAvgTable()

Returns the same metrics as getAvg() but formatted as a MATLAB table with station and class names for easier inspection.

Parameters: None

Returns:

MATLAB table with columns: [Node, JobClass, QLen, Util, RespT, ResidT, ArvR, Tput]

  • Rows with all-zero metrics are filtered out

  • Each row represents a station-class combination

Example:

solver = MVA(model);
T = solver.getAvgTable();
disp(T);

% Filter to specific station
queue1_metrics = T(strcmp(T.Node, 'Queue1'), :);

getAvgNode() / getAvgNodeTable()

Returns metrics for each node (including sinks) and class.

Returns: Table with same structure as getAvgTable()

getAvgChain() / getAvgChainTable()

Returns metrics aggregated by station and chain (instead of class).

Returns: Table with columns: [Station, Chain, QLen, Util, RespT, ResidT, ArvR, Tput]

getAvgNodeChain() / getAvgNodeChainTable()

Returns metrics aggregated by node and chain.

Returns: Table with columns: [Node, Chain, QLen, Util, RespT, ResidT, ArvR, Tput]

getAvgSys() / getAvgSysTable()

Returns system-level metrics (system response time and throughput) aggregated by chain.

getAvgSys() Returns: List [response_time, throughput] with system-level performance values

getAvgSysTable() Returns: Table with columns: [Chain, JobClasses, SysRespT, SysTput]

Note

System metrics are only defined by chain to avoid ambiguity when jobs switch classes within a chain.

Specialized Average Methods

getAvgArvR()

Returns arrival rates for each station and class.

Returns: Matrix [num_stations x num_classes]

getAvgQLen()

Returns average queue length for each station and class.

Returns: Matrix [num_stations x num_classes]

getAvgRespT()

Returns average response time for each station and class.

Returns: Matrix [num_stations x num_classes]

getAvgResidT()

Returns average residence time for each station and class.

Returns: Matrix [num_stations x num_classes]

getAvgTput()

Returns average throughput for each station and class.

Returns: Matrix [num_stations x num_classes]

getAvgUtil()

Returns average utilization for each station and class.

Returns: Matrix [num_stations x num_classes]

getAvgSysRespT()

Returns system-level average response time.

Returns: Vector of system response times (one per class)

getAvgSysTput()

Returns system-level average throughput.

Returns: Vector of system throughputs (one per class)

Chain-Based Metrics

The following methods return metrics aggregated by routing chains instead of job classes:

getAvgQLenChain() / getAvgNodeQLenChain()

Returns queue length aggregated by chain.

getAvgRespTChain() / getAvgNodeRespTChain()

Returns response time aggregated by chain.

getAvgTputChain() / getAvgNodeTputChain()

Returns throughput aggregated by chain.

getAvgUtilChain() / getAvgNodeUtilChain()

Returns utilization aggregated by chain.

State Probability Methods

getProbAggr(node, state)

Returns marginal state probabilities for jobs of different classes at a given station.

Parameters:

  • node - Network node (Queue, Delay, etc.) or node index (int)

  • state (optional) - State specification as vector. Default: empty (returns all states)

Returns:

  • Scalar probability value (if result is scalar)

  • Matrix of probabilities (if multi-dimensional)

  • Empty if computation fails or is not supported

Example:

solver = CTMC(model);
queue1 = model.nodes{1};

% Get probability of specific state [2 jobs of class 1, 1 job of class 2]
queue1.setState([2, 1]);
prob = solver.getProbAggr(queue1);  % Returns scalar
fprintf('Probability of state [2,1]: %f\n', prob);

% Get all state probabilities (returns matrix)
allProbs = solver.getProbAggr(queue1);

Supported by: CTMC, FLUID, JMT, MAM, MVA

getProb(node, state)

Returns state probabilities at equilibrium at a given station, including phase information (full state space).

Parameters:

  • node - Network node (Queue, Delay, etc.) or node index (int)

  • state (optional) - Complete state specification including phase. Default: empty

Returns:

  • Scalar probability value (if result is scalar)

  • Array of probabilities (if multi-dimensional)

  • Empty if computation fails

Example:

solver = CTMC(model);
queue1 = model.nodes{1};

% Get probability for a specific state with phase information
prob = solver.getProb(queue1, [1, 0, 2]);  % [class0_jobs, class1_jobs, phase]

Note

This method returns the full state space including phase information, whereas getProbAggr() aggregates over phases.

Supported by: CTMC, SSA

getProbSys()

Returns joint probabilities for the entire system state (all stations).

Parameters: None

Returns:

  • Multi-dimensional array of joint state probabilities

  • Empty if computation fails

Supported by: CTMC, SSA

getProbSysAggr()

Returns joint probabilities for jobs of different classes across all stations (aggregated over phases).

Parameters: None

Returns:

  • Struct containing: - probability - Array of joint probabilities - logNormConst - Log normalizing constant - isAggregated - true (for this method)

  • Empty if computation fails

Supported by: CTMC, JMT, NC

getProbNormConstAggr()

Returns the normalizing constant of state probabilities.

Parameters: None

Returns:

  • Scalar: The normalizing constant value

  • Empty if computation fails

Supported by: JMT, MVA, NC

Distribution Methods

getCdfRespT()

Returns the cumulative distribution function (CDF) of response times for each station and class at steady-state.

Parameters: None

Returns:

Cell array with shape {num_stations x num_classes}. Each cell {i, k} is either empty (if not available for that station-class pair), or a matrix [n_points x 2] where:

  • Column 1: Time points (response time values)

  • Column 2: CDF values (cumulative probability from 0 to 1)

Example:

solver = FLD(model);
cdfData = solver.getCdfRespT();

% Access CDF for station 1, class 1
if ~isempty(cdfData{1, 1})
    timePoints = cdfData{1, 1}(:, 1);
    cdfValues = cdfData{1, 1}(:, 2);

    % Plot CCDF (complementary CDF)
    semilogx(timePoints, 1 - cdfValues);
end

Supported by: CTMC, FLUID, JMT, MAM, SSA

getCdfPassT()

Returns the cumulative distribution function (CDF) of passage times between stations at steady-state.

Returns: Cell array with same structure as getCdfRespT()

Supported by: CTMC

Transient Analysis Methods

Note

Transient analysis requires specifying a timespan parameter when creating the solver. Example: solver = JMT(model, ‘timespan’, [0, 100])

getTranAvg()

Returns transient mean performance metrics (queue length, utilization, throughput) over time for every station and class.

Parameters: None (uses timespan from solver options)

Returns:

The return structure varies by solver:

FLD/CTMC: Struct with fields QNt, UNt, TNt

  • Each field is a cell array: {{station_0_classes}, {station_1_classes}, …}

  • Each cell contains time series data

JMT: Tuple {QNclass_t, UNclass_t, TNclass_t}

  • Each element has shape {num_stations x num_classes}

  • Each cell contains struct with fields: - handle - tuple of (station_obj, class_obj) - t - vector of time points - metric - vector of metric values at each time point

Example:

% Fluid solver - returns struct
solver = FLD(model, 'timespan', [0, 50]);
result = solver.getTranAvg();

QNt = result.QNt;  % Queue length over time
UNt = result.UNt;  % Utilization over time
TNt = result.TNt;  % Throughput over time

% Access queue length time series for station 1, class 1
qlenSeries = QNt{1}{1};  % matrix

% JMT solver - returns cell arrays
solverJmt = JMT(model, 'timespan', [0, 100]);
[QN_t, UN_t, TN_t] = solverJmt.getTranAvg();

% Access specific station-class time series
if ~isempty(QN_t{1, 1})
    timePoints = QN_t{1, 1}.t;
    qlenValues = QN_t{1, 1}.metric;
end

Supported by: CTMC, FLUID, JMT

getTranCdfRespT()

Returns response time distribution in the transient regime.

Returns: Cell array with shape {num_stations x num_classes}, same structure as getCdfRespT()

Supported by: JMT

getTranCdfPassT()

Returns first passage time distributions in the transient regime.

Supported by: FLUID

getTranProb(node)

Returns transient state probabilities for a specific node over time.

Parameters:

  • node - Network node (Queue, Delay, etc.) or node index

Returns: Struct containing transient probabilities or empty

Supported by: CTMC

getTranProbAggr(node)

Returns transient marginal state probabilities aggregated by class for a specific node.

Supported by: CTMC

getTranProbSys()

Returns transient joint system state probabilities over time.

Supported by: CTMC

getTranProbSysAggr()

Returns transient joint probabilities aggregated by class for the entire system.

Supported by: CTMC

Sample Path Methods

Note

Sample path methods generate discrete-event simulation traces showing the evolution of the system state over time. These are primarily used for validation, visualization, and detailed analysis of system dynamics.

sample(node, numSamples)

Returns a sample path of the state evolution at a given node, including detailed phase information.

Parameters:

  • node - Network node (Queue, Delay, etc.) to sample

  • numSamples - Number of samples/events to generate (int)

Returns:

Struct containing:

  • handle - Unique identifier (string)

  • t - Array of time points

  • state - State information at each time point (includes phase details)

  • event - Cell array of events that occurred

  • isAggregate - false (not aggregated)

  • nodeIndex - Index of the sampled node

  • numSamples - Number of samples collected

Example:

solver = SSA(model, 'seed', 12345);
queue1 = model.nodes{1};

sampleResult = solver.sample(queue1, 1000);
if ~isempty(sampleResult)
    times = sampleResult.t;
    states = sampleResult.state;
    events = sampleResult.event;

    % Plot sample path
    stairs(times, states(:, 1));  % State of first class
end

Supported by: CTMC, SSA

sampleAggr(node, numSamples)

Returns a sample path with aggregated state (number of jobs per class, without phase information).

Returns: Struct with same structure as sample(), but with isAggregate = true

Supported by: CTMC, JMT, SSA

sampleSys(numEvents)

Returns sample paths for all nodes in the system with detailed phase information.

Parameters:

  • numEvents - Number of events to simulate (int)

Supported by: CTMC, SSA

sampleSysAggr(numEvents)

Returns sample paths for all nodes with aggregated state (job counts per class, no phase information).

Supported by: CTMC, JMT, SSA

Solver Options

All solvers accept an options parameter or name-value pairs. Common options include:

  • cache (bool) - Cache solver results (default: true)

  • cutoff (int) - Maximum jobs per station/class (required for CTMC with open classes)

  • force (bool) - Bypass solver feasibility checks (default: false)

  • iter_max (int) - Maximum iterations for iterative solvers (default: 1000)

  • iter_tol (float) - Iteration convergence tolerance (default: 1e-6)

  • keep (bool) - Store intermediate files for debugging (default: false)

  • method (string) - Algorithm selection (solver-specific)

  • samples (int) - Number of samples for simulation-based solvers (default: 10000)

  • seed (int) - Random seed for stochastic solvers

  • timespan (vector) - Time range for transient analysis (e.g., [0, 100])

  • tol (float) - General numerical tolerance (default: 1e-4)

  • verbose (int) - Verbosity level (0=silent, 1=standard, 2=debug)

Individual Solvers

AUTO Solver

Purpose: Automatic solver selection based on model properties. The AUTO solver analyzes the model structure and dynamically selects the most appropriate solution method from available solvers (CTMC, NC, JMT, SSA, etc.).

The AUTO solver prioritizes analytical solvers over simulation and uses heuristics based on scheduling strategies, number of jobs, chains, and classes to make its selection. If the optimal solver does not support a requested function, it selects from feasible solvers in order of expected execution time.

Typical Usage:

model = Network('mymodel');
queue = Queue(model, 'Queue1', SchedStrategy.FCFS);
jobClass = ClosedClass(model, 'Class1', 5, queue);
queue.setService(jobClass, Exp(1.0));

solver = AUTO(model);
avgTable = solver.getAvgTable();
disp(avgTable);

Available Methods: All common NetworkSolver methods (the AUTO solver will delegate to an appropriate backend solver).

Configuration: No solver-specific options. The AUTO solver accepts standard options which it passes to the selected backend solver.

CTMC Solver

Purpose: Continuous-Time Markov Chain (CTMC) solver providing exact solutions via explicit generation of the underlying CTMC state space. This is the only method that guarantees exact results for all Markovian models, but it suffers from state-space explosion for larger models.

The CTMC solver is recommended for small to medium models (heuristically limited to ~6000 states) where exact solutions are required and the model is fully Markovian.

Typical Usage:

% Steady-state analysis
solver = CTMC(model);
avgTable = solver.getAvgTable();

% Transient analysis at time t=10
solverTransient = CTMC(model, 'timespan', [0, 10]);
qnT = solverTransient.getTranAvg();

% State probabilities
probAggr = solver.getProbAggr(queue1);
probSys = solver.getProbSys();

Solver-Specific Methods:

  • getCdfRespT() - Response time distribution at steady-state

  • getTranCdfPassT() - First passage time distribution in transient regime

  • getTranCdfRespT() - Response time distribution in transient regime

  • getProb() - State probabilities at equilibrium

  • getProbAggr() - Marginal state probabilities by class

  • getProbSys() - Joint system state probabilities

  • getProbSysAggr() - Joint probabilities by class

  • getTranAvg() - Transient performance metrics

  • getTranProb(), getTranProbAggr(), getTranProbSys(), getTranProbSysAggr() - Various transient probability methods

  • sample() - Sample path for a station (with phase information)

  • sampleAggr() - Sample path for a station (aggregated by class)

  • sampleSys() - Sample paths for all stations (with phase information)

  • sampleSysAggr() - Sample paths for all stations (aggregated by class)

Solution Methods (method option):

  • ‘default’ - Global balance solution (default)

Key Options:

  • cutoff (int) - Mandatory for models with open classes. Maximum number of jobs per station and class.

  • force (bool) - Bypass state-space size checks (use with caution)

  • timespan (vector) - Temporal range for transient analysis (e.g., [0, 50])

  • timestep (float) - Fixed time interval for transient sampling (adaptive by default)

Example:

% CTMC with open classes requires cutoff
solver = CTMC(model, 'cutoff', 10);

% Transient analysis with specific timestep
solver = CTMC(model, 'timespan', [0, 100], 'timestep', 1.0);
tranAvg = solver.getTranAvg();

FLUID Solver

Purpose: Approximates model behavior using Ordinary Differential Equation (ODE)-based mean-field approximations. The FLUID solver analyzes models via a system of ODEs, providing faster solutions than CTMC but with some approximation error.

The FLUID approximation becomes exact in the limit for processor-sharing (PS) and infinite-server (INF) scheduling. It scales better than CTMC for larger models and is particularly effective for models with many jobs.

Typical Usage:

% Steady-state analysis
solver = FLD(model);
avgTable = solver.getAvgTable();

% Response time distribution
cdfRespT = solver.getCdfRespT();

% Transient analysis
solverTransient = FLD(model, 'timespan', [0, 50]);
tranAvg = solverTransient.getTranAvg();

Solver-Specific Methods:

  • getCdfRespT() - Response time distribution

  • getProbAggr() - Marginal state probabilities by class

  • getTranAvg() - Transient performance metrics

  • getTranCdfPassT() - First passage time distributions

Solution Methods (method option):

  • ‘default’ or ‘matrix’ - ODE-based mean field approximations (default)

  • ‘closing’ - Fluid with closing method for open classes

  • ‘statedep’ - Kurtz’s mean field ODEs for closed models

  • ‘softmin’ - Smoothed statedep with softmin replacing min functions

Key Options:

  • stiff (bool) - Use stiff ODE solver (default: true)

  • iter_tol (float) - ODE solver tolerance (default: 1e-4)

  • iter_max (int) - Maximum iterations (default: 10)

  • timespan (vector) - Temporal range (default: [0, inf] for steady-state)

Example:

% Fluid with specific method and tolerance
solver = FLD(model, 'method', 'statedep', 'iter_tol', 1e-6);
avgTable = solver.getAvgTable();

JMT Solver

Purpose: Wrapper for the Java Modelling Tools (JMT) simulation (JSIM) and analytical solver (JMVA). The JMT solver supports the widest range of model features including non-Markovian distributions (Pareto, deterministic, empirical traces).

JMT is the most comprehensive solver in LINE, supporting virtually all model features through discrete-event simulation. It can also invoke JMT’s analytical MVA solver for product-form models.

Typical Usage:

% Simulation with specific seed and samples
solver = JMT(model, 'seed', 23000, 'samples', 50000);
avgTable = solver.getAvgTable();

% Sample path generation
samplePath = solver.sampleAggr(queue, 100);

% Transient response time distribution
tranCdf = solver.getTranCdfRespT();

Solver-Specific Methods:

  • getCdfRespT() - Response time distribution

  • getProbAggr() - Marginal state probabilities

  • getProbSysAggr() - Joint probabilities by class

  • sampleAggr() - Sample path for a station (aggregated by class)

  • sampleSysAggr() - Sample path for system (aggregated by class)

  • getTranCdfRespT() - Transient response time distribution

  • getTranAvg() - Transient performance metrics

Note

JMT does NOT support sample() or sampleSys() with detailed phase information due to simulator limitations.

Solution Methods (method option):

Simulation methods:

  • ‘jsim’ or ‘default’ - Discrete-event simulation in JSIM (default)

Analytical methods (product-form models only):

  • ‘jmva’ or ‘jmva.mva’ - Exact MVA in JMVA

  • ‘jmva.recal’ - Exact RECAL algorithm

  • ‘jmva.comom’ - Exact CoMoM algorithm

  • ‘jmva.amva’ or ‘jmva.bs’ - Bard-Schweitzer approximate MVA

  • ‘jmva.aql’ - AQL algorithm

  • ‘jmva.chow’ - Chow algorithm

  • ‘jmva.dmlin’ - De Souza-Muntz Linearizer

  • ‘jmva.lin’ - Linearizer algorithm

  • ‘jmva.ls’ - Logistic sampling

Key Options:

  • seed (int) - Random number generator seed for simulation (default: random)

  • samples (int) - Number of simulation samples per metric (minimum 5000, default: 10000)

  • para (bool) - Enable parallel simulation with multiple independent replicas

  • keep (bool) - Store intermediate .jsimg/.jsimw files for debugging

Example:

% High-precision simulation
solver = JMT(model, 'seed', 12345, 'samples', 100000, 'verbose', 1);
avgTable = solver.getAvgTable();

% Use analytical JMVA solver
solverAnalytical = JMT(model, 'method', 'jmva.mva');
avgTable = solverAnalytical.getAvgTable();

LN Solver

Purpose: LINE’s native solver for Layered Queueing Networks (LQNs) with task-entry activity graphs and inter-task calls. Supports decomposition of layers with iterative analysis and specialized cache modeling.

The LN solver iteratively analyzes each layer of the network until convergence of steady-state measures, allowing flexible composition of different solver types for individual layers.

Typical Usage:

% LN solver with MVA for layer analysis
solver = LN(layeredModel, @(layer) MVA(layer));
avgTable = solver.getAvgTable();

Available Methods: All standard steady-state average methods (getAvg, getAvgTable, etc.)

Solution Methods (method option):

  • ‘default’ - Default recursive solution based on mean values

  • ‘moment3’ - Solution by recursive 3-moment approximation of response time distributions

Key Options:

  • iter_tol (float) - Convergence tolerance for layer iterations (default: 1e-6)

LQNS Solver

Purpose: Wrapper around the external LQNS solver for layered queueing networks. Transforms LINE models into LQNS XML format, invokes the external solver, and parses results back into LINE format.

Note

Requires lqns and lqsim executables to be available on the system PATH.

Typical Usage:

solver = LQNS(layeredModel);
avgTable = solver.getAvgTable();

Solution Methods (method option):

  • ‘std’ or ‘lqns’ - LQNS analytical solver with default settings (default)

  • ‘exact’ - LQNS analytical solver with exact MVA method

  • ‘srvn’ - LQNS analytical solver with SRVN layering

  • ‘srvnexact’ - LQNS with SRVN layering and exact MVA

  • ‘lqsim’ - LQSIM simulator (specify simulation length via samples option)

Key Options:

  • samples (int) - Simulation length for lqsim method

MAM Solver

Purpose: Matrix-Analytic Methods (MAM) solver providing exact solutions for open Markovian systems via quasi-birth-death (QBD) process analysis. Solves infinite state-space models exactly by exploiting repetitive CTMC structure.

The MAM solver is particularly effective for open queueing models with MAP/PH arrivals and services, providing exact results without state-space truncation.

Typical Usage:

solver = MAM(model);
avgTable = solver.getAvgTable();

% Response time distribution
cdfRespT = solver.getCdfRespT();

Solver-Specific Methods:

  • getCdfRespT() - Response time distribution

  • getProbAggr() - Marginal state probabilities

Solution Methods (method option):

  • ‘default’ - Matrix-analytic solution of structured QBDs (default)

  • ‘dec.source’ - Decomposition with arrivals as from the source

  • ‘dec.poisson’ - Decomposition based on Poisson arrival flows

  • ‘dec.mna’ - Decomposition based on MNA method

MVA Solver

Purpose: Mean Value Analysis (MVA) solver providing fast approximate and exact solutions for product-form queueing networks. Typically the fastest solver with good accuracy for single-server stations.

The MVA solver is ideal for closed and mixed queueing networks with product-form properties. It provides various approximation algorithms trading speed for accuracy, as well as exact methods for smaller models.

Typical Usage:

% Exact MVA
solver = MVA(model, 'method', 'exact');
avgTable = solver.getAvgTable();

% Approximate MVA (faster for large models)
solverApprox = MVA(model, 'method', 'qd');
avgTable = solverApprox.getAvgTable();

Solver-Specific Methods:

All standard steady-state average methods are supported.

Note

MVA cannot produce response time distributions due to the nature of mean-value analysis.

Solution Methods (method option):

Approximation algorithms:

  • ‘default’, ‘amva’, or ‘qd’ - Queue-dependent approximate MVA (default)

  • ‘bs’ - Bard-Schweitzer approximate MVA

  • ‘lin’ - Linearizer approximate MVA

  • ‘qdlin’ - Queue-dependent Linearizer approximate MVA

  • ‘exact’ - Exact solution (method depends on model features)

Bounds methods:

  • ‘aba.upper’ / ‘aba.lower’ - Asymptotic bound analysis

  • ‘bjb.upper’ / ‘bjb.lower’ - Balanced job bounds

  • ‘gb.upper’ / ‘gb.lower’ - Geometric square-root bounds

  • ‘pb.upper’ / ‘pb.lower’ - Proportional bounds

  • ‘sb.upper’ / ‘sb.lower’ - Simple bounds

Single-station formulas (for tandem/cyclic networks):

  • ‘mm1’ - Exact M/M/1 formula

  • ‘mmk’ - Exact M/M/k (Erlang-C) formula

  • ‘mg1’ - M/G/1 (Pollaczek-Khinchine) formula

  • ‘gig1.klb’, ‘gig1.allen’, ‘gig1.heyman’, ‘gig1.kingman’, ‘gig1.kobayashi’, ‘gig1.marchal’ - Various GI/G/1 approximations

  • ‘gigk’ - Kingman approximation for GI/G/k

Key Options:

  • method (string) - Algorithm selection (see above)

  • iter_max (int) - Maximum iterations (default: 1000)

  • iter_tol (float) - Convergence tolerance (default: 1e-6)

Advanced configuration (via config struct):

  • config.multiserver (string) - Multiserver handling (‘default’, ‘seidmann’, ‘softmin’)

  • config.np_priority (string) - Non-preemptive priority (‘default’/’cl’, ‘shadow’)

  • config.highvar (string) - High variance handling (‘default’, ‘interp’, ‘hvmva’)

  • config.fork_join (string) - Fork-join handling (‘default’/’mmt’, ‘ht’)

Example:

% MVA with specific approximation and tolerance
solver = MVA(model, 'method', 'lin', 'iter_tol', 1e-8, 'iter_max', 5000);
avgTable = solver.getAvgTable();

% MVA with advanced multiserver configuration
options = MVA.defaultOptions();
options.method = 'qd';
options.config.multiserver = 'seidmann';
solver = MVA(model, options);

NC Solver

Purpose: Normalizing Constant Analyzer (NC) providing exact and approximate solutions based on the normalizing constant of state probability distributions. Maps the problem to multidimensional integrals solved with Monte Carlo sampling and asymptotic expansions.

The NC solver is particularly useful for obtaining marginal and joint state probabilities in closed queueing networks, offering multiple exact and approximate algorithms.

Typical Usage:

% Exact convolution algorithm
solver = NC(model, 'method', 'ca');
avgTable = solver.getAvgTable();

% State probabilities
probAggr = solver.getProbAggr(queue1);
probSysAggr = solver.getProbSysAggr();
normConst = solver.getProbNormConstAggr();

Solver-Specific Methods:

  • getProbAggr() - Marginal state probabilities by class

  • getProbSysAggr() - Joint probabilities by class

  • getProbNormConstAggr() - Normalizing constant

Solution Methods (method option):

Automatic selection:

  • ‘default’ or ‘adaptive’ - Automated choice of deterministic method (default)

  • ‘exact’ - Automated choice of exact solution method

  • ‘sampling’ - Automated selection of sampling method

Exact methods:

  • ‘ca’ - Multiclass convolution algorithm

  • ‘comom’ - Class-oriented method of moments (for homogeneous models)

  • ‘mva’ - Product of throughputs on MVA lattice

Approximation methods:

  • ‘cub’ - Grundmann-Moeller cubature rules

  • ‘kt’ - Knessl-Tier asymptotic expansion

  • ‘bkt’ - Knessl-Tier with the exact Stirling remainder subtracted

  • ‘le’ - Logistic asymptotic expansion

  • ‘ble’ - Logistic expansion with the bias correction; the default for normally-loaded closed models

  • ‘lekt’ - the estimator common to ‘ble’ and ‘bkt’, on the cheaper side

  • ‘aghq’ - Adaptive Gauss-Hermite quadrature of the simplex factor

  • ‘ls’ - Logistic sampling

  • ‘imci’ - Improved Monte Carlo integration

  • ‘bk’ - Birman-Kogan saddle-point evaluation

  • ‘bkue’ - Birman-Kogan single-chain uniform expansion

  • ‘lc’ - Birman-Kogan load concealment

  • ‘nrl’ - Norlund-Rice integral with logit transformation

  • ‘nrp’ - Norlund-Rice integral with probit transformation

  • ‘nre’ - Norlund-Rice integral on a saddle-tilted contour, with an Edgeworth correction

  • ‘pana’ - Panacea asymptotic expansion

  • ‘rd’ - Reduction heuristic

Loss network methods:

  • ‘erlangfp’ - Erlang fixed-point approximation for open loss networks with FCR (Finite Capacity Region)

Advanced configuration (via config struct):

  • config.multiserver (string) - How a finite multiserver station is represented. 'default' keeps the historical dispatch: Seidmann’s approximation on method 'default', and the exact load-dependent lattice mu(n)=min(n,c) on method 'exact'. 'seidmann' forces Seidmann everywhere, including on 'exact'. 'lld' (or 'exact') forces the exact lattice everywhere it is admissible, including on method 'default', subject to a 6000-state population-lattice budget above which Seidmann remains the only affordable option. The SolverMVA rules NC has no counterpart for ('softmin', 'conway', 'krzesinski', 'suri', 'erlang') warn and fall back to 'default'.

Loss Network Auto-Detection:

The NC solver automatically uses the erlangfp method when detecting an open model with a single Delay node inside a Finite Capacity Region (FCR) configured with DROP policy. The FCR constraints are mapped to the Erlang fixed-point parameters:

  • Global max jobs -> First capacity link (all classes contribute)

  • Per-class max jobs -> Additional capacity links (one per class)

model = Network('Loss Network');
source = Source(model, 'Source');
delay = Delay(model, 'Delay');
sink = Sink(model, 'Sink');

class1 = OpenClass(model, 'Class1', 0);
class2 = OpenClass(model, 'Class2', 1);

source.setArrival(class1, Exp(0.3));
source.setArrival(class2, Exp(0.2));
delay.setService(class1, Exp(1.0));
delay.setService(class2, Exp(0.8));

P = model.initRoutingMatrix();
P.set(class1, class1, source, delay, 1.0);
P.set(class1, class1, delay, sink, 1.0);
P.set(class2, class2, source, delay, 1.0);
P.set(class2, class2, delay, sink, 1.0);
model.link(P);

% Add FCR with drop policy
fcr = model.addRegion({delay});
fcr.setGlobalMaxJobs(5);
fcr.setClassMaxJobs(class1, 3);
fcr.setClassMaxJobs(class2, 3);
fcr.setDropRule(class1, true);  % true = drop
fcr.setDropRule(class2, true);

% NC solver automatically selects 'erlangfp' method
solver = NC(model);
avgTable = solver.getAvgTable();

Note

The NC solver requires DROP policy (not WAITQ/blocking) for FCR loss network analysis.

Example:

% NC on a multiserver model: the default uses Seidmann's approximation,
% 'lld' asks for the exact load-dependent lattice instead
options = NC.defaultOptions();
options.config.multiserver = 'lld';
solver = NC(model, options);

% NC with specific exact method
solver = NC(model, 'method', 'comom');
avgTable = solver.getAvgTable();

% NC with sampling for large models
solverSampling = NC(model, 'method', 'ls', 'samples', 50000);
avgTable = solverSampling.getAvgTable();

SSA Solver

Purpose: Stochastic Simulation Algorithm (SSA) solver based on CTMC stochastic simulation. Estimates the probability distribution of system states by generating sample paths, deriving performance metrics indirectly.

The SSA solver offers more efficient parallelization than JMT and can retrieve detailed node state evolution including active phases of service distributions.

Typical Usage:

% SSA simulation
solver = SSA(model, 'samples', 50000, 'seed', 12345);
avgTable = solver.getAvgTable();

% Detailed sample path with phase information
samplePath = solver.sample(queue, 100);
sampleSys = solver.sampleSys(100);

Solver-Specific Methods:

  • getCdfRespT() - Response time distribution (via simulation)

  • getProb() - State probabilities at equilibrium

  • getProbSys() - Joint system state probabilities

  • sample() - Sample path for a station (with phase information)

  • sampleAggr() - Sample path for a station (aggregated by class)

  • sampleSys() - Sample paths for all stations (with phase information)

  • sampleSysAggr() - Sample paths for all stations (aggregated by class)

Solution Methods (method option):

  • ‘default’ - Alias for ‘nrm’ if model supports it, otherwise ‘serial’ (default)

  • ‘nrm’ - Next reaction method for population models (PS/INF scheduling only)

  • ‘serial’ - CTMC stochastic simulation on single core

  • ‘para’ - Parallel simulations with independent replicas on multiple cores

Key Options:

  • samples (int) - Number of simulation samples (default: 10000)

  • seed (int) - Random number generator seed

  • para (bool) - Enable parallel execution

Example:

% Parallel SSA with many samples
solver = SSA(model, 'method', 'para', 'samples', 100000, 'seed', 42);
avgTable = solver.getAvgTable();

Solver Compatibility Matrix

This table summarizes which methods are supported by each solver.

Method

AUTO

CTMC

FLUID

JMT

MAM

MVA

NC

SSA

getAvg() / getAvgTable()

Yes

Yes

Yes

Yes

Yes

Yes

Yes

Yes

getCdfRespT()

Yes

Yes

Yes

Yes

Yes

No

No

Yes

getProbAggr()

Yes

Yes

Yes

Yes

Yes

Yes

Yes

No

getProb()

Yes

Yes

No

No

No

No

No

Yes

getProbSysAggr()

Yes

Yes

No

Yes

No

No

Yes

No

getTranAvg()

Yes

Yes

Yes

Yes

No

No

No

No

sample() / sampleSys()

Yes

Yes

No

No

No

No

No

Yes

sampleAggr()

Yes

Yes

No

Yes

No

No

No

Yes

See also: Choosing the Right Solver

See also: Quick Start

See also: Examples