API Documentation
This section provides detailed API documentation for all LINE Solver Python modules.
Distribution Module (line_solver.distributions)
Pure Python probability distributions for LINE queueing network models.
This package provides all probability distributions without requiring pure Python without Java dependencies and converted to Java only when needed (e.g., when running a solver
- Usage:
from line_solver.distributions import Exp, Erlang, HyperExp from line_solver.distributions import Poisson, Geometric from line_solver.distributions import PH, MAP, Coxian
# Create distributions in pure Python service = Exp(rate=2.0) arrival = Erlang(mean=1.0, phases=3)
# Distributions can be converted to Java when needed
- class Distribution[source]
Bases:
ABCBase class for all probability distributions.
This class provides the common interface for all probability distributions in LINE, including service time distributions and inter-arrival time distributions.
Initialize a new distribution.
- eval_pmf(x)[source]
Evaluate the probability mass function at point x (snake_case alias for evalPMF; dispatches to the concrete distribution’s override).
- getRate()[source]
Get the rate parameter (1/mean).
For immediate (zero-mean) distributions, returns GlobalConstants.Immediate (a large but finite value) to avoid numerical issues with infinite rates. This matches MATLAB’s behavior.
- get_rate()
Get the rate parameter (1/mean).
For immediate (zero-mean) distributions, returns GlobalConstants.Immediate (a large but finite value) to avoid numerical issues with infinite rates. This matches MATLAB’s behavior.
- get_scv()
Get the squared coefficient of variation (SCV).
SCV = Var[X] / E[X]^2
- get_skew()
Get the skewness of the distribution.
- get_support()
Get the support range [min, max] of the distribution.
- isDisabled()[source]
Check if this distribution is equivalent to a Disabled distribution.
Mirrors MATLAB Distribution.isDisabled (isnan(getMean(self))): a distribution whose mean is not a number carries no usable process representation, so the struct records it as disabled rather than mislabelling it. Returning a hardcoded False, as this did, made refreshStruct treat such a distribution as an ordinary one.
- sample(n=1, rng=None)[source]
Generate random samples from this distribution.
- Parameters:
n (int) – Number of samples to generate.
rng (numpy.random.Generator | None) – Optional random number generator.
- Returns:
Array of n random samples.
- Return type:
- class ContinuousDistribution[source]
Bases:
DistributionBase class for continuous probability distributions.
Initialize a new distribution.
- evalLST(s)[source]
Laplace-Stieltjes transform E[e^{-sX}] evaluated at s.
Generic numerical fallback: rectangle-rule integration of evalPDF over [0, 20*mean] with 1000 points. Subclasses with a closed form or a MATLAB-matching numerical scheme (Pareto/Lognormal/Weibull) override this. Used by the G/M/1 MVA solver’s sigma-root for non-PH arrivals.
- evalLaplaceTransform(s)
Laplace-Stieltjes transform E[e^{-sX}] evaluated at s.
Generic numerical fallback: rectangle-rule integration of evalPDF over [0, 20*mean] with 1000 points. Subclasses with a closed form or a MATLAB-matching numerical scheme (Pareto/Lognormal/Weibull) override this. Used by the G/M/1 MVA solver’s sigma-root for non-PH arrivals.
- class DiscreteDistribution[source]
Bases:
DistributionBase class for discrete probability distributions.
Initialize a new distribution.
- class Markovian[source]
Bases:
DistributionBase class for Markovian (phase-type) distributions.
Markovian distributions can be represented in terms of initial probability vectors and transition rate matrices.
Initialize a new distribution.
- getPH()[source]
Return the phase-type representation as a dict {0: D0, 1: D1}, matching the JAR Map<Integer, Matrix> shape.
- getRepresentation()[source]
Return the
(D0, D1)matrix representation used in the theory of Markovian arrival processes, as a list[D0, D1](elementkcorresponds to matrixD_k).
- get_d0()
Get the D0 matrix (for MAP representations).
- get_d1()
Get the D1 matrix (for MAP representations).
- get_init_prob()
Get the initial probability vector.
- get_mu()
Get the service rates in each phase.
- get_number_of_phases()
Get the number of phases.
- get_ph()
Return the phase-type representation as a dict {0: D0, 1: D1}, matching the JAR Map<Integer, Matrix> shape.
- get_phi()
Get the completion probabilities from each phase.
- get_representation()[source]
snake_case alias for
getRepresentation().
- class Exp(rate)[source]
Bases:
ContinuousDistribution,MarkovianExponential distribution.
The exponential distribution is the simplest continuous distribution for modeling service times in queueing systems. It has the memoryless property and SCV = 1.
- Parameters:
rate (float) – The rate parameter (lambda = 1/mean).
Initialize a new distribution.
- classmethod fitMean(mean)
Create an exponential distribution with the given mean.
- classmethod fit_rate(rate)
Create an exponential distribution with the given rate.
- get_rate()
Get the rate parameter (1/mean).
For immediate (zero-mean) distributions, returns GlobalConstants.Immediate (a large but finite value) to avoid numerical issues with infinite rates. This matches MATLAB’s behavior.
- class Det(value)[source]
Bases:
ContinuousDistributionDeterministic (constant) distribution.
All service times are exactly equal to the specified value. Has SCV = 0 (no variability).
- Parameters:
value (float) – The constant service time value.
Initialize a new distribution.
- classmethod fitMean(mean)
Create a deterministic distribution with the given mean.
Since Det has zero variance, the mean equals the constant value.
- class Immediate[source]
Bases:
DetImmediate (zero delay) distribution.
Represents instantaneous service with zero delay.
Initialize a new distribution.
- classmethod get_instance()
Get singleton instance of Immediate distribution.
- class Disabled[source]
Bases:
ContinuousDistributionDisabled distribution.
Represents a disabled service (no service at all). Used for nodes that don’t serve a particular job class.
Initialize a new distribution.
- classmethod get_instance()
Get singleton instance of Disabled distribution.
- class Erlang(phase_rate, nphases)[source]
Bases:
ContinuousDistribution,MarkovianErlang distribution (sum of k exponentials).
The Erlang distribution is the distribution of the sum of k independent exponential random variables with the same rate. It has SCV = 1/k.
- Parameters:
Mean = nphases / phase_rate = r / alpha
Initialize a new distribution.
- classmethod fitMeanAndOrder(mean, phases)
Create an Erlang distribution from mean and number of phases.
- classmethod fitMeanAndSCV(mean, scv)
Create an Erlang distribution from mean and SCV.
For Erlang, SCV = 1/k where k is number of phases. So phases = round(1/SCV), constrained to be >= 1.
- classmethod fitMeanAndScv(mean, scv)
Create an Erlang distribution from mean and SCV.
For Erlang, SCV = 1/k where k is number of phases. So phases = round(1/SCV), constrained to be >= 1.
- classmethod fit_mean_and_order(mean, phases)[source]
Create an Erlang distribution from mean and number of phases.
- class HyperExp(p_or_probs, rate1_or_rates, rate2=None)[source]
Bases:
ContinuousDistribution,MarkovianHyperexponential distribution (mixture of exponentials).
The hyperexponential distribution is a mixture of exponential distributions. It has SCV >= 1.
- Supports two calling conventions (matching MATLAB API):
HyperExp(p, rate1, rate2): 2-phase with probability p of rate1, probability (1-p) of rate2
HyperExp(probs, rates): n-phase with vectors of probabilities and rates
- Parameters:
p_or_probs (float | list | numpy.ndarray) – For 2-phase: probability of first component (scalar). For n-phase: list/array of probabilities.
rate1_or_rates (float | list | numpy.ndarray) – For 2-phase: rate of first component (scalar). For n-phase: list/array of rates.
rate2 (float | None) – For 2-phase only: rate of second component.
Initialize a new distribution.
- classmethod fitMeanAndSCV(mean, scv, p=0.99)
Create a 2-phase hyperexponential distribution from mean and SCV.
Uses the same algorithm as MATLAB’s map_hyperexp function.
- classmethod fitMeanAndSCVBalanced(mean, scv)
Create a 2-phase hyperexponential distribution with balanced means.
Uses balanced means representation where p/mu1 = (1-p)/mu2.
- classmethod fitMeanAndScv(mean, scv, p=0.99)
Create a 2-phase hyperexponential distribution from mean and SCV.
Uses the same algorithm as MATLAB’s map_hyperexp function.
- classmethod fitMeanAndScvBalanced(mean, scv)
Create a 2-phase hyperexponential distribution with balanced means.
Uses balanced means representation where p/mu1 = (1-p)/mu2.
- classmethod fit_mean_and_scv(mean, scv, p=0.99)[source]
Create a 2-phase hyperexponential distribution from mean and SCV.
Uses the same algorithm as MATLAB’s map_hyperexp function.
- classmethod fit_mean_and_scv_balanced(mean, scv)[source]
Create a 2-phase hyperexponential distribution with balanced means.
Uses balanced means representation where p/mu1 = (1-p)/mu2.
- property means: numpy.ndarray
Get the means of each component.
- property probs: numpy.ndarray
Get the probabilities of each component.
- property rates: numpy.ndarray
Get the rates of each component.
- class Gamma(shape, scale)[source]
Bases:
ContinuousDistributionGamma distribution.
The gamma distribution is a two-parameter continuous distribution that generalizes the exponential and Erlang distributions.
Initialize a new distribution.
- classmethod fitMeanAndSCV(mean, scv)
Create a Gamma distribution from mean and SCV.
- classmethod fitMeanAndScv(mean, scv)
Create a Gamma distribution from mean and SCV.
- class Lognormal(mu, sigma)[source]
Bases:
ContinuousDistributionLognormal distribution.
A random variable X has a lognormal distribution if log(X) is normally distributed.
- Parameters:
Initialize a new distribution.
- classmethod fitMeanAndSCV(mean, scv)
Construct a Lognormal from a target mean and squared coefficient of variation (SCV = variance/mean^2), converting to log-space (mu, sigma).
Port of MATLAB Lognormal.fitMeanAndSCV.
- classmethod fitMeanAndScv(mean, scv)
Construct a Lognormal from a target mean and squared coefficient of variation (SCV = variance/mean^2), converting to log-space (mu, sigma).
Port of MATLAB Lognormal.fitMeanAndSCV.
- class Pareto(alpha, scale)[source]
Bases:
ContinuousDistributionPareto distribution.
The Pareto distribution is a power-law distribution often used to model heavy-tailed phenomena.
- Parameters:
Initialize a new distribution.
- classmethod fitMeanAndSCV(mean, scv)
Create a Pareto distribution from mean and SCV.
- Parameters:
- Returns:
Pareto distribution with given mean and SCV.
- Return type:
Note
For Pareto with alpha > 2: mean = alpha * scale / (alpha - 1) var = scale^2 * alpha / ((alpha - 1)^2 * (alpha - 2)) scv = var / mean^2 = 1 / (alpha * (alpha - 2))
Solving for alpha: alpha = (1 + sqrt(1 + 4*scv)) / (2*scv) Then: scale = mean * (alpha - 1) / alpha
- classmethod fitMeanAndScv(mean, scv)
Create a Pareto distribution from mean and SCV.
- Parameters:
- Returns:
Pareto distribution with given mean and SCV.
- Return type:
Note
For Pareto with alpha > 2: mean = alpha * scale / (alpha - 1) var = scale^2 * alpha / ((alpha - 1)^2 * (alpha - 2)) scv = var / mean^2 = 1 / (alpha * (alpha - 2))
Solving for alpha: alpha = (1 + sqrt(1 + 4*scv)) / (2*scv) Then: scale = mean * (alpha - 1) / alpha
- classmethod fit_mean_and_scv(mean, scv)[source]
Create a Pareto distribution from mean and SCV.
- Parameters:
- Returns:
Pareto distribution with given mean and SCV.
- Return type:
Note
For Pareto with alpha > 2: mean = alpha * scale / (alpha - 1) var = scale^2 * alpha / ((alpha - 1)^2 * (alpha - 2)) scv = var / mean^2 = 1 / (alpha * (alpha - 2))
Solving for alpha: alpha = (1 + sqrt(1 + 4*scv)) / (2*scv) Then: scale = mean * (alpha - 1) / alpha
- class Uniform(min_val, max_val)[source]
Bases:
ContinuousDistributionUniform distribution on [min, max].
Initialize a new distribution.
- class Weibull(shape, scale)[source]
Bases:
ContinuousDistributionWeibull distribution.
The Weibull distribution is commonly used in reliability engineering to model time to failure.
Initialize a new distribution.
- class Normal(mean, std)[source]
Bases:
ContinuousDistributionNormal (Gaussian) distribution.
Note: For queueing applications, a truncated or shifted version may be needed since normal distributions can take negative values.
Initialize a new distribution.
- eval_cdf(x)
Evaluate the CDF at point x.
- eval_pdf(x)
Evaluate the PDF at point x.
- classmethod fitMeanAndVar(mean, var)[source]
Create a Normal distribution with given mean and variance.
- classmethod fit_mean(mean, std=1.0)
Create a Normal distribution with given mean and std.
- classmethod fit_mean_and_std(mean, std)
Create a Normal distribution with given mean and std.
- classmethod fit_mean_and_var(mean, var)
Create a Normal distribution with given mean and variance.
- get_mean()
Get the mean (expected value) of the distribution.
- get_scv()
Get the squared coefficient of variation (var/mean^2).
- get_skewness()
Get the skewness (always 0 for normal).
- get_std()
Get the standard deviation.
- get_var()
Get the variance.
- class MultivariateNormal(mu, Sigma)[source]
Bases:
ContinuousDistributionMultivariate Normal (Gaussian) distribution.
Represents a d-dimensional normal distribution with mean vector mu and covariance matrix Sigma.
- Parameters:
mu (list | numpy.ndarray) – d-dimensional mean vector.
Sigma (list | numpy.ndarray) – d x d positive definite covariance matrix.
Initialize a new distribution.
- evalPDF(x)[source]
Evaluate the multivariate normal PDF at point(s) x.
- Parameters:
x (list | numpy.ndarray) – Single point (1D array of length d) or multiple points (2D array of shape n x d)
- Returns:
Single float for one point, or numpy array for multiple points.
- Return type:
- classmethod fitMeanAndCovariance(mu, Sigma)[source]
Create a MultivariateNormal distribution with given mean and covariance.
- classmethod fit_mean_and_covariance(mu, Sigma)
Create a MultivariateNormal distribution with given mean and covariance.
- class Prior(distributions, probabilities)[source]
Bases:
ContinuousDistributionDiscrete prior distribution over alternative distributions.
Prior represents parameter uncertainty by specifying a discrete set of alternative distributions with associated probabilities. Used with the UQ solver for Bayesian-style analysis.
This is NOT a mixture distribution - each alternative represents a separate model realization.
- Parameters:
distributions (list) – List of Distribution objects.
probabilities (list | numpy.ndarray) – List of probabilities (must sum to 1).
Initialize a new distribution.
- get_alternative(idx)
Get the distribution at index idx.
- get_num_alternatives()
Get the number of alternative distributions.
- get_probabilities()
Get all probabilities.
- get_probability(idx)
Get the probability of alternative idx.
- is_prior()
Return True (used for detection by UQ solver).
- is_prior_distribution()
Alias for isPrior (used for detection by UQ solver).
- property probabilities: numpy.ndarray
Get the probabilities.
- class Expolynomial(density, eft, lft)[source]
Bases:
ContinuousDistributionExpolynomial distribution with density f(x) = sum ci * x^ai * exp(-li*x).
Represents an expolynomial density over a bounded domain [eft, lft], matching the Sirio/ORIS GEN expolynomial format.
- Parameters:
Initialize a new distribution.
- class NHPP(breakpoints, rates, cyclic=True)[source]
Bases:
ContinuousDistributionNon-homogeneous Poisson process (NHPP) with a piecewise-constant intensity.
The intensity is a step function of the wall clock: segment i covers [breakpoints[i], breakpoints[i+1]) and carries rate rates[i], so breakpoints has one more entry than rates. With cyclic=True the schedule repeats, giving a cyclic Poisson process.
- Two horizon conventions:
- cyclicthe schedule repeats with period
T = breakpoints[-1] - breakpoints[0]; the active segment at time t follows from (t - breakpoints[0]) % T.
- non-cyclicthe intensity is zero outside
[breakpoints[0], breakpoints[-1]), so the process emits nothing once the schedule is exhausted. A non-cyclic NHPP is therefore a transient construct: run to steady state it converges to the empty system, so callers should use a time span within the horizon.
This is NOT a renewal process. Successive intervals are dependent, because the position within the schedule carries over from one event to the next. Accordingly the scalar summaries that presuppose an i.i.d. interval distribution – getSCV, getSkew, getVar, evalCDF – are undefined and return NaN rather than a representative exponential value, which would silently misreport the process as Poisson. The schedule is the parameterisation: read it with getRateSchedule. getMean is well defined and returns the arrival-stationary (Palm) mean interval 1/timeAverageRate.
Solver support: the LDES simulation engine honours the exact schedule in both steady state (cyclic only) and transient analysis. SolverFLD honours it in getTranAvg, by injecting the intensity as a time-varying rate multiplier on the closing ODE; SolverFLD.getAvg uses the time-average rate, which is the steady state of a cyclic schedule. Every other solver rejects a model using it via the standard unsupported-feature check.
- Parameters:
breakpoints – strictly increasing segment boundaries, length n+1.
rates – non-negative rate on each segment, length n.
cyclic (bool) – whether the schedule repeats with the horizon as period.
Initialize a new distribution.
- property breakpoints: numpy.ndarray
Segment boundaries, length n+1.
- evalLST(s)[source]
NaN: no i.i.d. interval distribution, so no Laplace-Stieltjes transform. Overrides the base numerical quadrature, which would integrate against an undefined CDF.
- getRate()[source]
Get the rate parameter (1/mean).
For immediate (zero-mean) distributions, returns GlobalConstants.Immediate (a large but finite value) to avoid numerical issues with infinite rates. This matches MATLAB’s behavior.
- getRateSchedule()[source]
The parameterisation of the process; the scalar summaries are not.
Model compilation recognises a schedule-bearing process by this method rather than by class name.
- getSCV()[source]
NaN: an NHPP is not a renewal process, so there is no i.i.d. interval distribution for an SCV to summarise. Returning a representative value would report a time-varying process as an exponential one to every consumer of sn.scv.
- nextInterval(frm, residual)[source]
Solve int_{frm}^{frm+x} lambda(u) du = residual for x.
Walks the schedule forward, consuming the budget segment by segment. Returns 0 when a non-cyclic horizon is exhausted first, which callers read as “no further event”.
Exact for an NHPP: conditional on no event since the last one, the residual is governed by the intensity from the current instant onward, so a holding time drawn under a rate that has since changed is not a sample from this process.
- property rates: numpy.ndarray
Per-segment rates, length n.
- sample(n=1, rng=None)[source]
Draw n successive interarrival times along ONE sample path.
The intensity depends on absolute time, so this advances an internal clock across calls: consecutive samples form a realisation of the process starting at breakpoints[0], not independent draws from a marginal. Use resetSampleClock() to restart. A non-cyclic schedule that runs out returns 0 for every remaining sample, the intensity there being zero.
- class Poisson(lambda_)[source]
Bases:
DiscreteDistributionPoisson distribution.
The Poisson distribution models the number of events occurring in a fixed interval of time or space.
- Parameters:
lambda – Rate parameter (mean = variance = lambda).
Initialize a new distribution.
- class Geometric(p)[source]
Bases:
DiscreteDistributionGeometric distribution.
The geometric distribution models the number of failures before the first success in a sequence of Bernoulli trials.
- Parameters:
p (float) – Probability of success on each trial (0 < p <= 1).
Initialize a new distribution.
- class Binomial(n, p)[source]
Bases:
DiscreteDistributionBinomial distribution.
The binomial distribution models the number of successes in n independent Bernoulli trials.
Initialize a new distribution.
- class NegBinomial(r, p)[source]
Bases:
DiscreteDistributionNegative Binomial distribution.
Models the number of failures before r successes in a sequence of Bernoulli trials.
- Parameters:
Initialize a new distribution.
- class Zipf(s, n=10000)[source]
Bases:
DiscreteDistributionZipf distribution.
The Zipf distribution is a power-law distribution often used to model rank-frequency relationships (e.g., word frequencies).
- Parameters:
Initialize a new distribution.
- class Empirical(data)[source]
Bases:
DiscreteDistributionEmpirical discrete distribution from data.
Creates a distribution from observed data by computing the empirical probability mass function.
- Parameters:
data (list | numpy.ndarray) – Array of observed values.
Initialize a new distribution.
- property probs: numpy.ndarray
Get the probabilities for each value.
- property values: numpy.ndarray
Get the unique values.
- class Bernoulli(p)[source]
Bases:
DiscreteDistributionBernoulli distribution.
The simplest discrete distribution with two outcomes: success (1) with probability p and failure (0) with probability 1-p.
- Parameters:
p (float) – Probability of success (0 <= p <= 1).
Initialize a new distribution.
- class DiscreteUniform(a, b)[source]
Bases:
DiscreteDistributionDiscrete Uniform distribution.
Assigns equal probability to all integers in [a, b].
Initialize a new distribution.
- class DiscreteSampler(p, x=None)[source]
Bases:
DiscreteDistributionGeneral discrete distribution from values and probabilities.
Allows specifying an arbitrary discrete distribution by providing the possible values and their probabilities.
- Supports two calling conventions (matching the MATLAB/JAR API):
DiscreteSampler(p): values are implicitly 1, 2, …, n (MATLAB-style)
DiscreteSampler(p, x): explicit probabilities and values, in this order (MATLAB DiscreteSampler(p,x) / JAR DiscreteSampler(p,x))
- Parameters:
p (list | numpy.ndarray) – Array of probabilities (weights) of each item.
x (list | numpy.ndarray | None) – Array of possible values (only in the two-argument form).
Initialize a new distribution.
- property probs: numpy.ndarray
Get the probabilities.
- property values: numpy.ndarray
Get the possible values.
- class EmpiricalCdf(values, cdf)[source]
Bases:
DiscreteDistributionEmpirical distribution from CDF data.
Creates a distribution from specified CDF points (values and cumulative probabilities).
- Parameters:
values (list | numpy.ndarray) – Sorted array of values.
cdf (list | numpy.ndarray) – Cumulative probabilities at each value (must end with 1.0).
Initialize a new distribution.
- property cdf_values: numpy.ndarray
Get the CDF values.
- property values: numpy.ndarray
Get the values.
- EmpiricalCDF
alias of
EmpiricalCdf
- class Replayer(trace, loop=True)[source]
Bases:
DiscreteDistributionTrace-based distribution that replays recorded values.
Used for simulation where inter-arrival or service times are read from a trace file or data array.
- Parameters:
trace (str | list | numpy.ndarray) – Array of values to replay.
loop (bool) – Whether to loop when trace is exhausted (default: True).
Initialize a new distribution.
- fit_aph()[source]
Fit an acyclic phase-type (APH) distribution to the trace data.
Uses 3-moment matching (mean, SCV, skewness) to determine the optimal APH representation, matching MATLAB’s behavior.
- Returns:
APH distribution fitted to the trace data.
- property trace: numpy.ndarray
Get the trace data.
- class Trace(data, loop=True)[source]
Bases:
ReplayerEmpirical time series from a trace file.
Alias for Replayer with additional moment computation for histogram-style trace data (value, count pairs).
- Parameters:
data (list | numpy.ndarray) – Array of values to replay, or 2-column array of (x, cdf) pairs.
loop (bool) – Whether to loop when trace is exhausted (default: True).
Initialize a new distribution.
- class Coxian(means_or_rates, probs=None)[source]
Bases:
PHCoxian distribution.
A Coxian distribution is a special case of phase-type distributions where transitions can only go to the next phase or to absorption.
- Parameters:
means_or_rates (list | numpy.ndarray) – Service rates (mu) for each phase. Rates are converted to means internally.
probs (list | numpy.ndarray | None) – Transition probabilities (phi). If length equals number of phases, the last element (which should be 1.0 for absorption) is dropped. If length is n-1, used as-is.
Initialize a new distribution.
- classmethod fitCentral(mean, scv, skew=None)
Create a Coxian distribution from central moments.
- classmethod fitMeanAndSCV(mean, scv)
Create a Coxian distribution from mean and SCV.
Uses moment matching to construct a Coxian distribution. Matches MATLAB Coxian.fitMeanAndSCV.
- classmethod fitMeanAndScv(mean, scv)
Create a Coxian distribution from mean and SCV.
Uses moment matching to construct a Coxian distribution. Matches MATLAB Coxian.fitMeanAndSCV.
- classmethod fit_central(mean, scv, skew=None)[source]
Create a Coxian distribution from central moments.
- classmethod fit_mean_and_scv(mean, scv)[source]
Create a Coxian distribution from mean and SCV.
Uses moment matching to construct a Coxian distribution. Matches MATLAB Coxian.fitMeanAndSCV.
- property means: numpy.ndarray
Get the phase means.
- property probs: numpy.ndarray
Get the continuation probabilities.
- class Cox2(mu1, mu2, phi1)[source]
Bases:
Coxian2-phase Coxian distribution.
Convenience class for the common 2-phase case. Mirrors jline.lang.processes.Cox2 and MATLAB Cox2: the phases are given by their RATES, and phi1 is the COMPLETION probability of phase 1 (the job absorbs after phase 1 with probability phi1 and continues to phase 2 with probability 1 - phi1), matching Coxian’s phi convention.
- Parameters:
Initialize a new distribution.
- classmethod fitCentral(mean, var, skew=None)
Fit a 2-phase Coxian to the first three central moments.
Port of jline.lang.processes.Cox2.fitCentral and MATLAB Cox2.fitCentral. This override is REQUIRED for a different reason than fit_mean_and_scv: Coxian.fit_central discards skew and forwards to a two-moment fit, so an inherited Cox2.fitCentral would silently ignore the third moment that the JAR and MATLAB fit exactly.
Falls back to a two-moment fit when the three-moment solution is infeasible, and to a mean-only fit when SCV < 0.5, as the JAR does.
- classmethod fitMean(mean)
Fit a 2-phase Coxian to a mean alone.
Port of jline.lang.processes.Cox2.fitMean and MATLAB Cox2.fitMean.
- classmethod fitMeanAndSCV(mean, scv)
Fit a 2-phase Coxian to a mean and SCV.
Port of jline.lang.processes.Cox2.fitMeanAndSCV and MATLAB Cox2.fitMeanAndSCV, which agree branch for branch.
This override is REQUIRED: Coxian.fit_mean_and_scv builds its result as cls(mu_list, phi_list), a signature Cox2 does not have, so the inherited classmethod raises TypeError on every call. It also may return an Erlang-like fit with more than two phases, which a Cox2 cannot represent.
A 2-phase Coxian cannot achieve SCV < 0.5; there phi1 comes out negative and the constructor rejects it. MATLAB and the JAR build the infeasible object silently instead.
- classmethod fitMeanAndScv(mean, scv)
Fit a 2-phase Coxian to a mean and SCV.
Port of jline.lang.processes.Cox2.fitMeanAndSCV and MATLAB Cox2.fitMeanAndSCV, which agree branch for branch.
This override is REQUIRED: Coxian.fit_mean_and_scv builds its result as cls(mu_list, phi_list), a signature Cox2 does not have, so the inherited classmethod raises TypeError on every call. It also may return an Erlang-like fit with more than two phases, which a Cox2 cannot represent.
A 2-phase Coxian cannot achieve SCV < 0.5; there phi1 comes out negative and the constructor rejects it. MATLAB and the JAR build the infeasible object silently instead.
- classmethod fit_central(mean, var, skew=None)[source]
Fit a 2-phase Coxian to the first three central moments.
Port of jline.lang.processes.Cox2.fitCentral and MATLAB Cox2.fitCentral. This override is REQUIRED for a different reason than fit_mean_and_scv: Coxian.fit_central discards skew and forwards to a two-moment fit, so an inherited Cox2.fitCentral would silently ignore the third moment that the JAR and MATLAB fit exactly.
Falls back to a two-moment fit when the three-moment solution is infeasible, and to a mean-only fit when SCV < 0.5, as the JAR does.
- classmethod fit_mean(mean)[source]
Fit a 2-phase Coxian to a mean alone.
Port of jline.lang.processes.Cox2.fitMean and MATLAB Cox2.fitMean.
- classmethod fit_mean_and_scv(mean, scv)[source]
Fit a 2-phase Coxian to a mean and SCV.
Port of jline.lang.processes.Cox2.fitMeanAndSCV and MATLAB Cox2.fitMeanAndSCV, which agree branch for branch.
This override is REQUIRED: Coxian.fit_mean_and_scv builds its result as cls(mu_list, phi_list), a signature Cox2 does not have, so the inherited classmethod raises TypeError on every call. It also may return an Erlang-like fit with more than two phases, which a Cox2 cannot represent.
A 2-phase Coxian cannot achieve SCV < 0.5; there phi1 comes out negative and the constructor rejects it. MATLAB and the JAR build the infeasible object silently instead.
- class MMPP(Q, lambda_)[source]
Bases:
MAPMarkov-Modulated Poisson Process.
A special case of MAP where arrivals occur according to Poisson processes with rates that depend on an underlying Markov chain state.
- Parameters:
Q (list | numpy.ndarray) – Generator matrix of the modulating Markov chain.
lambda – Vector of Poisson rates for each state.
Initialize a new distribution.
- property Q: numpy.ndarray
Get the modulating Markov chain generator.
- property lambda_: numpy.ndarray
Get the Poisson rates for each state.
- class DMAP(D0, D1)[source]
Bases:
ContinuousDistribution,MarkovianDiscrete-time Markovian Arrival Process.
A DMAP models discrete-time arrival streams with correlation. D0 + D1 is a stochastic matrix (row sums = 1).
- Parameters:
D0 (list | numpy.ndarray) – Sub-stochastic transition matrix (no arrivals).
D1 (list | numpy.ndarray) – Transition matrix with arrivals.
Initialize a new distribution.
- property D0: numpy.ndarray
- property D1: numpy.ndarray
- getRate()[source]
Get the rate parameter (1/mean).
For immediate (zero-mean) distributions, returns GlobalConstants.Immediate (a large but finite value) to avoid numerical issues with infinite rates. This matches MATLAB’s behavior.
- property pi: numpy.ndarray
- setMean(target_mean)
Scale DMAP to match target mean.
- class ME(alpha, A, checkDensity=True)[source]
Bases:
ContinuousDistribution,MarkovianMatrix Exponential distribution.
ME distributions generalize Phase-Type distributions by allowing the initial vector alpha to have entries outside [0,1] and the matrix A to have arbitrary structure (not necessarily a sub-generator).
- Parameters:
alpha (list | numpy.ndarray) – Initial vector (may have negative entries).
A (list | numpy.ndarray) – Matrix parameter (eigenvalues must have negative real parts).
checkDensity (bool) – Scan the density for a negative value (default True). It is set to False only by subclasses whose representation is a density by construction, such as CME, where the scan would cost O(1e5) propagations of a large matrix and can never fire.
Initialize a new distribution.
- property A: numpy.ndarray
Get the matrix parameter.
- property alpha: numpy.ndarray
Get the initial vector.
- evalLST(s)[source]
Evaluate the Laplace-Stieltjes transform at s.
LST(s) = alpha * (s*I - A)^(-1) * (-A) * e, mirroring MATLAB ME.evalLST.
- static fitMoments(moments)
Create ME distribution matching given moments.
Uses the van de Liefvoort algorithm to construct a matrix-exponential distribution that has the specified moments.
- Parameters:
moments (list | numpy.ndarray) – List of moments. To obtain an ME of order M, provide 2*M-1 moments (e.g., 3 moments for order 2, 5 for order 3).
- Returns:
ME distribution matching the given moments.
- Raises:
ValueError – If moments cannot be matched (e.g., invalid structure).
- Return type:
- static fit_moments(moments)[source]
Create ME distribution matching given moments.
Uses the van de Liefvoort algorithm to construct a matrix-exponential distribution that has the specified moments.
- Parameters:
moments (list | numpy.ndarray) – List of moments. To obtain an ME of order M, provide 2*M-1 moments (e.g., 3 moments for order 2, 5 for order 3).
- Returns:
ME distribution matching the given moments.
- Raises:
ValueError – If moments cannot be matched (e.g., invalid structure).
- Return type:
- static fromErlang(k, rate)
Create ME from Erlang distribution.
- static fromExp(rate)
Create ME from exponential distribution.
- static fromHyperExp(p, rates, rate2=None)
Create ME from HyperExp distribution.
Can be called as: - from_hyper_exp(p, rate1, rate2) for 2-phase - from_hyper_exp([p1, p2, …], [r1, r2, …]) for n-phase
- static from_hyper_exp(p, rates, rate2=None)[source]
Create ME from HyperExp distribution.
Can be called as: - from_hyper_exp(p, rate1, rate2) for 2-phase - from_hyper_exp([p1, p2, …], [r1, r2, …]) for n-phase
- getProcess()[source]
Get the process representation as
[D0, D1] = [A, -A*e*alpha].Same convention as MATLAB ME.getProcess (a {D0,D1} cell) and jline.lang.processes.ME.getProcess (a two-entry MatrixCell).
- get_process()[source]
snake_case alias for
getProcess().
- sample(n=1, rng=None)[source]
Generate n samples by inverting the CDF.
A PH-style walk over the phase process is not applicable: alpha may have negative entries and A need not be a sub-generator, so there is no Markov chain to walk. Instead the CDF F(x) = 1 - alpha*exp(A*x)*e is tabulated on a grid covering the tail, inverted by binary search on the table and refined by safeguarded Newton steps against the exact density -alpha*exp(A*x)*A*e. Uniforms beyond the last tabulated point are mapped through the exponential tail of the dominant eigenvalue of A rather than clamped to the grid endpoint, which would truncate the tail and bias the mean low.
- class CME(mean, order)[source]
Bases:
MEConcentrated Matrix Exponential distribution.
A CME is the matrix-exponential distribution of odd order
2*n+1whose squared coefficient of variation is (numerically) minimal for that order, from the tables of Horvath, Horvath and Telek. Its SCV decays as O(1/n^2), so it goes far below the Erlang bound1/orderreachable by a phase-type distribution of the same order: order 101 gives SCV 3.9e-4, where Erlang-101 gives 9.9e-3.The density of the unit-mean CME with
nharmonic terms isf(x) = mu1 * exp(-mu1*x) * (c + sum_k [a_k*cos(k*w*mu1*x) + b_k*sin(k*w*mu1*x)])
with
w = omega, which is exactlyalpha*expm(A*x)*(-A*e)for the block-diagonalA = blkdiag(-mu1, mu1*[[-1,-k*w],[k*w,-1]] for k=1..n). The parametersa,b,c,omegaandmu1are read from the sameiltcme.jsontable used by the CME inverse Laplace transform.- Parameters:
Initialize a new distribution.
- static fitMeanAndSCV(mean, scv)[source]
Create the lowest-order CME with the given mean and SCV at most scv.
- Parameters:
- Returns:
The CME of that order, rescaled to the requested mean.
- Raises:
ValueError – if no tabulated order reaches the requested SCV.
- Return type:
- static fit_mean_and_scv(mean, scv)[source]
snake_case alias for
fitMeanAndSCV().
- static getMinSCV(order)[source]
Get the tabulated minimal SCV attained by a CME of the given order.
- get_order()[source]
snake_case alias for
getOrder().
- class MarkedMAP(process)[source]
Bases:
ContinuousDistribution,MarkovianMarked Markovian Arrival Process.
A MarkedMAP extends MAP to support multiple arrival types (marks/classes). It is defined by matrices D0, D1, D2, …, Dk where: - D0: transitions without arrivals - Dk (k >= 1): transitions with arrivals of type k
- Parameters:
process (list | numpy.ndarray) – List or array of matrices [D0, D1, D2, …, Dk].
Initialize a new distribution.
- sample(n=1, rng=None)[source]
Generate random inter-arrival times and their types.
- Returns:
Tuple of (times, types) arrays.
- Return type:
- class MarkedMMPP(process, num_types)[source]
Bases:
ContinuousDistribution,MarkovianMarked Markov-Modulated Poisson Process (M3PP).
A MarkedMMPP extends MMPP to support multiple arrival types (marks). In each state, arrivals of different types occur according to Poisson processes. The D1k matrices must be diagonal (MMPP constraint).
Uses the M3A representation format: D = {D0, D1, D11, D12, …, D1K} where K is the number of marking types.
- Parameters:
process (list | numpy.ndarray) – List of matrices [D0, D1, D11, D12, …, D1K] or [D0, D11, D12, …, D1K] (D1 computed as sum).
num_types (int) – Number of marking types K.
Initialize a new distribution.
- D(i, j=0)[source]
Get representation matrix.
- Parameters:
- Returns:
The requested matrix.
- Return type:
- class BMAP(process)[source]
Bases:
MarkedMAPBatch Markovian Arrival Process.
BMAP is a point process where arrivals occur in batches. Each matrix Dk represents transitions generating k arrivals.
- Parameters:
process (list | numpy.ndarray) – List of matrices [D0, D1, D2, …, Dk] where Dk is the rate matrix for batch size k.
Initialize a new distribution.
- static from_map_with_batch_pmf(D0, D1, batch_sizes, pmf)[source]
Create BMAP from base MAP and batch size distribution.
- Parameters:
D0 (numpy.ndarray) – Base MAP D0 matrix.
D1 (numpy.ndarray) – Base MAP D1 matrix.
batch_sizes (list) – List of possible batch sizes.
pmf (list) – Probability mass function for batch sizes.
- Returns:
BMAP with specified batch distribution.
- Return type:
- class RAP(H0, H1)[source]
Bases:
ContinuousDistribution,MarkovianRational Arrival Process.
RAP generalizes MAP by allowing the representation matrices to have entries that may lead to complex eigenvalues, as long as the resulting distribution is valid (non-negative PDF and CDF in [0,1]).
Similar to MAP, RAP is defined by two matrices H0 and H1 where: - H0: Rate transitions without arrivals (like D0 in MAP) - H1: Rate transitions with arrivals (like D1 in MAP)
- Parameters:
H0 (list | numpy.ndarray) – Square matrix for transitions without arrivals.
H1 (list | numpy.ndarray) – Square matrix for transitions with arrivals.
Initialize a new distribution.
- property H0: numpy.ndarray
Get the H0 matrix.
- property H1: numpy.ndarray
Get the H1 matrix.
- evalLST(s)[source]
Evaluate the Laplace-Stieltjes transform of the inter-arrival time.
LST(s) = pie * (s*I - H0)^(-1) * (-H0) * e, mirroring MATLAB RAP.evalLST.
- static fromErlang(k, rate)
Create RAP from Erlang distribution.
- static fromExp(rate)
Create RAP from exponential distribution.
- static fromMAP(map_dist)
Create RAP from MAP distribution.
- static fromPoisson(rate)
Create RAP from Poisson process (same as exponential).
- getMu()[source]
Get the total outgoing rate from each phase.
mu_i = -H0(i,i), the same MATLAB Markovian.getMu formula MAP uses. A RAP whose matrices happen to be nonnegative IS a MAP, so the two classes have to answer identically on such a pair; summing H1 instead counts only the arrival transitions and contradicted MAP on exactly that degenerate case.
- getPhi()[source]
Get the probability that a transition out of a phase is an arrival.
phi_i = (H1*e)_i / -H0(i,i), matching MATLAB Markovian.getPhi and MAP. The H0(0,0) == 0 guard mirrors the MATLAB special case for an immediate process.
- getPie()[source]
Get the phase vector embedded at arrival epochs.
This is the equilibrium distribution of the embedded DTMC P = (-H0)^(-1) H1, i.e. pie = pi*H1 / (pi*H1*e). It, and not the time-stationary pi, is the vector that governs the inter-arrival time marginal, matching MATLAB map_pie.
- get_process()[source]
snake_case alias for
getProcess().
- property pi: numpy.ndarray
Get the stationary distribution.
- sample(n=1, rng=None)[source]
Generate n successive inter-arrival times along one sample path.
A RAP has no underlying Markov chain over phases to walk, so sampling carries the conditional phase vector v (normalized so that v*e = 1) instead. Starting from the arrival-embedded vector pie, each draw inverts the conditional survival function v*exp(H0*x)*e at a uniform variate and then updates
v <- v*exp(H0*x)*H1 / (v*exp(H0*x)*H1*e). This reproduces the autocorrelation of the process; drawing from the ME marginal alone would produce independent inter-arrival times.
- class MMDP(Q, R)[source]
Bases:
ContinuousDistribution,MarkovianMarkov-Modulated Deterministic Process.
MMDP models a process where a deterministic RATE is modulated by an underlying Markov chain: in state i arrivals occur deterministically at rate r_i, i.e. one every 1/r_i time units.
Parameterized by rates, mirroring MATLAB MMDP.m and the JAR MMDP.java (MMDP(Q, R), R = diag(r)). This class previously took inter-arrival TIMES d, which made it a different process sharing a name: it reported getMean() = pi.d (the state-averaged time), whereas averaging rates gives 1/(pi.r). The two differ whenever the rates are not all equal, so the same model meant different things per codebase. MATLAB is the reference.
- Parameters:
Q (list | numpy.ndarray) – Generator matrix of the modulating Markov chain (row sums 0).
R (list | numpy.ndarray) – n x n diagonal matrix of deterministic rates, or an n-vector of them.
Initialize a new distribution.
- property Q: numpy.ndarray
Get the generator matrix.
- getMean()[source]
Mean inter-arrival time, the inverse of the mean rate.
Mirrors MATLAB MMDP.getMean. This is 1/(pi.r), not the state-averaged inter-arrival time pi.(1/r): the rate is what the chain modulates.
- class MMDP2(r0, r1, sigma0, sigma1)[source]
Bases:
MMDPMarkov-Modulated Deterministic Process with 2 states.
Convenience class for the common 2-state case.
Parameterized by deterministic RATES, mirroring MATLAB MMDP2.m and the JAR MMDP2.java (which build R = diag([r0, r1])). This class previously took deterministic TIMES d0/d1, which made it a different stochastic object sharing a name: averaging times as pi.d yields the arithmetic mean of the per-state times, whereas the rate parameterization averages rates and reports 1/(pi.r). The two disagree whenever r0 ~= r1, so a model written by one codebase and read by another silently changed meaning. MATLAB is the reference, so the rate form is canonical here too; the JSON wire keys are r0/r1 accordingly.
- Parameters:
Initialize a new distribution.
- dist_scale_rate(distrib, factor)[source]
Return a new distribution whose rate is FACTOR times the rate of DISTRIB, i.e. the time-scaled variable X/FACTOR. The scaling is exact: every moment of order n is divided by FACTOR^n, so the mean is divided by FACTOR while the SCV, the skewness and the whole shape of the distribution are preserved.
The scaled object is rebuilt from the parameters of the original, rather than by rescaling its Markovian representation, so that the parameter list stays coherent with the distribution family. Solvers that serialize the model (JMT, LDES) read the parameters, and would otherwise export the unscaled process.
This is the perturbation primitive of the finite-difference branch of getSensitivityTable: scaling the rate at a station-class by (1+h) is exactly the perturbation the derivative d(.)/d(rate) is taken along.
- Parameters:
distrib – A Distribution object.
factor – Positive scaling factor for the rate.
- Returns:
A new Distribution of the same family with rate*FACTOR.
- distScaleRate(distrib, factor)
Return a new distribution whose rate is FACTOR times the rate of DISTRIB, i.e. the time-scaled variable X/FACTOR. The scaling is exact: every moment of order n is divided by FACTOR^n, so the mean is divided by FACTOR while the SCV, the skewness and the whole shape of the distribution are preserved.
The scaled object is rebuilt from the parameters of the original, rather than by rescaling its Markovian representation, so that the parameter list stays coherent with the distribution family. Solvers that serialize the model (JMT, LDES) read the parameters, and would otherwise export the unscaled process.
This is the perturbation primitive of the finite-difference branch of getSensitivityTable: scaling the rate at a station-class by (1+h) is exactly the perturbation the derivative d(.)/d(rate) is taken along.
- Parameters:
distrib – A Distribution object.
factor – Positive scaling factor for the rate.
- Returns:
A new Distribution of the same family with rate*FACTOR.
API Submodules
Cache API (line_solver.api.cache)
Cache Analysis Algorithms.
Native Python implementations for analyzing cache systems, including exact recursive methods, singular perturbation methods, importance sampling, TTL-based caches, and various approximation techniques.
- Key algorithms:
cache_erec: Exact recursive normalizing constant cache_prob_erec: Exact recursive state probabilities cache_spm: Singular perturbation method cache_miss: Miss rate computation cache_is: Importance sampling cache_ttl_*: TTL-based cache analysis cache_rrm_*: Random replacement model
- cache_lrum_map_levelstats(D0, D1, T)[source]
Level statistics of one item’s embedded (list, phase) chain under the LRU(m)-MAP TTL approximation (Gast and Van Houdt, PEVA 2017, eqs. 5-9).
- Parameters:
D0 (numpy.ndarray) – (d,d) hidden-transition matrix of the item’s MAP
D1 (numpy.ndarray) – (d,d) arrival matrix of the item’s MAP
T (numpy.ndarray) – characteristic times (h,)
- Returns:
time-stationary level probabilities (h+1,), list occupancies (h,), request-weighted hit fractions (h,)
- Return type:
(prob, occ, hitfrac)
References
Original MATLAB: matlab/src/api/cache/cache_lrum_map_levelstats.m
- cache_t_lrum_map(D0c, D1c, m)[source]
Characteristic times for the LRU(m)-MAP TTL approximation.
- Parameters:
D0c (list) – list of per-item (d,d) hidden-transition matrices
D1c (list) – list of per-item (d,d) arrival matrices
m (numpy.ndarray) – cache capacity vector (h,)
- Returns:
Characteristic times (h,)
- Return type:
References
Original MATLAB: matlab/src/api/cache/cache_t_lrum_map.m
- cache_ttl_lrum_map(D0c, D1c, m)[source]
Request-weighted hit/miss probabilities for LRU(m) with per-item MAP request streams (Gast and Van Houdt, PEVA 2017). Intended for items with genuinely distinct or correlated request processes (e.g. marked MAP arrivals); when items are i.i.d. marks of a common stream the request sequence is IRM and the Poisson-based TTL approximations already apply.
- Parameters:
D0c (list) – list of per-item (d,d) hidden-transition matrices
D1c (list) – list of per-item (d,d) arrival matrices
m (numpy.ndarray) – cache capacity vector (h,)
- Returns:
(n,h+1) request-weighted probabilities (column 0 = miss) and (n,h+1) time-stationary level occupancy probabilities
- Return type:
(pij, pijtime)
References
Original MATLAB: matlab/src/api/cache/cache_ttl_lrum_map.m
- cache_erec(gamma, m)[source]
Compute the cache normalizing constant using exact recursive method.
This method serves as a wrapper that calls the auxiliary function to perform the actual computation.
- Parameters:
gamma (numpy.ndarray) – Cache access factors matrix (n x h), where n is number of items and h is number of cache levels.
m (numpy.ndarray) – Cache capacity vector (1 x h or h,).
- Returns:
Normalizing constant E.
- Return type:
- cache_erec_aux(gamma, m, k)[source]
Auxiliary method for computing cache normalizing constant using exact recursive method.
This method performs the core computation recursively, adjusting the size of the input matrix.
- Parameters:
gamma (numpy.ndarray) – Cache access factors matrix (n x h).
m (numpy.ndarray) – Cache capacity vector (h,).
k (int) – Current number of rows in the recursive step.
- Returns:
Normalizing constant for the given configuration.
- Return type:
- cache_prob_erec(gamma, m)[source]
Compute cache state probabilities using exact recursive method.
This method calculates the probabilities of the cache being in different states based on the cache access factors and capacity.
- Parameters:
gamma (numpy.ndarray) – Cache access factors matrix (n x h), where n is number of items and h is number of cache levels.
m (numpy.ndarray) – Cache capacity vector (1 x h or h,).
- Returns:
Matrix (n x h+1) containing cache state probabilities. Column 0 is miss probability, columns 1..h are hit probabilities at each cache level.
- Return type:
- cache_mva(gamma, m)[source]
Mean Value Analysis for cache systems.
Computes cache performance metrics using MVA approach.
- Parameters:
gamma (numpy.ndarray) – Request rate matrix (n x h).
m (numpy.ndarray) – Cache size parameters (h,).
- Returns:
pi: Steady-state probabilities
pi0: Miss probabilities per item
pij: Hit probabilities per item per level (n x h)
x: Throughput vector
u: Utilization vector
E: Normalizing constant
- Return type:
Tuple of (pi, pi0, pij, x, u, E) containing
- cache_xi_iter(gamma, m, tol=1e-12, max_iter=1000)[source]
Compute cache xi terms using iterative method from Gast-van Houdt.
This method calculates the xi values which are important for understanding the distribution of items in the cache. The algorithm assumes that the access factors are monotone with the list index.
- Parameters:
gamma (numpy.ndarray) – Cache access factors matrix (n x h).
m (numpy.ndarray) – Cache capacity vector (h,).
tol (float) – Convergence tolerance (default: 1e-12).
max_iter (int) – Maximum iterations (default: 1000).
- Returns:
Vector of xi values (h,).
- Return type:
- cache_spm(gamma, m)[source]
Approximate the normalizing constant using SPM method.
Computes the normalizing constant of the cache steady state distribution using the singular perturbation method (also known as ray integration).
- Parameters:
gamma (numpy.ndarray) – Cache access factors matrix (n x h).
m (numpy.ndarray) – Cache capacity vector (h,).
- Returns:
Z: Approximated normalizing constant
lZ: Log of normalizing constant
xi: Xi terms vector
- Return type:
Tuple of (Z, lZ, xi) where
- cache_prob_spm(gamma, m)[source]
Compute cache miss probabilities using singular perturbation method.
Uses the SPM (ray integration) method to compute miss probabilities for cache systems.
- Parameters:
gamma (numpy.ndarray) – Cache access factors matrix (n x h).
m (numpy.ndarray) – Cache capacity vector (h,).
- Returns:
Vector of miss probabilities for each item.
- Return type:
- cache_prob_fpi(gamma, m, tol=1e-8, max_iter=1000)[source]
Compute cache hit probabilities using fixed point iteration (FPI method).
Matches MATLAB cache_prob_fpi: Uses fixed point iteration to compute cache hit probability distribution.
- Parameters:
gamma (numpy.ndarray) – Cache access factors matrix (n x h).
m (numpy.ndarray) – Cache capacity vector (h,).
tol (float) – Convergence tolerance (unused, kept for API compatibility).
max_iter (int) – Maximum iterations (unused, kept for API compatibility).
- Returns:
Column 0: miss probabilities
Columns 1:h: hit probabilities at each level
- Return type:
Matrix (n x h+1) where
- cache_miss(gamma, m, lambd=None)[source]
Compute miss rates for a cache system using exact recursive method.
- Parameters:
gamma (numpy.ndarray) – Item popularity probabilities (n x h matrix)
m (numpy.ndarray) – Cache capacity vector (h,)
lambd (numpy.ndarray | None) – Optional arrival rates per user per item (u x n x h+1)
- Returns:
M: Global miss rate
MU: Per-user miss rate (u,) or None
MI: Per-item miss rate (n,) or None
pi0: Per-item miss probability (n,) or None
- Return type:
Tuple of (M, MU, MI, pi0) where
References
Original MATLAB: matlab/src/api/cache/cache_miss.m
- cache_xi_fp(gamma, m, xi_init=None, tol=1e-14, max_iter=10000)[source]
Fixed-point iteration for computing cache performance metrics.
Computes cache performance metrics including Lagrange multipliers, miss probabilities, and hit probabilities.
- Parameters:
gamma (numpy.ndarray) – Item popularity probabilities (n x h)
m (numpy.ndarray) – Cache capacity vector (h,)
xi_init (numpy.ndarray | None) – Optional initial guess for Lagrange multipliers
tol (float) – Convergence tolerance (default: 1e-14)
max_iter (int) – Maximum iterations (default: 10000)
- Returns:
xi: Converged Lagrange multipliers (h,)
pi0: Miss probability per item (n,)
pij: Hit probability per item per list (n x h)
it: Number of iterations
- Return type:
Tuple of (xi, pi0, pij, it) where
References
Original MATLAB: matlab/src/api/cache/cache_xi_fp.m
- cache_miss_fpi(gamma, m, lambd=None)[source]
Compute cache miss rates using fixed-point iteration method.
- Parameters:
gamma (numpy.ndarray) – Item popularity probabilities (n x h)
m (numpy.ndarray) – Cache capacity vector (h,)
lambd (numpy.ndarray | None) – Optional arrival rates per user per item (u x n x h+1)
- Returns:
M: Global miss rate
MU: Per-user miss rate or None
MI: Per-item miss rate or None
pi0: Per-item miss probability or None
- Return type:
Tuple of (M, MU, MI, pi0) where
References
Original MATLAB: matlab/src/api/cache/cache_miss_fpi.m
- cache_miss_spm(gamma, m, lambd=None)[source]
Compute cache miss rates using singular perturbation method.
- Parameters:
gamma (numpy.ndarray) – Item popularity probabilities (n x h)
m (numpy.ndarray) – Cache capacity vector (h,)
lambd (numpy.ndarray | None) – Optional arrival rates per user per item (u x n x h+1)
- Returns:
M: Global miss rate
MU: Per-user miss rate or None
MI: Per-item miss rate or None
pi0: Per-item miss probability or None
lE: Log of normalizing constant
- Return type:
Tuple of (M, MU, MI, pi0, lE) where
References
Original MATLAB: matlab/src/api/cache/cache_miss_spm.m
- cache_mva_miss(p, m, R)[source]
Compute cache miss rates using Mean Value Analysis.
- Parameters:
p (numpy.ndarray) – Item popularity probabilities (n,)
m (numpy.ndarray) – Cache capacity vector (h,)
R (numpy.ndarray) – Routing probabilities (h+1 x n)
- Returns:
M: Global miss rate
Mk: Per-item miss rate (n,)
- Return type:
Tuple of (M, Mk) where
References
Original MATLAB: matlab/src/api/cache/cache_mva_miss.m
- cache_miss_rmf(gamma, m, lambd, tspan=None, x0init=None)[source]
RMF (1/N-accurate) miss rates for RANDOM(m) caches.
Mirrors the cache_miss_fpi contract. gamma is accepted for interface compatibility (used for sizing only); the popularity is recovered from lambd, the (u, n, h+1) per-user per-item arrival rates.
- Parameters:
gamma – item access factors (unused beyond sizing).
m – cache capacity vector (h,).
lambd – arrival rates per user per item per list (u, n, >=1).
tspan – optional [t0, t1]. When given, also integrates the plain mean-field drift over the window and returns the transient trajectory (the same drift that _fixed_point drives to steady state). Omitting tspan preserves the steady-state-only contract.
x0init – optional initial occupancy (dim,) for the transient; defaults to the standard first-m-in-list initial state. Used to carry the cache mean occupancy across environment switches.
- Returns:
Tuple (M, MU, MI, pi0) when tspan is None, else (M, MU, MI, pi0, tout, pi0_t, MU_t, xtraj) with tout (nt,), pi0_t (n, nt) per-item list-0 occupancy, MU_t (u, nt) per-user miss rate, and xtraj (dim, nt) full DDPP occupancy trajectory.
- cache_is(gamma, m, samples=100000)[source]
Importance sampling estimation of cache normalizing constant.
Estimates the normalizing constant for cache models using Monte Carlo importance sampling.
- Parameters:
gamma (numpy.ndarray) – Item popularity probabilities (n x h matrix)
m (numpy.ndarray) – Cache capacity vector (h,)
samples (int) – Number of Monte Carlo samples (default: 100000)
- Returns:
E: Normalizing constant estimate
lE: Log of normalizing constant
- Return type:
Tuple of (E, lE) where
References
Original MATLAB: matlab/src/api/cache/cache_is.m
- cache_prob_is(gamma, m, samples=100000)[source]
Importance sampling estimation of cache hit probabilities.
Estimates cache hit probability distribution using Monte Carlo importance sampling.
- Parameters:
gamma (numpy.ndarray) – Item popularity probabilities (n x h matrix)
m (numpy.ndarray) – Cache capacity vector (h,)
samples (int) – Number of Monte Carlo samples (default: 100000)
- Returns:
prob[i, 0] = miss probability for item i prob[i, 1+j] = hit probability for item i at level j
- Return type:
Cache hit probability matrix (n x h+1)
References
Original MATLAB: matlab/src/api/cache/cache_prob_is.m
- cache_miss_is(gamma, m, lambd=None, samples=100000)[source]
Importance sampling estimation of cache miss rates.
Computes global, per-user, and per-item miss rates using Monte Carlo importance sampling.
- Parameters:
gamma (numpy.ndarray) – Item popularity probabilities (n x h matrix)
m (numpy.ndarray) – Cache capacity vector (h,)
lambd (numpy.ndarray | None) – Optional arrival rates per user per item (u x n x h+1)
samples (int) – Number of Monte Carlo samples (default: 100000)
- Returns:
M: Global miss rate
MU: Per-user miss rate or None
MI: Per-item miss rate or None
pi0: Per-item miss probability or None
lE: Log of normalizing constant
- Return type:
Tuple of (M, MU, MI, pi0, lE) where
References
Original MATLAB: matlab/src/api/cache/cache_miss_is.m
- logmeanexp(x)[source]
Compute log(mean(exp(x))) in a numerically stable way.
Uses the log-sum-exp trick for numerical stability.
- cache_t_hlru(gamma, m)[source]
Characteristic time of each list of an h-LRU / LRU(m) cache.
Solves the TTL (characteristic-time) fixed point of the list-based h-LRU (LRU(m)) policy: sum_k pi_l(k;T) = m[l] for each list l, where the level probabilities follow the birth-death form pi_l ~ prod_{s<=l} (1-e_s)/e_s with e_s = exp(-gamma_k*T_s) (Gast and Van Houdt, SIGMETRICS 2015). Solved by per-list bisection with Gauss-Seidel sweeps.
- Parameters:
gamma (numpy.ndarray) – (n,) per-item request rates; an (n x h) matrix is accepted for backward compatibility (first column used)
m (numpy.ndarray) – Cache capacity vector (h,)
- Returns:
Characteristic time for each cache list (h,)
- Return type:
References
Original MATLAB: matlab/src/api/cache/cache_t_hlru.m
- cache_ttl_hlru(gamma, m)[source]
Steady-state list occupancy probabilities for an h-LRU / LRU(m) cache.
Characteristic-time (TTL) approximation of the list-based h-LRU policy: h LRU lists of capacities m[0..h-1], a miss inserts at the head of list 1, a hit in list l exchanges the item with the tail of list l+1 (Gast and Van Houdt, SIGMETRICS 2015). For h=1 this reduces exactly to the Che approximation for LRU.
- Parameters:
gamma (numpy.ndarray) – Per-item request rates. Accepts (n,), (n x h), or the MVA analyzer layout (u x n x h+1) which is aggregated over users.
m (numpy.ndarray) – Cache capacity vector (h,)
- Returns:
(n x h+1) probabilities; column 0 = not cached, column 1+l = in list l
- Return type:
References
Original MATLAB: matlab/src/api/cache/cache_ttl_hlru.m
- cache_ttl_lrua(lambd, R, m, seed=23000, ttl=None)[source]
Compute steady-state probabilities for TTL-LRU cache with arrival routing.
Uses fixed-point iteration with DTMC solving for cache systems with multiple users, items, and levels with routing.
- Parameters:
lambd (numpy.ndarray) – Arrival rates per user per item per list (u x n x h+1)
R (list) – Routing probability structure. Can be either: - 1D list: R[i] is the (h+1 x h+1) routing matrix for item i - 2D list: R[v][i] is the routing matrix for user v, item i
m (numpy.ndarray) – Cache capacity vector (h,)
seed (int) – Random seed for initialization (default: 23000)
ttl (numpy.ndarray | None) – Optional real TTL per cache level (h,). Caps the characteristic time at each level: items expire after ttl[l] time units even if the cache is not full. Units are in model time (request epochs when arrival rates sum to 1). Use np.inf for levels with no TTL. When TTL is binding, effective occupancy may be less than m[l].
- Returns:
Steady-state probability distribution (n x h+1)
- Return type:
References
Original MATLAB: matlab/src/api/cache/cache_ttl_lrua.m
- cache_rrm_meanfield_ode(t, x, lambd, m, n, h)[source]
ODE function for RRM mean-field cache dynamics.
Defines the differential equations for the Random Replacement Model mean-field cache dynamics.
- Parameters:
t (float) – Time variable (unused, for ODE solver compatibility)
x (numpy.ndarray) – State vector of length n*(h+1), representing probabilities
lambd (numpy.ndarray) – Arrival rates per item (n,)
m (numpy.ndarray) – Cache capacity vector (h,)
n (int) – Number of items
h (int) – Number of cache levels
- Returns:
Time derivative of state vector
- Return type:
References
Original MATLAB: matlab/src/api/cache/cache_rrm_meanfield_ode.m
- cache_rrm_meanfield(lambd, m, t_end=10000.0, seed=23000)[source]
Solve RRM mean-field steady state using ODE integration.
Computes the steady-state probability distribution for a cache with random replacement policy using mean-field ODE dynamics.
- Parameters:
lambd (numpy.ndarray) – Arrival rates per item (n,)
m (numpy.ndarray) – Cache capacity vector (h,)
t_end (float) – End time for ODE integration (default: 10000.0)
seed (int) – Random seed for initial conditions (default: 23000)
- Returns:
prob: Steady-state probability matrix (n x h+1)
missrate: Global miss rate (lambda * miss_prob)
missratio: Miss ratio (missrate / sum(lambda))
- Return type:
Tuple of (prob, missrate, missratio) where
References
Original MATLAB: matlab/src/api/cache/cache_rrm_meanfield.m
- cache_gamma_lp(lambd, R)[source]
Compute gamma parameters for cache models using linear programming approach.
Computes item popularity probabilities at each cache level based on arrival rates and routing probabilities.
- Parameters:
lambd (numpy.ndarray) – Arrival rates per user per item per list (u x n x h+1)
R (list) – Routing probability structure (list of lists, R[v][i] is matrix for user v, item i)
- Returns:
gamma: Item popularity probabilities at each level (n x h)
u: Number of users
n: Number of items
h: Number of cache levels
- Return type:
Tuple of (gamma, u, n, h) where
References
Original MATLAB: matlab/src/api/cache/cache_gamma_lp.m
Product-Form Queueing Networks (line_solver.api.pfqn)
Product-form queueing network (PFQN) algorithms.
Native Python implementations of analytical algorithms for product-form queueing networks, including Mean Value Analysis (MVA), normalizing constant methods, and various approximation techniques.
- Key algorithms:
pfqn_mva: Standard Mean Value Analysis pfqn_ca: Convolution Algorithm pfqn_nc: Normalizing Constant methods pfqn_bs: Balanced System analysis pfqn_aql: Approximate queue lengths
- pfqn_mva(L, N, Z=None, mi=None)[source]
Mean Value Analysis for multi-class closed product-form network.
Implements the exact MVA algorithm using population recursion. Computes exact performance measures for closed product-form networks with load-independent stations.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R) where M is stations, R is classes
N (numpy.ndarray) – Population vector (1 x R or R,) - number of jobs per class
Z (numpy.ndarray) – Think time vector (1 x R or R,) - think time per class (default 0)
mi (numpy.ndarray) – Multiplicity vector (1 x M or M,) - servers per station (default 1)
- Returns:
XN: Throughputs per class (1 x R)
CN: Response times per class (1 x R) - total cycle time
QN: Queue lengths (M x R)
UN: Utilizations (M x R)
RN: Residence times (M x R)
TN: Node throughputs (M x R)
AN: Arrival rates (M x R)
- Return type:
Tuple of (XN, CN, QN, UN, RN, TN, AN) where
- pfqn_mva_single_class(N, L, Z=0.0, mi=None)[source]
Mean Value Analysis for single-class closed network.
Simplified MVA for single customer class, with optional multi-server stations specified via mi (multiplicity).
- Parameters:
N (int) – Number of customers
L (numpy.ndarray) – Service demands at each station (1D array of length M)
Z (float) – Think time (default 0)
mi (numpy.ndarray | None) – Number of servers at each station (default all 1)
- Returns:
‘X’: Throughput
’Q’: Queue lengths (array of length M)
’R’: Residence times (array of length M)
’U’: Utilizations (array of length M)
’lG’: Log of normalizing constant
- Return type:
dict with keys
- pfqn_bs(L, N, Z=None, tol=1e-6, maxiter=1000, QN0=None, type_sched=None)[source]
Bard-Schweitzer Approximate Mean Value Analysis (MVA).
Iterative approximate MVA algorithm that uses the (N-1)/N correction for the arrival theorem, providing good accuracy for most networks.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector
Z (numpy.ndarray) – Think time vector (default 0)
tol (float) – Convergence tolerance (default 1e-6)
maxiter (int) – Maximum iterations (default 1000)
QN0 (numpy.ndarray) – Initial queue lengths (default: uniform distribution)
type_sched (numpy.ndarray) – Scheduling strategy per station (default: PS)
- Returns:
XN: System throughputs (1 x R) QN: Mean queue lengths (M x R) UN: Utilizations (M x R) RN: Residence times (M x R) it: Number of iterations performed
- Return type:
Tuple (XN, QN, UN, RN, it) matching MATLAB’s pfqn_bs
- pfqn_aql(L, N, Z=None, max_iter=1000, tol=1e-6, QN0=None)[source]
Approximate Queue Length (AQL) algorithm.
Uses iterative approximation to compute queue lengths for large populations where exact MVA would be computationally expensive.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector
Z (numpy.ndarray) – Think time vector (default 0)
max_iter (int) – Maximum iterations (default 1000)
tol (float) – Convergence tolerance (default 1e-6)
- Returns:
Same format as pfqn_mva
- Return type:
Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray]
- pfqn_sqni(L, N, Z=None)[source]
Square-root Non-iterative (SQNI) approximate MVA.
Implements a fast approximation for multi-class closed queueing networks that reduces the system to single-queue representations with interpolation-based corrections.
This method is particularly efficient for networks where one station dominates (bottleneck analysis), providing a good trade-off between accuracy and computational speed.
- Parameters:
L (numpy.ndarray) – Service demand vector (1 x R or R,) - demands at the bottleneck queue
N (numpy.ndarray) – Population vector (1 x R or R,) - number of jobs per class
Z (numpy.ndarray) – Think time vector (1 x R or R,) - think time per class (default 0)
- Returns:
Q: Queue lengths (2 x R) - first row for queue, second placeholder
U: Utilizations (2 x R) - first row for queue, second placeholder
X: Throughputs (1 x R)
- Return type:
Tuple of (Q, U, X) where
- Reference:
Based on the SQNI method for approximate MVA analysis.
- pfqn_qd(L, N, ga=None, be=None, Q0=None, tol=1e-6, max_iter=1000)[source]
Queue-Dependent (QD) Approximate MVA.
Implements the QD-AMVA algorithm that uses queue-dependent correction factors to improve accuracy of approximate MVA for closed networks.
The algorithm iteratively computes queue lengths using: - A correction factor delta = (N_tot - 1) / N_tot - Per-class correction factor delta_r = (N_r - 1) / N_r - Optional scaling functions ga(A) and be(A) for advanced corrections
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R) - rows are stations, columns are classes
N (numpy.ndarray) – Population vector (R,) - number of jobs per class
ga (callable) – Gamma scaling function ga(A) -> array(M,) (default: ones) A is the arrival queue seen by class, A[k] = 1 + delta * sum(Q[k,:])
be (callable) – Beta scaling function be(A) -> array(M, R) (default: ones) A is the arrival queue per class, A[k,r] = 1 + delta_r * Q[k,r]
Q0 (numpy.ndarray) – Initial queue length estimate (M x R) (default: proportional)
tol (float) – Convergence tolerance (default 1e-6)
max_iter (int) – Maximum iterations (default 1000)
- Returns:
Q: Mean queue lengths (M x R) X: Class throughputs (R,) U: Utilizations (M x R) iter: Number of iterations performed
- Return type:
Tuple of (Q, X, U, iter) where
- Reference:
Schweitzer, P.J. “Approximate analysis of multiclass closed networks of queues.” Proceedings of the International Conference on Stochastic Control and Optimization (1979).
- pfqn_qdlin(L, N, Z=None, tol=1e-6, max_iter=1000)[source]
QD-Linearizer (QDLIN) Approximate MVA.
Combines Queue-Dependent (QD) correction with Linearizer iteration for improved accuracy in multi-class closed networks.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,) (default: zeros)
tol (float) – Convergence tolerance (default 1e-6)
max_iter (int) – Maximum iterations (default 1000)
- Returns:
Q: Mean queue lengths (M x R) U: Utilizations (M x R) R: Residence times (M x R) X: Class throughputs (1 x R) C: Cycle times (1 x R) iter: Number of iterations performed
- Return type:
Tuple of (Q, U, R, X, C, iter) where
- pfqn_qli(L, N, Z=None, tol=1e-6, max_iter=1000)[source]
Queue-Line (QLI) Approximate MVA (Wang-Sevcik).
Implements the Wang-Sevcik Queue-Line approximation which provides improved accuracy for multi-class networks by better estimating the queue length seen by arriving customers.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,) (default: zeros)
tol (float) – Convergence tolerance (default 1e-6)
max_iter (int) – Maximum iterations (default 1000)
- Returns:
Q: Mean queue lengths (M x R) U: Utilizations (M x R) R: Residence times (M x R) X: Class throughputs (1 x R) C: Cycle times (1 x R) iter: Number of iterations performed
- Return type:
Tuple of (Q, U, R, X, C, iter) where
- Reference:
Wang, W. and Sevcik, K.C. “Performance Models for Multiprogrammed Systems.” IBM Research Report RC 5925 (1976).
- pfqn_fli(L, N, Z=None, tol=1e-6, max_iter=1000)[source]
Fraction-Line (FLI) Approximate MVA (Wang-Sevcik).
Implements the Wang-Sevcik Fraction-Line approximation, an alternative to Queue-Line that uses a different formula for estimating the queue length seen by arriving customers.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,) (default: zeros)
tol (float) – Convergence tolerance (default 1e-6)
max_iter (int) – Maximum iterations (default 1000)
- Returns:
Q: Mean queue lengths (M x R) U: Utilizations (M x R) R: Residence times (M x R) X: Class throughputs (1 x R) C: Cycle times (1 x R) iter: Number of iterations performed
- Return type:
Tuple of (Q, U, R, X, C, iter) where
- Reference:
Wang, W. and Sevcik, K.C. “Performance Models for Multiprogrammed Systems.” IBM Research Report RC 5925 (1976).
- pfqn_bsfcfs(L, N, Z=None, tol=1e-6, max_iter=1000, QN=None, weight=None)[source]
Bard-Schweitzer approximate MVA for FCFS scheduling with weighted priorities.
Implements AMVA with FCFS approximation where classes can have relative priority weights affecting the expected waiting times.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R) where M is stations, R is classes
N (numpy.ndarray) – Population vector (1 x R) - number of jobs per class
Z (numpy.ndarray) – Think time vector (1 x R) - default: zeros
tol (float) – Convergence tolerance (default 1e-6)
max_iter (int) – Maximum iterations (default 1000)
QN (numpy.ndarray) – Initial queue length matrix (M x R) - default: uniform distribution
weight (numpy.ndarray) – Weight matrix (M x R) for relative priorities - default: ones
- Returns:
XN: System throughput per class (1 x R) QN: Mean queue lengths (M x R) UN: Utilizations (M x R) RN: Residence times (M x R) it: Number of iterations performed
- Return type:
Tuple of (XN, QN, UN, RN, it) where
- Reference:
Bard, Y. and Schweitzer, P.J. “Analyzing Closed Queueing Networks with Multiple Job Classes and Multiserver Stations.” Performance Evaluation Review 7.1-2 (1978).
- pfqn_joint(n, L, N, Z=None, lGN=None)[source]
Compute joint queue-length probability distribution.
Computes the joint probability for a given queue-length state vector in a closed product-form queueing network.
- Parameters:
n (numpy.ndarray) – Queue-length state vector (M,) for total or (M x R) for per-class - If 1D (M,): n[i] is the total number of jobs at station i - If 2D (M x R): n[i,r] is the number of class-r jobs at station i
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (1 x R)
Z (numpy.ndarray) – Think time vector (1 x R) - default: zeros
lGN (float) – Log normalizing constant (optional, computed if not provided)
- Returns:
Joint probability of state n
- Return type:
pjoint
Examples
# Total queue-lengths (Z > 0) >>> p = pfqn_joint([2, 1], [[10, 2], [5, 4]], [2, 2], [91, 92])
# Per-class queue-lengths >>> p = pfqn_joint([[1, 0], [0, 1]], [[10, 2], [5, 4]], [2, 2], [91, 92])
- pfqn_ca(L, N, Z=None)[source]
Convolution Algorithm for normalizing constant computation.
Computes the normalizing constant G(N) for a closed product-form queueing network using Buzen’s convolution algorithm.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R) where M is stations, R is classes
N (numpy.ndarray) – Population vector (1 x R or R,) - number of jobs per class
Z (numpy.ndarray) – Think time vector (1 x R or R,) - think time per class (default 0)
- Returns:
G: Normalizing constant
lG: log(G)
- Return type:
Tuple (G, lG) where
- pfqn_is(L, N, Z=None, options=None)[source]
Importance-sampling (IS) estimate of the normalizing constant of a closed LOAD-INDEPENDENT product-form queueing network with M single-server queues of per-class demand L and an aggregated delay of think time Z.
This is the load-independent case of
pfqn_ld_is()(capacities mu_i(k)=1), and the ordinary-network counterpart of the order-independent pfqn_oi_is and the pass-and-swap pfqn_pas_is: all four are the same sample-an-ordering estimator, differing only in the per-position factor of each station’s balance function. For a single-server queue that factor is the demand of the class at that position, L(i,q_p); for the delay it is Z(q_p)/p; for an OI/P&S station it is the reciprocal rank rate 1/mu_i(supp(q_1..q_p)).With ell = sum(N), an ordering c of all ell jobs is drawn by placing a uniformly random present class at each step (probability p(c) = product of the reciprocal branching factors), and the sum over ALL ways of cutting c into contiguous per-station segments is computed exactly by dynamic programming:
G(N) = E_{C~p}[ S(C)/p(C) ], S(c) = sum_{cuts} prod_m prod_p L(m, seg_m(p))
which is unbiased for the exact constant of
pfqn_nc().- Parameters:
L (
(M,R) array) – Per-class service demands at the M single-server queues.N (
(R,) array) – Closed population vector, finite.Z (
(R,) array, optional) – Aggregated think time (delay) demand; None or zeros if none.options (
dictoroptions object, optional) – Fieldssamples(default 1e4) andseed(optional).
- Returns:
(G, lG) – IS estimate of the normalizing constant and its logarithm.
- Return type:
Examples
>>> L = np.array([[0.5, 0.3], [0.2, 0.4]]); N = np.array([3, 2]); Z = np.array([1.0, 1.0]) >>> G, lG = pfqn_is(L, N, Z, {'samples': 100000})
See also
- pfqn_nc(L, N, Z=None, method='ca', options=None)[source]
Normalizing constant computation dispatcher.
Selects appropriate algorithm based on method parameter.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,) (default: zeros)
method (str) – Algorithm to use: - ‘ca’, ‘exact’: Convolution algorithm - ‘default’: Auto-select based on problem size - ‘le’: Leading eigenvalue asymptotic - ‘cub’: Controllable upper bound - ‘imci’: Importance sampling Monte Carlo integration - ‘panacea’: Hybrid convolution/MVA - ‘propfair’: Proportionally fair allocation - ‘mmint2’: Gauss-Legendre quadrature - ‘gleint’: Gauss-Legendre integration - ‘sampling’: Monte Carlo sampling - ‘kt’: Knessl-Tier expansion - ‘comom’: Conditional moments - ‘rd’: Reduction heuristic - ‘ls’: Linearizer
- Returns:
Tuple (G, lG) - normalizing constant and its log
- Return type:
- pfqn_nc_resolved_method(method)[source]
The algorithm pfqn_nc actually runs for METHOD.
pfqn_nc substitutes a different algorithm for some method names, so the requested name is not always the one that ran. Callers that report the method to the user must resolve it through here, otherwise the banner names an algorithm that never executed.
Currently only ‘comom’ substitutes: the native pfqn_comomrm port is not numerically robust for R>1, so convolution is used instead, which is exact for the single-station product-form models CoMoM-RM targets. The substitution is unconditional, hence resolvable without solving. Note this is BROADER than MATLAB, whose pfqn_nc reports ‘ca’ only for the R==1 case and genuinely runs CoMoM-RM for R>1 with a single queue.
- pfqn_panacea(L, N, Z=None)[source]
PANACEA algorithm (hybrid convolution/MVA).
Currently implemented as wrapper around convolution algorithm.
- Parameters:
L (numpy.ndarray) – Service demand matrix
N (numpy.ndarray) – Population vector
Z (numpy.ndarray) – Think time vector
- Returns:
Tuple (G, lG) - normalizing constant and its log
- Return type:
- pfqn_propfair(L, N, Z=None)[source]
Proportionally Fair allocation approximation for normalizing constant.
Estimates the normalizing constant using a convex optimization program that is asymptotically exact in models with single-server PS queues only.
This method is based on Schweitzer’s approach and Walton’s proportional fairness theory for multi-class networks.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R) where M is stations, R is classes
N (numpy.ndarray) – Population vector (1 x R or R,) - number of jobs per class
Z (numpy.ndarray) – Think time vector (1 x R or R,) - think time per class (default 0)
- Returns:
G: Estimated normalizing constant
lG: log(G)
X: Asymptotic throughputs per class (1 x R)
- Return type:
Tuple (G, lG, X) where
References
Schweitzer, P. J. (1979). Approximate analysis of multiclass closed networks of queues. In Proceedings of the International Conference on Stochastic Control and Optimization.
Walton, N. (2009). Proportional fairness and its relationship with multi-class queueing networks.
- pfqn_ls(L, N, Z=None, I=100000)[source]
Logistic sampling approximation for normalizing constant.
Approximates the normalizing constant using importance sampling from a multivariate normal distribution fitted at the leading eigenvalue mode.
This method is particularly effective for large networks where convolution becomes computationally expensive.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,) (default: zeros)
I (int) – Number of samples for Monte Carlo integration (default: 100000)
- Returns:
G: Estimated normalizing constant lG: log(G)
- Return type:
Tuple (G, lG) where
- Reference:
G. Casale. “Accelerating performance inference over closed systems by asymptotic methods.” ACM SIGMETRICS 2017.
- pfqn_clw(L, N, Z=None, m=None, l=None, gamma=None)[source]
Choudhury-Leung-Whitt normalization constant by numerical inversion of the generating function (JACM 42(5):935-970, 1995).
Computes g(K) of a multichain closed product-form network with single-server and (optionally) infinite-server queues by numerically inverting its p-dimensional generating function (eq. 4.5)
G(z) = exp(sum_j rho_{j0} z_j) / prod_i (1 - sum_j rho_{ji} z_j)^{m_i}
where j=1..p indexes chains, i=1..q’ the distinct single-server queues with multiplicity m_i. g(K) is recovered by p nested one-dimensional lattice-Poisson inversions (eq. 2.3) with restrictive static scaling (eqs. 5.41-5.46) and log-domain recovery (eq. 7.1).
- Parameters:
L (numpy.ndarray) – (q’ x p) single-server relative traffic intensities, L[i,j]=rho_{ji}.
N (numpy.ndarray) – (p,) closed-chain population vector K.
Z (numpy.ndarray) – (p,) aggregate infinite-server relative intensities rho_{j0}. Default 0.
m (numpy.ndarray) – (q’,) queue multiplicities m_i. Default ones.
l (numpy.ndarray) – (p,) inner lattice parameters l_j. Default 1,2,2,3,3,…
gamma (numpy.ndarray) – (p,) aliasing parameters gamma_j. Default 11,13,13,15,15,…
- Returns:
normalization constant (inf if it overflows double) and its natural logarithm (always finite).
- Return type:
Tuple (G, lG)
Note: exact nested inversion of cost prod_j 2 l_j K_j; practical for moderate populations and few chains. The paper’s Euler summation and dimension reduction speed-ups are not applied here.
- pfqn_clw_lld(L, N, Z=None, mu=None, l=None, gamma=None)[source]
Choudhury-Leung-Whitt normalization constant by numerical inversion of the generating function (JACM 42(5):935-970, 1995), extended to limited load-dependent (LLD) stations via the per-center transforms of Bertozzi and McKenna (SIAM Review 35(2):239-268, 1993).
The generating function is (Bertozzi-McKenna eqs. 2.17/2.23)
G(z) = exp(sum_j rho_{j0} z_j) prod_i F_i(sum_j rho_{ji} z_j)
where F_i is the transform of the station factor of queue i (eq. 2.16) with load-dependent rate scalings S_i(k) = mu[i,k]. For an LLD queue, S_i(k) = c_i constant for k >= l_i, and F_i is the rational function (eq. 2.19)
- F_i(x) = [c_i + sum_{n=1}^{l_i-1} (c_i - S_i(n))
/ prod_{k=1}^n S_i(k) * x^n] / (c_i - x),
analytic except for a simple pole at x = c_i. Multiserver and load-independent queues are special cases. Since g(K) depends on S_i(k) only for k <= sum(K), general load-dependent input is truncated to LLD at sum(K) without loss of exactness.
g(K) is recovered by p nested one-dimensional lattice-Poisson inversions (CLW eq. 2.3) with restrictive static scaling adapted from CLW eqs. 5.41-5.46 (each queue normalized by its pole c_i, simple pole) and log-domain recovery (eq. 7.1).
- Parameters:
L (numpy.ndarray) – (q’ x p) single-server relative traffic intensities, L[i,j]=rho_{ji}.
N (numpy.ndarray) – (p,) closed-chain population vector K.
Z (numpy.ndarray) – (p,) aggregate infinite-server relative intensities rho_{j0}. Default 0.
mu (numpy.ndarray) – (q’ x n) load-dependent rate scalings mu[i,k] = S_i(k+1); if fewer than sum(N) columns are given the last column is extended (LLD assumption). Default ones (all queues load-independent).
l (numpy.ndarray) – (p,) inner lattice parameters l_j. Default 1,2,2,3,3,…
gamma (numpy.ndarray) – (p,) aliasing parameters gamma_j. Default 11,13,13,15,15,…
- Returns:
normalization constant (inf if it overflows double) and its natural logarithm (always finite).
- Return type:
Tuple (G, lG)
Note: cost is prod_j 2 l_j K_j contour points, each of cost O(sum_i l_i); practical for moderate populations and few chains.
- pfqn_linearizer(L, N, Z, sched_type, tol=1e-8, maxiter=1000, QN0=None)[source]
Linearizer approximate MVA algorithm.
- Parameters:
L (numpy.ndarray) – Demand matrix (M x R) - rows are stations, columns are classes
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,)
sched_type (List[str]) – List of scheduling strategies per station (‘FCFS’, ‘PS’, etc.)
tol (float) – Convergence tolerance
maxiter (int) – Maximum iterations
- Returns:
Q: Queue lengths (M x R) U: Utilizations (M x R) W: Waiting times (M x R) T: Station throughputs (M x R) C: Response times (1 x R) X: Class throughputs (1 x R) iterations: Number of iterations
- Return type:
Tuple of (Q, U, W, T, C, X, iterations)
- pfqn_gflinearizer(L, N, Z, sched_type, tol=1e-8, maxiter=1000, alpha=1.0, QN0=None)[source]
General-form linearizer approximate MVA.
- Parameters:
L (numpy.ndarray) – Demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,)
sched_type (List[str]) – List of scheduling strategies per station
tol (float) – Convergence tolerance
maxiter (int) – Maximum iterations
alpha (float) – Linearization parameter (scalar)
- Returns:
Same as pfqn_linearizer
- Return type:
Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, int]
- pfqn_egflinearizer(L, N, Z, sched_type, tol=1e-8, maxiter=1000, alpha=None, QN0=None)[source]
Extended general-form linearizer with class-specific parameters.
- Parameters:
L (numpy.ndarray) – Demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,)
sched_type (List[str]) – List of scheduling strategies per station
tol (float) – Convergence tolerance
maxiter (int) – Maximum iterations
alpha (numpy.ndarray) – Class-specific linearization parameters (R,)
- Returns:
Tuple of (Q, U, W, T, C, X, iterations)
- Return type:
Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, int]
- pfqn_momlin(L, N, Z=None, tol=1e-8, maxiter=1000)[source]
Approximate first and second queue-length moments of a closed product-form network, scalable to large populations and many classes.
- Parameters:
- Return type:
- class PfqnMomlin(Q, X, U, R, QVar, QCov, dQ)[source]
Bases:
objectResult container for
pfqn_momlin().- Q
Mean queue length.
- Type:
np.ndarray (M x R)
- X
Throughput per class.
- Type:
np.ndarray (1 x R)
- U, R
Utilization and residence time.
- Type:
np.ndarray (M x R)
- QVar
Queue-length variance.
- Type:
np.ndarray (M x R)
- QCov
Queue-length covariance,
QCov[i, r, j, s] = Cov[n_ir, n_js].- Type:
np.ndarray (M x R x M x R)
- dQ
Demand derivatives,
dQ[i, r, j, s] = dQ_ir/dD_js.- Type:
np.ndarray (M x R x M x R)
- pfqn_sens(L, N, Z=None, mi=None)[source]
Exact derivatives of {X, Q, U, R} w.r.t. demands L and think times Z.
Derivatives are analytic (exact to machine precision), not finite differences. The CoMoM-backed kernel is selected for the repairman model (a single single-server queue, M=1, plus a think-time delay where every populated class has positive think time and demand); it is polynomial in the number of classes R. Every other model uses forward-mode differentiation of the exact MVA recursion.
- Parameters:
L (
(M,R) array) – Service demand matrix,L[i, r] = visits_ir / rate_ir.N (
(R,) array) – Population per class.Z (
(R,) array, optional) – Think time per class (default zeros).mi (
(M,) array, optional) – Station residence multiplicity (default ones).
- Return type:
- class PfqnSens(X, Q, U, R, params, dX, dQ, dU, dR, QCov=None, QVar=None, QTotVar=None, QCovAsym=None)[source]
Bases:
objectResult container for
pfqn_sens().- X, Q, U, R
Base MVA measures.
Xis (1 x R) system throughput per class,Q(M x R) mean queue length,U(M x R) utilization,R(M x R) residence time per visit.- Type:
np.ndarray
- params
One entry per differentiation parameter
pwith keystype(‘L’ or ‘Z’),station(i, or -1 for Z) andjobclass(r).
- dX
- Type:
np.ndarray (R x P)
- dQ, dU, dR
Derivative of each base measure w.r.t. parameter
p.- Type:
np.ndarray (M x R x P)
- QCov
Queue-length covariance,
QCov[i, r, j, s] = Cov[n_ir, n_js] = D_js dQ_ir/dD_js. The same-station blocks (i == j) come frompfqn_sens_mva(); the cross-station ones are read off the Jacobian.- Type:
np.ndarray (M x R x M x R)
- QVar
Queue-length variance,
QVar[i, r] = QCov[i, r, i, r].- Type:
np.ndarray (M x R)
- QTotVar
Variance of the total queue length per station,
QTotVar[i] = Var[sum_r n_ir].- Type:
np.ndarray (M,)
- QCovAsym
Roundoff-level residual of the moment recursion, see
pfqn_sens_mva().- Type:
- pfqn_sens_mva(L, N, Z=None, mi=None)[source]
Exact second moments of the queue lengths of a closed product-form network.
The moments are obtained by an MVA-type recursion evaluated on the same population lattice as
pfqn_mva(), so no derivative of the model is ever formed and the cost is O(M*R^2) per lattice point rather than the O(M^2*R^2) of the differentiated-MVA kernel used bypfqn_sens().The recursion is obtained by differentiating the Reiser-Lavenberg MVA equation
Q(j,v|N) = X(v|N) L(j,v) (mi(j) + Qtot(j|N-e_v))with respect to the visit ratiotheta(i,k)of classkat stationiand rescaling. WritingW(k,i;v,j|N) = Cov[n(i,k), n(j,v)]at population N,- W(k,i;v,j|N) = Q(j,v|N) (Q(i,k|N-e_v) - Q(i,k|N))
[i==j & k==v] Q(j,v|N)
X(v|N) L(j,v) sum_t W(k,i;t,j|N-e_v)
with
W(.|0) = 0. This routine evaluates the same-station casei==j, which is self-contained: the inner sum then only involves same-station terms, so a single scalarSsum(j,k|N) = sum_t W(k,j;t,j|N)carried along the lattice closes the recursion. The cross-station casei != jis not self-contained (it couples every station pair) and costs as much as the full Jacobian, so it is left topfqn_sens().Setting
i == jandmi == 1reproduces Corollary 1 of de Souza e Silva and Muntz, i.e. its equations (2.9a) for the variance and (2.10) for the covariance; the station multiplicitymicancels identically becauseX(v|N) L(j,v) (mi(j) + Qtot(j|N-e_v)) = Q(j,v|N)is the MVA equation for anymi. The equivalent statement for an infinite-server station, equation (2.9b), is recovered automatically because LINE folds the delay into the think timeZ, which enters only throughX(v|N)and carries no queue-length moment of its own.- Parameters:
L (
(M,R) array) – Service demand matrix,L[i, r] = visits_ir / rate_ir.N (
(R,) array) – Population per class. Must be finite (closed populations only).Z (
(R,) array, optional) – Think time per class (default zeros).mi (
(M,) array, optional) – Server multiplicity per station (default ones).
- Return type:
Notes
Restricted to closed populations. Mixed and load-dependent models are handled by
pfqn_sens_mvaldmx().For a station of multiplicity
mi[i] > 1, which LINE treats asmi[i]identical replicas sharing the demand rowL[i, :], the moments returned are those of the aggregate queue length over the replicas.
- class PfqnSensMva(X, Q, U, R, QCov, QVar, QTotVar, QCovAsym)[source]
Bases:
objectResult container for
pfqn_sens_mva().- X, Q, U, R
Base MVA measures, identical entry by entry to
pfqn_mva(L, N, Z, mi).Xis (1 x R) system throughput per class,Q(M x R) mean queue length,U(M x R) utilization,R(M x R) residence time per visit.- Type:
np.ndarray
- QCov
QCov[i, r, s] = Cov[n(i,r), n(i,s)], the queue-length covariance of classesrandsat stationi. Symmetric in(r, s).- Type:
np.ndarray (M x R x R)
- QVar
QVar[i, r] = QCov[i, r, r] = Var[n(i,r)].- Type:
np.ndarray (M x R)
- QTotVar
QTotVar[i] = Var[sum_r n(i,r)], i.e.sum_{r,s} QCov[i, r, s]. This is Theorem 3 of de Souza e Silva and Muntz, obtained here without a capacity derivative.- Type:
np.ndarray (M,)
- pfqn_sens_ldmx_ec(lam, D, mu)[source]
Effective capacity terms of the mixed load-dependent MVA and their exact derivatives with respect to the open-class load.
Computes the terms
EC,EandEprimeof the mixed load-dependent MVA of Bruell-Balbo-Afshari, exactly aspfqn_ldmx_ec()does, and additionally their exact analytic derivatives with respect to the open-class loadLo[i]of each station.Lo[i] = sum_r lambda[r] D[i, r]is the only channel through which a service demand entersE,EprimeandEC: the load-dependent ratesmuare independent of the demands. Stationi’s terms depend onLo[i]alone, so a single derivative per station is enough, and the chain rule then yields the derivative with respect to any demand-scaling parameter. This is the factorization behind equations (19), (21) and (24)-(31) of Akyildiz and Strelen, which are reproduced here term by term.- Parameters:
lam (
(R,) array) – Arrival rate vector. Zero for closed classes.D (
(M,R) array) – Service demand matrix.mu (
(M,Nt) array) – Load-dependent rate matrix, limited load dependence.
- Returns:
EC (
(M,Nt) array) – Effective capacity matrix.E (
(M,1 + Nt) array) – E-function values,E[i, n]holding the MATLABE(i, 1+n).Eprime (
(M,1 + Nt) array) – E-prime function values, indexed asE.Lo (
(M,) array) – Open class load vector.dEC (
(M,Nt) array) –dEC[i, n] = dEC(i, n)/dLo(i).dE (
(M,1 + Nt) array) –dE[i, n] = dE(i, n)/dLo(i).dEprime (
(M,1 + Nt) array) –dEprime[i, n] = dEprime(i, n)/dLo(i).
- Return type:
Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray]
- pfqn_sens_mvaldmx(lam, D, N, Z, mu=None, S=None)[source]
Exact second moments of the queue lengths of a mixed open/closed product-form network with limited load-dependent service rates.
This is the load-dependent and mixed counterpart of
pfqn_sens_mva(), which is restricted to closed load-independent models.The method is the moment analysis of Akyildiz and Strelen. Their Theorem 1, equation (11), states that multiplying a queue-length moment by one further factor
Q_jTcosts one derivative with respect to a parametery_jthat scales the service demandss_irof the classesrinTat stationj:- E[Q_jT^k …] = d/dy_j E[Q_jT^(k-1) …]|_{y_j=1}
nbar_jT E[Q_jT^(k-1) …]
Taking
k=2andT={s}gives the second moment, henceCov[n(i,r), n(j,s)] = d nbar(i,r) / dy_(j,s) |_{y=1}
which is evaluated here by forward-mode differentiation of the mixed load-dependent MVA of Bruell-Balbo-Afshari, i.e. of exactly the recursion implemented by
pfqn_mvaldmx(). The differentiated equations are (13) for the residence times, (15)-(17) for the conditional marginal probabilities, (18) for the throughputs, (19) and (24)-(31) for the effective capacities (delegated topfqn_sens_ldmx_ec()), (32) for the closed-class queue lengths and (33) for the open-class ones.Because a demand-scaling parameter perturbs the whole network through the closed-class throughputs, the derivatives must be propagated for every parameter, so the cross-station covariances come out at no extra cost and are returned in
QCovFull. This is unlikepfqn_sens_mva(), whose cheaper same-station recursion cannot reach them.- Parameters:
lam (
(R,) array) – Arrival rate vector. Must be zero on closed classes.D (
(M,R) array) – Service demand matrix.N (
(R,) array) – Population vector.infentries denote open classes.Z (
(R,) array) – Think time vector.mu (
(M,sum(N)) array, optional) – Load-dependent rate matrix, limited load dependence (default ones).S (
(M,) array, optional) – Number of servers per station. Accepted for signature compatibility withpfqn_mvaldmx(), which likewise does not read it: the multiserver behaviour is carried entirely by the ratesmu.
- Return type:
Notes
Open classes are supported: an open class contributes to the load
Lo[i]that drives the effective capacities, and equation (21) supplies the correspondingdLo/dy.The moments of an open class are those of its queue length at a station, which is finite even though its population is infinite.
- class PfqnSensMvaldmx(X, Q, U, R, QCov, QCovFull, QVar, QTotVar, QCovAsym)[source]
Bases:
objectResult container for
pfqn_sens_mvaldmx().- X, Q, U, R
Base measures, identical to
pfqn_mvaldmx(lambda, D, N, Z, mu, S).Xis (R,) throughput per class,Q(M x R) mean queue length,U(M x R) utilization,R(M x R) residence time.- Type:
np.ndarray
- QCov
QCov[i, r, s] = Cov[n(i,r), n(i,s)], the same-station block.- Type:
np.ndarray (M x R x R)
- QCovFull
QCovFull[i, r, j, s] = Cov[n(i,r), n(j,s)].- Type:
np.ndarray (M x R x M x R)
- QVar
QVar[i, r] = Var[n(i,r)].- Type:
np.ndarray (M x R)
- QTotVar
QTotVar[i] = Var[sum_r n(i,r)].- Type:
np.ndarray (M,)
- pfqn_sens_mom(L, N, Z=None, mi=None, groups=None)[source]
Exact moments E[Q_i], E[Q_i^2], E[Q_i^3] and the covariances Cov[Q_i,Q_j] of the TOTAL queue lengths
Q_i = sum_r n(i,r)of a closed product-form (BCMP) queueing network.The method is the moment analysis of Strelen. Its Theorem 3.1 states that one further factor
Q_iin a moment costs one differentiation with respect tox_i, the reciprocal of the capacity of stationi, i.e. a parameter that scales the service times of ALL classes at stationi:E[Q_i^j] = m_i E[Q_i^(j-1)] + x_i d/dx_i E[Q_i^(j-1)], Q_i^0 = 1
Iterating from
E[Q_i^0] = 1gives, withm_i = E[Q_i], equation (3.2):Var[Q_i] = x_i dm_i/dx_i Cov[Q_i,Q_j] = x_j dm_i/dx_j = x_i dm_j/dx_i E[Q_i^2] = x_i dm_i/dx_i + m_i^2 E[Q_i^3] = x_i^2 d^2m_i/dx_i^2 + (x_i + 3 x_i m_i) dm_i/dx_i + m_i^3
so the third moment requires the SECOND derivative of the MVA recursion, which is what this routine adds over
pfqn_sens_mva()andpfqn_sens()(both first order only). The derivatives are obtained by second-order forward-mode differentiation of the Reiser-Lavenberg recursion, i.e. by carrying, for each parameter, the value together with its first and second derivative along the population lattice (Theorem 3.2 for one class, Theorem 3.5 for several).The parameter need not scale a whole column. Theorem 1 of Akyildiz and Strelen states the same recursion for a parameter that scales the service times of an arbitrary class subset
Tat stationi, and the moments it generates are then those ofQ_(i,T) = sum_(r in T) n(i,r).groupssupplies that subset structure: it partitions the classes, and the routine reports the moments of each group’s queue length at each station. The three useful settings are:groups = ones(R) the whole column: per-station TOTALS (default, this is Strelen's x_i) groups = 1..R one class per group: PER-CLASS moments, so that even the third moment is per class groups = chain(r) one group per chain: PER-CHAIN moments
Strelen states only the first; the generalization is Akyildiz and Strelen’s
T. The per-class setting reproducespfqn_sens_mva()’s second moments exactly.- Parameters:
L (
(M,R) array) – Service demand matrix,L[i, r] = visits_ir / rate_ir.N (
(R,) array) – Population per class. Must be finite (closed populations only).Z (
(R,) array, optional) – Think time per class (default zeros).mi (
(M,) array, optional) – Server multiplicity per station (default ones).groups (
(R,) array, optional) – Class-to-group map, a partition of the classes intoG = max(groups)groups labelled consecutively 1..G with no empty group. Defaultones(R), i.e. one group holding every class, the per-station total. Labels are 1-based, as in MATLAB.
- Return type:
Notes
Restricted to closed populations, as is the moment analysis of the reference. Mixed and load-dependent second moments are in
pfqn_sens_mvaldmx().Moments of the sojourn times at FCFS centers are built on top of these queue-length moments by
pfqn_sens_respt(), following Theorem 4.1.The exact recursion costs
O(prod(N+1))lattice points;pfqn_sens_linearizer()approximates the same quantities in polynomial time.
- class PfqnSensMom(X, Q, U, R, m, dm, d2m, Var, Cov, M2, M3, Skew, CovAsym)[source]
Bases:
objectResult container for
pfqn_sens_mom().- X, Q, U, R
Base MVA measures, identical entry by entry to
pfqn_mva(L, N, Z, mi).Xis (1 x R),Q,UandRare (M x R).- Type:
np.ndarray
- m
m[i, g] = E[Q_(i,g)], the mean queue length of groupgat stationi. COLLAPSED to (M,) in the default single-group case, where it is the per-station total.- Type:
np.ndarray (M,G)
- dm
dm[i, g, j, g2], the scaled first derivative ofm_(i,g)with respect to the parameter of(j, g2). Collapsed to (M, M) when G == 1.- Type:
np.ndarray (M,G,M,G)
- d2m
d2m[i, g], the scaled pure second derivative with respect to the parameter of(i, g). Only that entry is needed by (3.2); the mixed second derivatives are not required for moments of a singleQ_(i,g)and would cost an extra factorM*Gto carry. Collapsed to (M,) when G == 1.- Type:
np.ndarray (M,G)
- Var
Var[Q_(i,g)]. Collapsed to (M,) when G == 1.- Type:
np.ndarray (M,G)
- Cov
Cov[i, g, j, g2] = Cov[Q_(i,g), Q_(j,g2)]. Collapsed to (M, M) when G == 1, where the group index carries no information.- Type:
np.ndarray (M,G,M,G)
- M2
E[Q_(i,g)^2]. Collapsed to (M,) when G == 1.- Type:
np.ndarray (M,G)
- M3
E[Q_(i,g)^3]. Collapsed to (M,) when G == 1.- Type:
np.ndarray (M,G)
- Skew
Skewness of
Q_(i,g), i.e. the third central moment divided byVar^(3/2). NaN where the variance is zero (a deterministic queue length). Collapsed to (M,) when G == 1.- Type:
np.ndarray (M,G)
- pfqn_sens_respt(S, V, N, Z=None, b=None, tmax=3)[source]
Exact raw moments
E[W_(i,l)^t],t = 1..tmax, of the sojourn time of a class-l job at an FCFS b-server centeriof a closed product-form queueing network, together with the variance of that sojourn time.This is Theorem 4.1 of the reference. Its mechanism is the arrival theorem of Lavenberg-Reiser and Sevcik-Mitrani: a class-l job arriving at center
ifindsjjobs already there with probabilityp_i(j, N - 1_l). Conditioning the sojourn time onjand inverting the Laplace transform of the conditional density gives:E[W_(i,l)^t] = t!/mu^t + sum_{tau=0..t} a_(t,tau)(0) E[Qt_i^tau] - sum_{j=0..b-1} p_i(j,N-1_l) sum_{tau=0..t} a_(t,tau)(0) j^tauwhere
mu = 1/S(i)is the rate of each of thebservers,Qt_iis the total queue length at centeriat populationN - 1_l(so its moments are those ofpfqn_sens_mom()evaluated one job down in classl), and the coefficientsa_(t,tau)(0)depend only onbandmu, not on the network (Remark 4.3 of the reference). The momentsE[Qt_i^tau]up totau = 3need the second derivative of the MVA recursion, so this routine carries a second-order forward-mode pass exactly aspfqn_sens_mom()does, but over the b-server recursion (4.1)-(4.2) rather than the single-server one.For
b = 1the coefficientsa_(t,0)(0)vanish identically and the double-sum correction disappears, so no marginal probabilities are needed (Remark 4.2 of the reference); the routine still evaluates the general expression, which reduces to that case on its own.Only FCFS centers are covered. The reference is explicit that the sojourn-time distribution at PS and LCFS centers is in general not known, so no analogue exists there. FCFS in a BCMP network further requires the service time to be exponential and class-independent, which is why this routine takes a per-station service time
S(i)and a separate visit-ratio matrixVrather than a demand matrix: the sojourn time is per visit, so the per-visit ratemu = 1/S(i)must be known and cannot be recovered from the demandL(i,l) = S(i)*V(i,l)alone.- Parameters:
S (
(M,) array) – Service time at each station, common to all classes.V (
(M,R) array) – Visit ratio matrix. The demand isL[i, r] = S[i] * V[i, r].N (
(R,) array) – Population per class. Must be finite (closed populations only).Z (
(R,) array, optional) – Think time per class (default zeros).b (
(M,) array, optional) – Number of servers at each station (default ones).tmax (
int, optional) – Highest sojourn-time moment to return, 1..3 (default 3). The coefficientsa_(t,tau)(0)are tabulated in the reference up tot = 3.
- Return type:
Notes
Restricted to closed populations. Load-dependent rates are not covered here; the b-server dependence is the only state dependence, and it is carried exactly by (4.1)-(4.2).
- class PfqnSensRespt(X, Q, U, m, Var, p, W, WM, Wresid, WVar, WSkew)[source]
Bases:
objectResult container for
pfqn_sens_respt().- X, Q, U
Base measures at population
N.Xis (1 x R),QandUare (M x R).- Type:
np.ndarray
- W
W[i, l] = E[W_(i,l)], the mean sojourn time per visit of a class-l job at stationi. Zero where classldoes not visiti.- Type:
np.ndarray (M,R)
- WM
WM[i, l, t-1] = E[W_(i,l)^t].- Type:
np.ndarray (M,R,tmax)
- WVar
Var[W_(i,l)] = E[W^2] - E[W]^2. Requirestmax >= 2.- Type:
np.ndarray (M,R)
- WSkew
Skewness of
W_(i,l). Requirestmax >= 3; NaN if the variance is zero.- Type:
np.ndarray (M,R)
- m
E[Q_i]at populationN, the total queue length.- Type:
np.ndarray (M,)
- Var
Var[Q_i]at populationN.- Type:
np.ndarray (M,)
- p
p[i, j] = P[Q_i = j]at populationN, forj = 0..b_i-1. These are the only marginal probabilities the b-server recursion needs, so the matrix is RAGGED: rowiis meaningful only up to columnb_iand is zero-padded out tomax(b). A padded entry is notP[Q_i = j]; it is simply not computed. Read rowiasp[i, :b[i]].- Type:
np.ndarray (M,max(b))
- Wresid
The residence time
w_i(l)of the MVA recursion. The identityW[i, l] = Wresid[i, l] / V[i, l]is an independent check of thet = 1case of (4.5).- Type:
np.ndarray (M,R)
- pfqn_sens_linearizer(L, N, Z=None, tol=None, maxiter=200)[source]
Approximate moments E[Q_i], Var[Q_i], Cov[Q_i,Q_j], E[Q_i^2] and E[Q_i^3] of the per-station total queue lengths of a closed product-form queueing network, by the LINEARIZER-2 / LINEARIZER-3 algorithms of the reference (Section 5).
Motivation. The exact moment analysis of
pfqn_sens_mom()evaluates the MVA recursion on the whole population lattice, so it costsO(prod(N+1))and is unusable once the populations are large. The Linearizer replaces that lattice by a fixed point over a handful of populations, and the reference observes that the same trick applies to the derivatives: differentiate the Linearizer equations, append the differentiated equations to the originals, and iterate all of them together. This routine does that, carrying both the first and the second derivative, so it returns everything (3.2) needs, including the third moment. Carrying only the first derivative is the reference’s LINEARIZER-2; carrying the second as well is its LINEARIZER-3.The approximation. CORE (equations (5.1)-(5.2)) estimates the queue lengths at population
n - 1_lfrom those atnby:v_i(l) = m_i^(n)(l) / n(l) m_i^(n-1_l')(l) = (n - 1_l')_l * ( v_i(l) + delta_i(l',l) )
and substitutes them into the exact MVA equations. Setting the delta terms to zero gives Bard-Schweitzer; Linearizer instead estimates them from (5.3),
delta_i^(N)(l',l) = v_i^(N-1_l')(l) - v_i^(N)(l), by running CORE at each of theN - 1_lpopulations, and holds them fixed across populations (the heuristic (5.4)). Differentiating (5.1)-(5.3) gives (5.5)-(5.8), which are carried alongside.Accuracy. The reference reports, over 51 networks including 34 stress cases, relative errors below 2.1% on E[Q], 4.1% on E[Q^2] and 6.2% on E[Q^3]. The tests measure the error against the exact
pfqn_sens_mom()on models small enough for both, and assert bands of that order rather than machine precision: this routine is an approximation and is expected to disagree with the exact answer.- Parameters:
L (
(M,R) array) – Service demand matrix,L[i, r] = visits_ir / rate_ir.N (
(R,) array) – Population per class. Must be finite (closed populations only).Z (
(R,) array, optional) – Think time per class (default zeros).tol (
float, optional) – Convergence tolerance of the CORE fixed point on the mean queue lengths. Default: the test of the reference,1/(4000+16*sum(n)), which is also applied to the variances at 1e-3.maxiter (
int, optional) – Maximum CORE iterations (default 200).
- Return type:
Notes
Single-server stations plus an optional delay
Z, matchingpfqn_linearizer().The exact counterpart is
pfqn_sens_mom(); the per-class exact second moments are inpfqn_sens_mva().
- class PfqnSensLinearizer(X, Q, U, W, m, dm, d2m, Var, Cov, M2, M3, Skew, CovAsym, iter)[source]
Bases:
objectResult container for
pfqn_sens_linearizer().- X, Q, U, W
Approximate base measures.
Xis (1 x R);Q,UandWare (M x R).- Type:
np.ndarray
- m
Approximate
E[Q_i], the total queue length at stationi.- Type:
np.ndarray (M,)
- dm
dm[i, h] = x_h dm_i/dx_h, the scaled first derivative.- Type:
np.ndarray (M,M)
- d2m
d2m[i] = x_i^2 d^2m_i/dx_i^2.- Type:
np.ndarray (M,)
- Var, Cov, M2, M3, Skew
The moments of (3.2), formed exactly as in
pfqn_sens_mom()but from the approximate derivatives.Var,M2,M3andSkeware (M,);Covis (M x M).- Type:
np.ndarray
- CovAsym
Raw asymmetry of
Covbefore symmetrization. Unlike the exact routines, this is NOT expected to sit at roundoff: the Linearizer fixed point does not enforce the symmetry that the product form guarantees, so this is a useful measure of the approximation error.- Type:
- pfqn_mvald(L, N, Z, mu, stabilize=True)[source]
Exact MVA for load-dependent closed queueing networks.
This algorithm extends standard MVA to handle stations where the service rate depends on the number of jobs present.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R) - rows are stations, columns are classes.
N (numpy.ndarray) – Population vector (R,).
Z (numpy.ndarray) – Think time vector (R,).
mu (numpy.ndarray) – Load-dependent rate matrix (M x Ntot) where mu[i,k] is the service rate at station i when k jobs are present.
stabilize (bool) – Force non-negative probabilities (default: True).
- Returns:
XN: Class throughputs (1 x R). QN: Mean queue lengths (M x R). UN: Utilizations (M,), per STATION, i.e. 1-P_j(0). Matches MATLAB
pfqn_mvald, which likewise reports utilization per station and not per class.
CN: Cycle times (1 x R). lGN: Log normalizing constant evolution. isNumStable: True if numerically stable. pi: Marginal queue-length probabilities (M x Ntot+1).
- Return type:
Tuple of (XN, QN, UN, CN, lGN, isNumStable, pi)
- pfqn_mvams(lambda_arr, L, N, Z, mi=None, S=None)[source]
General-purpose MVA for mixed networks with multiserver nodes.
This function handles networks with open/closed classes and multi-server stations, routing to the appropriate specialized algorithm.
- Parameters:
lambda_arr (numpy.ndarray) – Arrival rate vector (R,). Use 0 for closed classes.
L (numpy.ndarray) – Service demand matrix (M x R).
N (numpy.ndarray) – Population vector (R,). Use np.inf for open classes.
Z (numpy.ndarray) – Think time vector (R,).
mi (numpy.ndarray | None) – Queue replication factors (M,) (default: ones).
S (numpy.ndarray | None) – Number of servers per station (M,) (default: ones).
- Returns:
XN: Class throughputs (1 x R). QN: Mean queue lengths (M x R). UN: Utilizations. Per STATION-CLASS (M x R) on every branch except
the closed multiserver one, which delegates to pfqn_mvald and so reports per STATION (M,). This shape inconsistency is inherited from MATLAB pfqn_mvams, which behaves identically; the only caller (api/solvers/mva/handler.py) discards UN and recomputes utilization analytically, as solver_mva.m does.
- CN: Residence times per STATION-CLASS (M x R), as in MATLAB
pfqn_mvams and pfqn_mva. Note this is NOT what pfqn_mva returns as its own CN in Python (that is the (1 x R) cycle time); the residence time is pfqn_mva’s RN.
lG: Log normalizing constant.
- Return type:
Tuple of (XN, QN, UN, CN, lG)
References
Original MATLAB: matlab/src/api/pfqn/pfqn_mvams.m
- pfqn_mvamx(lambda_arr, L, N, Z, mi=None)[source]
Exact MVA for mixed open/closed single-server networks.
Handles networks with both open classes (infinite population, external arrivals) and closed classes (fixed population, no external arrivals).
- Parameters:
lambda_arr (numpy.ndarray) – Arrival rate vector (R,). Use 0 for closed classes.
L (numpy.ndarray) – Service demand matrix (M x R).
N (numpy.ndarray) – Population vector (R,). Use np.inf for open classes.
Z (numpy.ndarray) – Think time vector (R,).
mi (numpy.ndarray | None) – Queue replication factors (M,) (default: ones).
- Returns:
XN: Class throughputs (1 x R). QN: Mean queue lengths (M x R). UN: Utilizations (M x R). CN: Cycle times (M x R). lGN: Log normalizing constant.
- Return type:
Tuple of (XN, QN, UN, CN, lGN)
- pfqn_xzabalow(L, N, Z)[source]
Lower ABA (asymptotic bound analysis) bound on throughput.
Returns N / (Z + sum(L)*N), the ABA lower throughput bound for single-class closed queueing networks. This is NOT the classical Zahorjan-Balanced (balanced job bounds) lower bound; that one is pfqn_xzgsblow, which is tighter.
- Parameters:
L (numpy.ndarray) – Service demand vector (M,).
Z (float) – Think time.
- Returns:
Lower bound on throughput.
- Return type:
- pfqn_xzabaup(L, N, Z)[source]
Upper asymptotic bound on throughput (Zahorjan-Balanced).
Provides a simple upper bound on system throughput for single-class closed queueing networks based on bottleneck analysis.
- Parameters:
L (numpy.ndarray) – Service demand vector (M,).
Z (float) – Think time.
- Returns:
Upper bound on throughput.
- Return type:
- pfqn_qzgblow(L, N, Z, i)[source]
Lower asymptotic bound on queue length (Zahorjan-Gittelsohn-Bryant).
- pfqn_qzgbup(L, N, Z, i)[source]
Upper asymptotic bound on queue length (Zahorjan-Gittelsohn-Bryant).
- pfqn_xzgsblow(L, N, Z)[source]
Lower asymptotic bound on throughput (Zahorjan-Gittelsohn-Schweitzer-Bryant).
Provides a tighter lower bound than pfqn_xzabalow by accounting for queue length bounds.
- Parameters:
L (numpy.ndarray) – Service demand vector (M,).
Z (float) – Think time.
- Returns:
Lower bound on throughput.
- Return type:
- pfqn_xzgsbup(L, N, Z)[source]
Upper asymptotic bound on throughput (Zahorjan-Gittelsohn-Schweitzer-Bryant).
Provides a tighter upper bound than pfqn_xzabaup by accounting for queue length bounds.
- Parameters:
L (numpy.ndarray) – Service demand vector (M,).
Z (float) – Think time.
- Returns:
Upper bound on throughput.
- Return type:
- pfqn_mwrbb(V, S, N, Z=None, sched=None, prio=None)[source]
Majumdar-Woodside robust box bounds on throughput for closed multiclass queueing networks with mixed scheduling disciplines.
Computes distribution-insensitive (NBUE) upper and lower bounds on the per-class system throughput of a closed multiclass queueing network, per S. Majumdar and C.M. Woodside, “Robust bounds and throughput guarantees for closed multiclass queueing networks”, Performance Evaluation 32 (1998) 101-136. The upper bound intersects the no-contention bound (eq. 2) with the utilization-based bound (eq. 3) and is discipline-independent. The lower bound is the multiclass throughput guarantee of Theorem 2 (eq. 15): X_c >= N_c / (Z_c + sum_k V_kc (S_kc + d_kc+)), where d_kc+ depends on the discipline at station k – FIFO (Theorem 1 / Lemma 1), processor sharing (Lemma 2), preemptive priority (Lemma 3), non-preemptive priority (Lemmas 4-5). The coupled inequalities are resolved by the interval- narrowing fixed point reproducing the BNR-Prolog robust box bounds; for a single FIFO class it reduces to the Muntz-Wong bounds. Only queueing stations are passed; Z aggregates the pure-delay stations.
- Parameters:
V (numpy.ndarray) – (K, C) mean visits of class c at queueing station k.
S (numpy.ndarray) – (K, C) mean service demand per visit of class c at station k.
N (numpy.ndarray) – (C,) population of class c.
Z (numpy.ndarray) – (C,) think time of class c (default zeros).
sched (numpy.ndarray) – (K,) discipline code per station (0=FIFO, 1=PS, 2=non-preemptive priority, 3=preemptive priority, 4=ABA full-contention discipline-independent); default all FIFO.
prio (numpy.ndarray) – (C,) class priority, lower value = higher priority; default equal.
- Returns:
(C,) lower bound on class throughput (Theorem 2). Xup: (C,) upper bound on class throughput (eqs. 2-3). Wlo: (K, C) per-visit residence time consistent with the lower bound.
- Return type:
Xlo
- pfqn_pbh(L, N, Z=0.0, level=1)[source]
Performance Bound Hierarchy (Eager-Sevcik 1983), single-class.
Returns (Xlo, Xhi, Qlo, Qhi). Level-level throughput/queue bounds; level 1 (Z=0) equals the BJB optimistic bound, and the bracket tightens to exact MVA as level -> N.
- pfqn_pbk(L, N, Z=0.0, k=1)[source]
Iterative PB(k) proportional bounds (Eager-Sevcik / CMS08). Backed by the PBH recursion at level k. Returns (Xlo, Xhi).
- pfqn_bjbk(L, N, Z=0.0, k=1)[source]
Iterative BJB(k) balanced job bounds (CMS08). BJB(1) recovers the noniterative balanced job bound. Returns (Xlo, Xhi).
- pfqn_cbh(L, N, Z=0.0, level=2)[source]
Convolutional Bound Hierarchy (Dowdy et al. 1984), single-class.
level exactly-convolved servers (1..M); the bracket tightens monotonically and equals exact at level M. Returns (Xlo, Xhi).
- pfqn_mcub(L, N, Z=None)[source]
Multiclass Composite Upper Bound (Kerola 1986). L is M x R.
Returns (Xub, Xlb): Xub the per-class composite UPPER bound (eqs 13-16), Xlb the per-class multiclass Balanced Job Bounds LOWER bound (eq 10) that seeds it. Both are 1 x R arrays.
- pfqn_ssd(L, N, Z=0.0, nservers=None)[source]
Server-Station Disaggregation bounds (Suri-Dallery 1986, Thm 5), single-class multiserver. Returns (Xlo, Xhi).
- pfqn_sib(L, N, Z=0.0, level=3)[source]
Successively Improving Bounds (Srinivasan 1985), single-class, Z=0 only.
Returns (Xlo, Xhi, Wlo, Whi). Raises ValueError for Z>0 (delay needs the Section-3.2 demand substitution, not yet implemented).
- pfqn_ldbcmp(L, N, Z=0.0, c=None, tol=1e-10)[source]
Anselmi-Cremonesi (2008) lower throughput bound for closed single-class BCMP networks with load-dependent stations. Returns (Xlo, Rhi, Qhat).
c[i]=0 marks a fixed-rate (LI) station; c[i]>0 a Heffes LD station with open queue (c[i]+1)*rho/(1-rho). Bottleneck assumed fixed-rate. NaN if N < Qhat.
- pfqn_marie(L, N, Z=None, scv=None, tol=1e-8, maxiter=1000, nservers=None)[source]
Marie’s method (single-class). L is M x 1 demands, N scalar population, Z scalar think time, scv per-station SCV (M,). Returns (X, Q, U, C, it, mu): X scalar chain throughput, Q/U/C per-station (M,), it iterations, mu the converged LD multiplier matrix (M x N).
Multiclass (L with >1 column) raises NotImplementedError.
- pfqn_le(L, N, Z=None)[source]
Logistic Expansion (LE) asymptotic approximation for normalizing constant.
Provides an asymptotic estimate of the normalizing constant for closed product-form queueing networks. Useful for large populations where exact methods become computationally expensive.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R).
N (numpy.ndarray) – Population vector (R,).
Z (numpy.ndarray | None) – Think time vector (R,). Optional.
- Returns:
Gn: Estimated normalizing constant. lGn: Logarithm of normalizing constant.
- Return type:
Tuple of (Gn, lGn)
- Reference:
G. Casale. “Accelerating performance inference over closed systems by asymptotic methods.” ACM SIGMETRICS 2017.
- pfqn_cub(L, N, Z=None, order=None, atol=1e-8)[source]
Cubature method for normalizing constant using Grundmann-Moeller rules.
Uses numerical integration over simplices to compute the normalizing constant exactly (for sufficient order) or approximately.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R).
N (numpy.ndarray) – Population vector (R,).
Z (numpy.ndarray | None) – Think time vector (R,). Optional.
order (int | None) – Degree of cubature rule (default: ceil((sum(N)-1)/2)).
atol (float) – Absolute tolerance (default: 1e-8).
- Returns:
Gn: Estimated normalizing constant. lGn: Logarithm of normalizing constant.
- Return type:
Tuple of (Gn, lGn)
- Reference:
G. Casale. “Accelerating performance inference over closed systems by asymptotic methods.” ACM SIGMETRICS 2017.
- pfqn_mci(D, N, Z=None, I=100000, variant='imci')[source]
Monte Carlo Integration (MCI) for normalizing constant estimation.
Provides a Monte Carlo estimate of the normalizing constant for closed product-form queueing networks.
- Parameters:
D (numpy.ndarray) – Service demand matrix (M x R).
N (numpy.ndarray) – Population vector (R,).
Z (numpy.ndarray | None) – Think time vector (R,). Optional, defaults to zeros.
I (int) – Number of samples (default: 100000).
variant (str) – MCI variant - ‘mci’, ‘imci’ (improved), or ‘rm’ (repairman). Default: ‘imci’.
- Returns:
G: Estimated normalizing constant. lG: Logarithm of normalizing constant. lZ: Individual random sample log values.
- Return type:
Tuple of (G, lG, lZ)
- Reference:
Implementation based on MonteQueue methodology.
- pfqn_grnmol(L, N)[source]
Normalizing constant using Grundmann-Moeller quadrature.
Computes the normalizing constant for closed product-form queueing networks using Grundmann-Moeller cubature rules on simplices.
This is an exact method that uses polynomial quadrature to compute the normalizing constant integral representation.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R).
N (numpy.ndarray) – Population vector (R,).
- Returns:
G: Normalizing constant. lG: Logarithm of normalizing constant.
- Return type:
Tuple of (G, lG)
- Reference:
Grundmann, A. and Moller, H.M. “Invariant Integration Formulas for the N-Simplex by Combinatorial Methods”, SIAM J Numer. Anal. 15 (1978), pp. 282-290.
- pfqn_le_fpi(L, N)[source]
Fixed-point iteration to find mode location (no think time).
Public wrapper for the internal _pfqn_le_fpi function.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R).
N (numpy.ndarray) – Population vector (R,).
- Returns:
Mode location vector u (M,).
- Return type:
- pfqn_le_fpiZ(L, N, Z)[source]
Fixed-point iteration to find mode location (with think time).
Public wrapper for the internal _pfqn_le_fpiZ function.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R).
N (numpy.ndarray) – Population vector (R,).
Z (numpy.ndarray) – Think time vector (R,).
- Returns:
u: Mode location vector (M,). v: Scale factor.
- Return type:
Tuple of (u, v)
- pfqn_le_hessian(L, N, u)[source]
Compute Hessian matrix (no think time case).
Public wrapper for the internal _pfqn_le_hessian function.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R).
N (numpy.ndarray) – Population vector (R,).
u (numpy.ndarray) – Mode location vector (M,).
- Returns:
Hessian matrix (M-1 x M-1).
- Return type:
- pfqn_le_hessianZ(L, N, Z, u, v)[source]
Compute Hessian matrix (with think time case).
Public wrapper for the internal _pfqn_le_hessianZ function.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R).
N (numpy.ndarray) – Population vector (R,).
Z (numpy.ndarray) – Think time vector (R,).
u (numpy.ndarray) – Mode location vector (M,).
v (float) – Scale factor.
- Returns:
Hessian matrix (M x M).
- Return type:
- pfqn_ncld(L, N, Z, mu, options=None)[source]
Main method to compute normalizing constant of a load-dependent model.
Provides the main entry point for computing normalizing constants in load-dependent queueing networks with automatic method selection and preprocessing.
- Parameters:
L (numpy.ndarray) – Service demands at all stations (M x R)
N (numpy.ndarray) – Number of jobs for each class (1 x R)
Z (numpy.ndarray) – Think times for each class (1 x R)
mu (numpy.ndarray) – Load-dependent scalings (M x Ntot)
options (Dict[str, Any] | None) – Solver options with keys: - method: ‘default’, ‘exact’, ‘rd’, ‘comomld’, etc. - tol: Numerical tolerance
- Returns:
PfqnNcResult with G (normalizing constant), lG (log), and method used
- Return type:
- pfqn_ld_is(L, N, Z=None, mu=None, options=None)[source]
Importance-sampling (IS) estimate of the normalizing constant of a closed LOAD-DEPENDENT product-form queueing network. Load-dependent counterpart of pfqn_pas_is / pfqn_oi_is: the same sample-an-ordering estimator, with the order-independent rank rate replaced by the load-dependent capacity.
Identity. Every product-form station’s balance function is the sum, over the orderings q of a given per-class count vector n, of an ordered product of a per-position factor:
F_i(n) = |n|!/prod_r(n_r!) * prod_r L(i,r)^{n_r} / prod_{k=1}^{|n|} mu_i(k) = sum_{q: |q|=n} prod_{p=1}^{|n|} L(i,q_p) / mu_i(p)since the multiset has |n|!/prod_r(n_r!) orderings, each contributing the same ordered product. The delay (infinite-server) node is the special case mu_Z(k)=k, giving F_Z(n)=prod_r Z_r^{n_r}/n_r!; a single-server queue is mu_i(k)=1; a c-server queue is mu_i(k)=min(k,c).
Consequently, with ell = sum(N) and a “cut vector” splitting an ordering c of all ell jobs into S contiguous segments (one per station):
G(N) = sum_{c} sum_{cuts} prod_{m=1}^{S} w_m(seg_m), w_m(q) = prod_{p=1}^{|q|} L(m,q_p) / mu_m(p)
because summing over the orderings of each segment independently reproduces prod_m F_m(n_m), and each count split is realized exactly once.
Estimator. An ordering c is drawn by placing, at each step, a uniformly random present class; p(c) is the product of the reciprocal branching factors. For the sampled c the inner sum over ALL cut vectors is computed exactly by the dynamic program A_0(0)=1, A_m(k) = sum_{j<=k} A_{m-1}(j) * w_m(c_{j+1..k}), so S(c)=A_S(ell) in O(S*ell^2) time (no cut enumeration). Then G = E_{C~p}[S(C)/p(C)] is unbiased, estimated by the sample mean.
- Parameters:
L (
(M,R) array) – Per-class service demands at the M queueing stations.N (
(R,) array) – Closed population vector, finite.Z (
(R,) array, optional) – Aggregated think time (delay) demand; None or zeros if none.mu (
(M,ell) arrayorsequenceofcallables, optional) – Load-dependent capacities;mu[i][k-1]is the capacity of station i holding k jobs. None for the load-independent case mu(i,k)=1 (seepfqn_is()).options (
dictoroptions object, optional) – Fieldssamples(default 1e4) andseed(optional).
- Returns:
PfqnNcResult with ``G`the IS estimate` ofthe normalizing constant andlG = log(G).
- Return type:
Examples
>>> L = np.array([[0.5, 0.3], [0.2, 0.4]]); N = np.array([3, 2]); Z = np.array([1.0, 1.0]) >>> mu = np.array([[1, 2, 2, 2, 2], [1, 1, 1, 1, 1]], dtype=float) >>> res = pfqn_ld_is(L, N, Z, mu, {'samples': 100000, 'seed': 7})
- pfqn_ncldmx(lam, D, N, Z=None, mu=None, S=None, options=None)[source]
Normalizing constant for mixed open/closed networks with limited load dependence.
- Parameters:
lam (numpy.ndarray) – Arrival rate vector (R,) - 0 on closed classes
D (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,) - inf for open classes
Z (numpy.ndarray | None) – Think time vector (R,), optional
mu (numpy.ndarray | None) – Load-dependent rate matrix (M x >= sum(N_closed)), optional
S (numpy.ndarray | None) – Number of servers per station (M,), kept for signature parity
options (Dict[str, Any] | None) – Solver options forwarded to pfqn_ncld
- Returns:
PfqnNcldmxResult with the closed-conditional constant (G, lG), the open-class normalizing prefactor lGopen and the method used for the closed-conditional solve.
- Return type:
- class PfqnNcldmxResult(G, lG, lGopen, method='default')[source]
Bases:
objectResult of a mixed limited load-dependent normalizing constant computation.
- pfqn_gld(L, N, mu, options=None)[source]
Compute normalizing constant of a load-dependent closed queueing network.
Uses the generalized convolution algorithm for computing normalizing constants in load-dependent closed queueing networks.
- Parameters:
L (numpy.ndarray) – Service demands at all stations (M x R)
N (numpy.ndarray) – Number of jobs for each class (1 x R)
mu (numpy.ndarray) – Load-dependent scalings (M x Ntot)
- Returns:
PfqnNcResult with G (normalizing constant) and lG (log)
- Return type:
- pfqn_gldsingle(L, N, mu, options=None)[source]
Compute normalizing constant for single-class load-dependent model.
Auxiliary function used by pfqn_gld to compute the normalizing constant in a single-class load-dependent model using dynamic programming.
- Parameters:
L (numpy.ndarray) – Service demands at all stations (M x 1)
N (numpy.ndarray) – Number of jobs (scalar or 1x1 array)
mu (numpy.ndarray) – Load-dependent scaling factors (M x Ntot)
options (Dict[str, Any] | None) – Solver options (unused, for API compatibility)
- Returns:
PfqnNcResult with G (normalizing constant) and lG (log)
- Raises:
RuntimeError – If multiclass model is detected
- Return type:
- pfqn_mushift(mu, k)[source]
Shift a load-dependent scaling vector by one position.
Used in recursive normalizing constant computations.
- Parameters:
mu (numpy.ndarray) – Load-dependent scalings matrix (M x N)
k (int) – Row index to shift
- Returns:
Shifted mu matrix (M x N-1)
- Return type:
- pfqn_comomrm_ld(L, N, Z, mu, options=None)[source]
Run the COMOM normalizing constant method on a load-dependent repairman model.
Implements the Class-Oriented Method of Moments (COMOM) for computing normalizing constants in load-dependent repairman queueing models.
- Parameters:
L (numpy.ndarray) – Service demands at all stations (M x R)
N (numpy.ndarray) – Number of jobs for each class (1 x R)
Z (numpy.ndarray) – Think times for each class (1 x R)
mu (numpy.ndarray) – Load-dependent scalings (M x Ntot)
- Returns:
PfqnComomrmLdResult with G, lG, and marginal probabilities
- Return type:
- pfqn_fnc(alpha, c=None)[source]
Compute scaling factor of a load-dependent functional server.
Used to calculate the mean queue length in load-dependent systems by computing functional scaling factors from load-dependent service rate parameters.
- Parameters:
alpha (numpy.ndarray) – Load-dependent scalings (M x N)
c (numpy.ndarray | None) – Scaling constants (1 x M), optional. If None, auto-selected.
- Returns:
PfqnFncResult with mu (functional server scalings) and c (scaling constants)
- Return type:
- pfqn_oi_nc(Z, N, mu=None, options=None)[source]
Normalizing constant of a closed OI + single-delay product-form network.
The OI stations are analyzed by the balanced-fairness recursion of Bonald and Proutiere (2003) combined with the multichain convolution over stations. The exact G(N) is obtained by recursive peeling: peel the last OI station (empty), then per class r with N_r>0 place one class-r job at that station and recurse on N - e_r with the station rate function shifted by e_r.
- Parameters:
Z (
(R,) think-time demand vectorofthe aggregated delay node.)N (
(R,) closed population vector,finite.)mu (
listofcallables,one per OI station. Each ``mu[m](n)`returns the`) – total service rate of station m given the per-class occupancy (count) vector n. May be empty/None to model a pure delay network.options (
accepted for signature parity; unused.)
- Returns:
(G, lG)
- Return type:
normalizing constantandits natural log.
- pfqn_oi_fnc(Phi, N=None, f=None, options=None)[source]
OI generalization of the load-dependent functional server.
Builds an auxiliary OI station whose balance function Psi satisfies the convolution identity
(Psi * Phi)(n) = (1 + f(n)) Phi(n), then inverts Psi to the FNC ratemu_f(n) = (sum_{r: n_r>0} Psi(n-e_r)) / Psi(n).- Parameters:
Phi (
balance functionofthe existing OI station over the lattice,an) – R-dimensional array of shape (N_1+1, …, N_R+1), or a flat column-major vector.N (
(R,) closed population vector. Optional when Phi is a full) – R-dimensional array (then N = shape(Phi) - 1).f (
target queue-dependent function f(n),f(0)=0 (default f = sum(n)).)options (
accepted for signature parity; unused.)
- Returns:
(muf, Psi, mu) – balance array (lattice shape), and tabulated FNC rate array.
- Return type:
callable rate handle (Inf outside the lattice),FNC
- pfqn_oi_insvc(oirate, N, options=None)[source]
Conditional mean number of in-service jobs per class at an OI station.
This is the quantity underlying the LINE utilization convention at order-independent stations,
U_r = E[sir_r] / cwithcthe number of servers andsir_rthe number of class-r jobs receiving a strictly positive service rate.In an OI station the state is the ordered list
c = (c_1,...,c_n)of job classes (position 1 = head) and the job in position p is served at the rank rate incrementDelta_p(c) = mu(c_1..c_p) - mu(c_1..c_{p-1}), so the total rate telescopes tomu(c). Position p is in service whenDelta_p(c) > 0, andsir_r(c) = #{p : c_p = r, Delta_p(c) > 0}. Note thatsir_rcounts JOBS, not servers: a single job served concurrently by several compatible servers counts once. This matches the definition used by the exact CTMC solver (State.to_marginal, PAS branch) and by LDES.Because
muis permutation-invariant, the unnormalized weight of an ordering c of the multiset n factorizes over its prefixes asw(c) = prod_p 1/mu(n(c_1..c_p)), andPhi(n) = sum_c w(c)obeys the balanced-fairness recursion (condition on the tail element):Phi(0) = 1, Phi(n) = (1/mu(n)) sum_{r: n_r>0} Phi(n - e_r)
Conditioning the same way and using
sir_r(c) = sir_r(c_1..c_{|n|-1}) + [c_{|n|} = r] * 1{mu(n) > mu(n - e_r)}gives the companion recursion forXi_r(n) = sum_c w(c) sir_r(c):Xi_r(0) = 0 Xi_r(n) = (1/mu(n)) [ sum_{s: n_s>0} Xi_r(n - e_s) + 1{n_r > 0} 1{mu(n) > mu(n - e_r)} Phi(n - e_r) ]
Given n every ordering carries the same class-weight factor, so the conditional law of the ordering is
w(c)/Phi(n)andE[sir_r | n] = Xi_r(n)/Phi(n) =: g_r(n), a function of the count vector alone. The station mean then follows from the count marginal pM asE[sir_r] = sum_n pM(n) g_r(n), or in normalizing-constant form from the functional-server identity ofpfqn_oi_fnc()applied tof(n) = g_r(n)(noteg_r(0) = 0, as required).- Parameters:
oirate (
function ``mu(n)`returning the OI total service rate for the`) – per-class count vector n (length R).mu(0)is taken as 0.N (
(R,) closed population vector,finite.)options (
accepted for signature parity,currently unused.)
- Returns:
g (
(prod(N+1),R) table,column-major over the lattice 0 <= n <= N,with) –g[1 + sum(n * stride), r] = E[sir_r | n].Xi (
(prod(N+1),R) table with the sir-weighted balance ``Xi_r(n)`.`)Phi (
(prod(N+1),) table with the OI balance function ``Phi(n)`.`)
- Return type:
See also
- pfqn_pas_is(N, mu, H=None, options=None)[source]
Importance-sampling estimate of G_C and mean queue lengths of a closed two-station P&S tandem with swap graph H.
G_C = sum_{c in D} sum_{k=0}^{ell} Phi_1(c[:k]) Phi_2(reverse(c[k:])), where D is the set of orderings non-decreasing w.r.t. H and Phi_m(q) = prod_p 1/mu_m(supp(q[:p])). Orderings are drawn from D by placing, at each step, a uniformly random placement-order-minimal present class (auto-normalized IS, notebook generator IS_3); E[xi] = G_C[xi]/G_C[1] reuses the same samples. Taking xi = class-r count in the prefix gives the station-1 mean queue length of class r.
- Parameters:
N (
(R,) closed population vector (macrostate),finite.)mu (
listofexactly two callables. mu[m](n) is the total OI rank rate of) – station m given the per-class occupancy (count) vector n (depends only on supp(n)); this is the count-based svcRateFun of an OI/PAS node.H (
(R,R) swap-graph adjacency (H[b,a] != 0 forbids a before b). Empty ->) – pure OI (all orderings feasible).options (
dictoroptions object; fields ``samples`(default 1e4),`) –seed(optional),verbose(default False).
- Returns:
(G, lG, Q) – station-1 mean queue lengths and Q[1] = N - Q[0].
- Return type:
G is the IS estimateofG_C,lG = log(G),Q is (2,R) with the
- pas_placement(H)[source]
Placement-order logic of a P&S / OI network with swap graph H.
An ordering c is feasible iff it is non-decreasing w.r.t. H, i.e. class a never appears before class b whenever H[b, a] != 0 (Comte and Dorsman, 2021); equivalently H[b, a] != 0 means b must precede a. The transitive closure P[i, j] = 1 iff i must precede j makes the full order explicit.
- Parameters:
H (
(R,R) swap-graph adjacency. Empty/all-zero -> no constraint.)- Returns:
(P, placeable) – placeable(x) returns the array of class indices drawable next given the remaining per-class count vector x (present classes with no remaining predecessor still to be placed).
- Return type:
P is the (R,R) precedence closure (or None if H is empty);
- pas_swap2order(swap, listRate, N0=None)[source]
Global placement-order DAG H of a closed two-station P&S tandem 1->2->1.
With a non-empty swap graph the ordered chain is reducible; the recurrent communicating class is the set of splits of the orderings that are the linear extensions of a single placement partial order (Comte and Dorsman, 2021). pfqn_pas_is samples those orderings from H, so it needs this GLOBAL order. The order is class-level (multiplicity-independent): enumerate the reachable class from the all-in-queue-1 single-job-per-class state; each reachable state (l1; l2) exposes the full ordering c = l1 + reverse(l2); then H[i, j] = 1 iff i precedes j in every such c (forced precedence).
- Parameters:
swap (
(R,R) swap graph, orlist [G1,G2]ofthe two per-queue graphs) – (G[a, b] != 0 means class a chases class b). Empty/all-zero -> H = 0.listRate (
listoftwo callables; listRate[m](c) is the total service rate) – of queue m on the ordered prefix c (0-based). Prunes zero-rate (non- head) completions.N0 (
(R,) minimal probing population; defaultstoones(R).)
- Returns:
H
- Return type:
(R,R) global placement-order DAG; H[i,j] = 1 iff i must precede j.
- pfqn_mvaoi(Z, N, mu, Dli=None, options=None)[source]
Mean-value analysis of a closed product-form OI network.
Mean-value counterpart of
pfqn_oi_nc()and the marginal formpfqn_mvaoi_marg(): for a closed product-form network of an aggregated infinite-server (delay) node, any number of load-independent (LI) single-server product-form queues, and any number of order-independent (OI) stations, it returns the same exact per-class throughput and queue-lengths WITHOUT computing any normalizing constant or joint marginal, using only mean quantities. It is the composition-dependent generalization of the Conditional MVA (CMVA) of Casale, “A Note on Stable Flow-Equivalent Aggregation in Closed Networks” (QUESTA 2009), extended to MULTIPLE OI stations by carrying one rate-shift vectors_iper OI station i (rowiof the shift matrixS).Throughout,
randsindex job classes;iindexes OI stations;jindexes LI queues. State(S, Nn)is processed by increasingsum(Nn); each OI station keeps its ownD^i,rho^iandQ^irecursions driven by the common throughputX^{(S)}(Nn), and the population conservation aggregates every station’s contribution:Nn_r = X_r Z_r + sum_j Q^{(j)}_r + sum_i Q^{(i)}_r,
with the LI queue term
Q^{(j)}_r = X_r D_{j,r}(1 + sum_s Q^{(j)}_s(Nn - e_r)).- Parameters:
Z (
(R,) think-time demand vectorofthe aggregated delay node.)N (
(R,) closed population vector,finite.)mu (
callableorlistofcallables ``mu_i(n)`returning the OI total service`) – rate of station i for the per-class occupancy (count) vector n. A bare callable is accepted as the single-station shorthand.Dli (
(J,R) per-class demand matrixofthe LI single-server queues; None or) – empty when J = 0.options (
accepted for signature parity; unused.)
- Returns:
(X, Qoi, Qli, Qdelay, Soi) – (K, R), LI queue-lengths (J, R), delay queue-length (R,) =
X * Z, and the per-class mean number of IN-SERVICE jobs at each OI station (K, R).Soi[i, r] = E[sir_r]counts the class-r jobs receiving a strictly positive rank rate (seepfqn_oi_insvc()); the utilization of OI station i isSoi[i, r] / c_i. Unlike X/Qoi/Qli, which are pure mean-value quantities, Soi is a distributional statistic and is obtained from the OI count marginal assembled from the zero-shift throughputsX^{(0)}(k)already cached by the mean-value recursion above (no normalizing constant is formed).- Return type:
per-class throughput (R,),OI queue-lengths
- pfqn_mvaoi_marg(D, N, isDelay, mu)[source]
Exact marginal load-dependent MVA for OI networks.
Marginal-distribution counterpart of
pfqn_mvaoi(). Carries, for each OI station, its joint count-vector marginalpM_i(n | k)and closes the per-class throughput by population conservation. Handles delay + LI product-form queues + any number of OI stations.- Parameters:
D (
(M,R) per-class demand at every station (OI rows ignored).)N (
(R,) closed population vector,finite.)isDelay (
(M,) True for infinite-server (delay) stations.)mu (
length-M list; ``mu[i]`is the OI rate callable` ofthe count vector n,or) – None for non-OI stations.
- Returns:
(XN, QN)
- Return type:
per-class throughput (R,)andper-station queue-lengths (M,R).
- class PfqnNcResult(G, lG, method='default')[source]
Bases:
objectResult of normalizing constant computation.
- class PfqnComomrmLdResult(G, lG, prob)[source]
Bases:
objectResult of COMOM load-dependent computation.
- prob: numpy.ndarray
- class PfqnFncResult(mu, c)[source]
Bases:
objectResult of functional server scaling computation.
- mu: numpy.ndarray
- pfqn_unique(L, mu=None, gamma=None, tol=1e-14)[source]
Consolidate replicated stations into unique stations with multiplicity.
Identifies stations with identical demand rows L[i,:] and (if present) identical load-dependent rates mu[i,:] or class-dependent rates gamma[i,:]. Returns reduced matrices with only unique stations plus a multiplicity vector.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R)
mu (numpy.ndarray | None) – Load-dependent rate matrix (M x Ntot), optional - pass None if not used
gamma (numpy.ndarray | None) – Class-dependent service rate matrix (M x R), optional - pass None if not used
tol (float) – Tolerance for floating point comparison (default 1e-14)
- Returns:
PfqnUniqueResult containing reduced matrices and mapping information
- Return type:
- pfqn_expand(QN, UN, CN, mapping)[source]
Expand per-station metrics from reduced model to original dimensions.
Expands performance metrics computed on a reduced model (with unique stations) back to the original model dimensions by replicating values according to mapping.
- Parameters:
QN (numpy.ndarray) – Queue lengths from reduced model (M’ x R)
UN (numpy.ndarray) – Utilizations from reduced model (M’ x R)
CN (numpy.ndarray) – Cycle times from reduced model (M’ x R)
mapping (numpy.ndarray) – Mapping vector from pfqn_unique (length M), mapping[i] = unique station index
- Returns:
Tuple of (QN_full, UN_full, CN_full) in original dimensions (M x R)
- Return type:
- pfqn_combine_mi(mi, mapping, M_unique)[source]
Combine user-provided multiplicity vector with detected replica multiplicity.
For each unique station j, sums the mi values of all original stations mapping to it.
- Parameters:
mi (numpy.ndarray) – User-provided multiplicity vector (1 x M_original or M_original,)
mapping (numpy.ndarray) – Mapping vector from pfqn_unique (length M_original)
M_unique (int) – Number of unique stations
- Returns:
Combined multiplicity vector (1 x M_unique)
- Return type:
- class PfqnUniqueResult(L_unique, mu_unique, gamma_unique, mi, mapping)[source]
Bases:
NamedTupleResult class for pfqn_unique containing all output matrices and mapping information.
- L_unique
Reduced demand matrix (M’ x R) with M’ <= M unique stations
- Type:
- mu_unique
Reduced load-dependent rates (M’ x Ntot), None if mu was empty
- Type:
numpy.ndarray | None
- gamma_unique
Reduced class-dependent rates (M’ x R), None if gamma was empty
- Type:
numpy.ndarray | None
- mi
Multiplicity vector (1 x M’), mi[j] = count of stations mapping to unique station j
- Type:
- mapping
Mapping vector (1 x M), mapping[i] = unique station index for original station i
- Type:
Create new instance of PfqnUniqueResult(L_unique, mu_unique, gamma_unique, mi, mapping)
- L_unique: numpy.ndarray
Alias for field number 0
- gamma_unique: numpy.ndarray | None
Alias for field number 2
- mapping: numpy.ndarray
Alias for field number 4
- mi: numpy.ndarray
Alias for field number 3
- mu_unique: numpy.ndarray | None
Alias for field number 1
- pfqn_lldfun(n, lldscaling=None, nservers=None)[source]
AMVA-QD load and queue-dependent scaling function.
Computes the scaling factor for load-dependent queueing stations, accounting for multi-server stations and general load-dependent service rate scaling.
- Parameters:
n (numpy.ndarray) – Queue population vector (M,)
lldscaling (numpy.ndarray | None) – Load-dependent scaling matrix (M x Nmax), optional
nservers (numpy.ndarray | None) – Number of servers per station (M,), optional
- Returns:
Scaling factor vector (M,)
- Return type:
References
Original MATLAB: matlab/src/api/pfqn/pfqn_lldfun.m
- pfqn_mu_ms(N, m, c)[source]
Compute load-dependent rates for m identical c-server FCFS stations.
Calculates the effective service rate as a function of the number of jobs in the system for a network of m identical stations, each with c parallel servers.
- Parameters:
- Returns:
Load-dependent service rate vector (1 x N)
- Return type:
References
Original MATLAB: matlab/src/api/pfqn/pfqn_mu_ms.m
- pfqn_nc_sanitize(lam, L, N, Z, atol=1e-8)[source]
Sanitize and preprocess network parameters for NC solvers.
Removes empty/ill-defined classes, rescales demands for numerical stability, and reorders classes by think time.
- Parameters:
lam (numpy.ndarray) – Arrival rate vector
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector
Z (numpy.ndarray) – Think time vector
atol (float) – Absolute tolerance for numerical comparisons
- Returns:
lambda: Sanitized arrival rates
L: Sanitized service demands (rescaled)
N: Sanitized populations
Z: Sanitized think times (rescaled)
lGremaind: Log normalization factor from removed classes
- Return type:
Tuple of (lambda, L, N, Z, lGremaind) where
References
Original MATLAB: matlab/src/api/pfqn/pfqn_nc_sanitize.m
- pfqn_cdfun(nvec, cdscaling=None, class_idx=0)[source]
AMVA-QD class-dependence function for queue-dependent scaling.
Returns, for every station i, the reciprocal of the class-dependent scaling
beta_{i,r}(n_i1, …, n_iR)
evaluated at the per-class population vector nvec[i, :], for class r = class_idx.
cdscaling[i] is a callable of the per-class population vector at station i. It may return either
a scalar, i.e. a chain-independent scaling beta_i(n) shared by every class (the common case, and the historical contract), or
an array of length R, i.e. the per-class scalings [beta_{i,1}(n), …, beta_{i,R}(n)], of which element class_idx is taken.
The per-class form expresses Sauer’s chain-dependent service rates mu_{r,i}(n) (Sauer 1983, “Computational Algorithms for State-Dependent Queueing Networks”, eq. (40)), so a single class-dependence mechanism covers both the chain-independent and the chain-specific cases.
An empty (None) entry means station i declares no class dependence and is left at the neutral scaling 1.
- Parameters:
nvec (numpy.ndarray) – Population state matrix (M x R) or vector (M,)
cdscaling (List | None) – List of class-dependence callables, one per station
class_idx (int) – 0-based class index selecting beta_{i,r} (default: 0)
- Returns:
Scaling factor vector (M,)
- Return type:
References
Original MATLAB: matlab/src/api/pfqn/pfqn_cdfun.m
- factln_vec(arr)[source]
Compute log(n!) element-wise for an array.
- Parameters:
arr (numpy.ndarray) – Array of non-negative numbers
- Returns:
Array of log(n!) values
- Return type:
- softmin(a, b, alpha=20.0)[source]
Compute a smooth approximation to min(a, b) using weighted average.
Matches MATLAB formula: (x*exp(-alpha*x) + y*exp(-alpha*y)) / (exp(-alpha*x) + exp(-alpha*y))
- oner(n, s)[source]
Return a copy of n with position s reduced by 1.
- Parameters:
n (numpy.ndarray) – Population vector
s (int) – Index to decrement (0-based)
- Returns:
Copy of n with n[s] -= 1
- Return type:
- multichoose(r, n)[source]
Generate all combinations with repetition.
Returns all ways to choose n items from r categories with repetition, where the result is a matrix with each row being a combination.
- Parameters:
- Returns:
Matrix (C x r) where C = C(n+r-1, r-1) is the number of combinations
- Return type:
- matchrow(matrix, row)[source]
Find the index of a row in a matrix.
- Parameters:
matrix (numpy.ndarray) – 2D array to search in
row (numpy.ndarray) – 1D array to find
- Returns:
1-based index of the matching row, or 0 if not found
- Return type:
- pfqn_comom(L, N, Z=None, atol=1e-8)[source]
CoMoM algorithm for computing the normalizing constant.
Implements the Composite Method of Moments algorithm for computing normalizing constants in closed product-form queueing networks.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,), default zeros
atol (float) – Absolute tolerance
- Returns:
Logarithm of the normalizing constant
- Return type:
lG
References
Original MATLAB: matlab/src/api/pfqn/pfqn_comom.m
- pfqn_comomrm(L, N, Z, m=1, atol=1e-8)[source]
CoMoM for finite repairman model.
Computes the normalizing constant for a closed network with a single queueing station and delay stations (repairman model).
- Parameters:
L (numpy.ndarray) – Service demand matrix (1 x R) - single station
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,)
m (int) – Replication factor (default: 1)
atol (float) – Absolute tolerance
- Returns:
ComomResult with lG (log normalizing constant) and lGbasis
- Return type:
References
Original MATLAB: matlab/src/api/pfqn/pfqn_comomrm.m
- pfqn_comomrm_orig(L, N, Z, m=1, atol=1e-8)[source]
Original CoMoM implementation for repairman model.
This is the original implementation of CoMoM without optimizations. Kept for reference and validation.
- Parameters:
L (numpy.ndarray) – Service demand matrix (1 x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,)
m (int) – Replication factor (default: 1)
atol (float) – Absolute tolerance
- Returns:
ComomResult with lG and lGbasis
- Return type:
References
Original MATLAB: matlab/src/api/pfqn/pfqn_comomrm_orig.m
- pfqn_comomrm_ms(L, N, Z, m, c, atol=1e-8)[source]
CoMoM for multi-server repairman model.
Computes the normalizing constant for a repairman model where the queueing station has multiple servers.
- Parameters:
L (numpy.ndarray) – Service demand matrix (1 x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,)
m (int) – Number of identical stations
c (int) – Number of servers per station
atol (float) – Absolute tolerance
- Returns:
ComomResult with lG and lGbasis
- Return type:
References
Original MATLAB: matlab/src/api/pfqn/pfqn_comomrm_ms.m
- pfqn_procomom(L, N, Z=None, atol=1e-14)[source]
ProCoMoM algorithm for computing marginal queue-length probabilities.
Computes the marginal queue-length probability distribution at each station using the Probabilistic Class-Oriented Method of Moments. Uses matrix recursion with SVD/QR decomposition for numerical stability, with automatic perturbation on rank deficiency.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R).
N (numpy.ndarray) – Population vector (R,).
Z (numpy.ndarray) – Think time vector (R,), default zeros.
atol (float) – Absolute numerical tolerance (default 1e-14).
- Returns:
- Marginal probability matrix (M x sumN+1).
Pr[k, j] = P(n_k = j) for station k, queue length j.
Q: Mean queue length vector (M,).
- Return type:
Pr
References
Original MATLAB: matlab/src/api/pfqn/pfqn_procomom.m
- pfqn_procomom2(L, N, Z=None, atol=1e-8)[source]
Projected CoMoM method for normalizing constant.
Uses a projection-based approach to compute the normalizing constant, which can be more efficient for certain model structures.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,), default zeros
atol (float) – Absolute tolerance
- Returns:
Logarithm of the normalizing constant
- Return type:
lG
References
Original MATLAB: matlab/src/api/pfqn/pfqn_procomom2.m
- class ComomResult(lG, lGbasis=None)[source]
Bases:
NamedTupleResult of CoMoM normalizing constant computation.
Create new instance of ComomResult(lG, lGbasis)
- lGbasis: numpy.ndarray | None
Alias for field number 1
- pfqn_mmint2(L, N, Z, m=1)[source]
McKenna-Mitra integral form using scipy.integrate.
Computes the normalizing constant using numerical integration of the McKenna-Mitra integral representation.
- Parameters:
L (numpy.ndarray) – Service demand vector (R,)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,)
m (int) – Replication factor (default: 1)
- Returns:
G: Normalizing constant
lG: Logarithm of normalizing constant
- Return type:
Tuple of (G, lG)
References
Original MATLAB: matlab/src/api/pfqn/pfqn_mmint2.m
- pfqn_mmint2_gausslegendre(L, N, Z, m=1)[source]
McKenna-Mitra integral with Gauss-Legendre quadrature.
Uses Gauss-Legendre quadrature for improved accuracy in computing the McKenna-Mitra integral.
- Parameters:
L (numpy.ndarray) – Service demand vector (R,)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,)
m (int) – Replication factor (default: 1)
- Returns:
G: Normalizing constant
lG: Logarithm of normalizing constant
- Return type:
Tuple of (G, lG)
References
Original MATLAB: matlab/src/api/pfqn/pfqn_mmint2_gausslegendre.m
- pfqn_mmint2_gausslaguerre(L, N, Z, m=1)[source]
McKenna-Mitra integral with Gauss-Laguerre quadrature.
Uses Gauss-Laguerre quadrature which is naturally suited for integrals with exponential decay.
- Parameters:
L (numpy.ndarray) – Service demand vector (R,)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,)
m (int) – Replication factor (default: 1)
- Returns:
G: Normalizing constant
lG: Logarithm of normalizing constant
- Return type:
Tuple of (G, lG)
References
Original MATLAB: matlab/src/api/pfqn/pfqn_mmint2_gausslaguerre.m
- pfqn_mmsample2(L, N, Z, m=1, n_samples=10000)[source]
Monte Carlo sampling approximation for normalizing constant.
Uses Monte Carlo sampling to approximate the McKenna-Mitra integral. Useful for very large populations where quadrature becomes expensive.
- Parameters:
L (numpy.ndarray) – Service demand vector (R,)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,)
m (int) – Replication factor (default: 1)
n_samples (int) – Number of Monte Carlo samples (default: 10000)
- Returns:
G: Normalizing constant (approximate)
lG: Logarithm of normalizing constant
- Return type:
Tuple of (G, lG)
References
Original MATLAB: matlab/src/api/pfqn/pfqn_mmsample2.m
- logsumexp(x)[source]
Compute log(sum(exp(x))) in a numerically stable way.
- Parameters:
x (numpy.ndarray) – Array of values
- Returns:
log(sum(exp(x)))
- Return type:
- pfqn_schmidt(D, N, S, sched, v=None)[source]
Schmidt’s exact MVA for networks with general scheduling disciplines.
Implements Schmidt’s exact Mean Value Analysis algorithm for product-form queueing networks with PS, FCFS, or INF scheduling disciplines, including support for multi-server stations.
- Parameters:
D (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
S (numpy.ndarray) – Number of servers per station (M,) or (M x R)
sched (numpy.ndarray) – Scheduling discipline per station (M,) - SchedStrategy values
v (numpy.ndarray | None) – Visit ratio matrix (M x R), optional (default: ones)
- Returns:
XN: System throughput (M x R) - same per station for closed networks QN: Mean queue lengths (M, R) UN: Utilization (M, R), per station-class, D*X/nservers CN: Cycle times / response times (M, R)
- Return type:
Tuple of (XN, QN, UN, CN)
References
Original MATLAB: matlab/src/api/pfqn/pfqn_schmidt.m
- pfqn_schmidt_ext(D, N, S, sched, v=None)[source]
Extended Schmidt MVA algorithm with queue-aware alpha corrections.
A queue-aware version of the Schmidt algorithm that precomputes alpha values for improved accuracy in networks with class-dependent FCFS scheduling.
- Reference:
R. Schmidt, “An approximate MVA algorithm for exponential, class-dependent multiple server stations,” Performance Evaluation, vol. 29, no. 4, pp. 245-254, 1997.
- Parameters:
D (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
S (numpy.ndarray) – Number of servers per station (M,) or (M x R)
sched (numpy.ndarray) – Scheduling discipline per station (M,) - SchedStrategy values
v (numpy.ndarray | None) – Visit ratio matrix (M x R), optional (default: ones)
- Returns:
XN: System throughput (M x R) QN: Mean queue lengths (M, R) UN: Utilization (M, R) CN: Cycle times / response times (M, R)
- Return type:
Tuple of (XN, QN, UN, CN)
- class SchmidtResult(XN, QN, UN, CN)[source]
Bases:
objectResult from Schmidt’s exact MVA.
- XN: numpy.ndarray
- QN: numpy.ndarray
- UN: numpy.ndarray
- CN: numpy.ndarray
- pprod(N, Nmax=None)[source]
Generate population vectors for MVA recursion.
When called with one argument, initializes to zero vector. When called with two arguments, increments to next population vector. Returns -1 when iteration is complete.
- Parameters:
N (numpy.ndarray) – Current population vector or max population
Nmax (numpy.ndarray | None) – Maximum population per class (if incrementing)
- Returns:
Next population vector, or array of -1 if done
- Return type:
- hashpop(nvec, Nc, C, prods)[source]
Hash population vector to linear index.
- Parameters:
nvec (numpy.ndarray) – Population vector
Nc (numpy.ndarray) – Maximum population per class
C (int) – Number of classes
prods (numpy.ndarray) – Precomputed products for hashing
- Returns:
Linear index (1-based for MATLAB compatibility)
- Return type:
- pfqn_dac(L, N, Z=None, mu=None)[source]
DAC (Distribution Analysis by Chain) method for joint queue-length distributions.
Computes the joint queue-length distribution of a closed product-form network by a chain-by-chain recursion over a related network in which every chain holds a single customer, a transformation that leaves the aggregate queue-length distribution unchanged. Given the distribution of a network with k-1 such chains, adding one customer of a chain with demands r gives
c_j = sum_{n=1..k} (n/mu_j(n)) * P_j^{k-1}(n-1) lambda_k = 1 / sum_j r_j c_j P^k(n) = lambda_k * sum_j r_j (n_j/mu_j(n_j)) * P^{k-1}(n-e_j)
where lambda_k is the throughput of the customer being added and 1/c_j is the throughput of a chain visiting center j only. The recursion conserves probability mass by construction, hence it is numerically stable.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray | None) – Think time vector (R,), optional (default: zeros). If sum(Z)>0 an extra infinite-server station is appended, so that states has M+1 columns and its last column holds the think-station population.
mu (numpy.ndarray | None) – Load-dependent rate matrix (M x Nt), Nt=sum(N), optional (default: ones, i.e. single-server fixed rate). Use mu[j,:]=1..Nt for infinite server and mu[j,n]=min(n+1,c) for a c-server station.
- Returns:
- Pjoint: Probability of the aggregate state in the corresponding row
of states, of length nchoosek(Nt+J-1, J-1)
states: Aggregate states (S x J), states[s,j] = jobs at center j XN: Throughput of chain r (R,) QN: Mean number of chain-r customers at station j (M x R) UN: Utilization of station j (M,), i.e. 1-P_j(0) CN: Cycle time of chain r, exclusive of think time (R,) pi: Marginal probabilities, pi[j,n] = P(n jobs at station j),
shape (M, Nt+1)
- Return type:
Tuple of (Pjoint, states, XN, QN, UN, CN, pi)
References
E. de Souza e Silva, “Distribution Analysis of Product Form Queueing Networks”, UCLA Computer Science Department, CSD-870023, April 1987.
- pfqn_recal(L, N, Z=None, m0=None)[source]
RECAL (REcursive CALculation) method for normalizing constant.
Computes the normalizing constant G(N) using the RECAL recursive method, which is efficient for networks with moderate population sizes.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray | None) – Think time vector (R,), optional (default: zeros)
m0 (numpy.ndarray | None) – Initial multiplicity vector (M,), optional (default: ones)
- Returns:
G: Normalizing constant lG: Logarithm of normalizing constant
- Return type:
Tuple of (G, lG)
References
Original MATLAB: matlab/src/api/pfqn/pfqn_recal.m Conway, A.E. and Georganas, N.D. “RECAL - A New Efficient Algorithm for the Exact Analysis of Multiple-Chain Closed Queueing Networks”, JACM, 1986.
- pfqn_mvac(L, N, Z=None)[source]
MVAC (Mean Value Analysis by Chain) for closed product-form networks.
Exact mean value analysis of a closed multichain product-form queueing network composed of single-server fixed-rate (SSFR) queues and infinite-server (IS) centers. Unlike the classic MVA recursion of pfqn_mva, which recurs on the population vector and costs O(prod(N+1)), MVAC recurs on the chains: each class is reduced to single-customer chains and the removed chains are replaced by self-looping single-customer (SCSL) chains pinned at a service center, so the multiplicity vector v = (v_1,…,v_J), with v_j the number of SCSL chains at center j, indexes the recursion in place of the population vector. MVAC is thus attractive for networks with few centers and many chains, and is the mean-value counterpart of the RECAL normalizing-constant recursion of pfqn_recal. Since no normalizing constant is formed, MVAC does not suffer the floating-point underflow/overflow that complicates RECAL and convolution.
With j, i indexing centers (j = 1,…,J1 SSFR and j = J1+1,…,J IS), k, l indexing single-customer chains, a_jk the relative utilization (service demand) of chain k at center j, a_k = sum_j a_jk, K the total number of single-customer chains, and I_k = {v : sum_j v_j = K - k}, the recursion of Section II of the paper reads
lambda^k_k(v) = 1 / (a_k + sum_{j=1}^{J1} a_jk (L^{k-1}_j(v) + v_j)) (10) L^k_{jk}(v) = lambda^k_k(v) a_jk (1 + L^{k-1}_j(v) + v_j), j SSFR (9a) L^k_{jk}(v) = lambda^k_k(v) a_jk, j IS (9b) L^k_i(v) = sum_j L^k_{jk}(v) L^{k-1}_i(v + 1_j) + L^k_{ik}(v) (7) L^k_{il}(v) = sum_j L^k_{jk}(v) L^{k-1}_{il}(v + 1_j), l = 1..k-1 (6)
with L^0_j(v) = 0, where L^k_j(v) is the mean number of customers at center j (SCSL customers excluded), L^k_{jl}(v) the mean number of chain-l customers at center j, and lambda^k_k(v) the throughput of chain k, all for the network with normalizing constant G_k(v). Equation (10) is the arrival-theorem closure obtained by summing (9a)-(9b) over all centers, since chain k holds a single customer. The measures of the original network are read off at k = K and v = 0.
Part 1 of the basic step evaluates (10), (9) and (7) and yields the measures of chain K; part 2 evaluates (6) and yields those of the chains that visit at least one IS center, whose throughput then follows from Little’s law at that center. Chains visiting only SSFR centers require a re-execution of part 1 with their label interchanged with K, which is cheap because the levels below the interchanged label are unaffected and are reused. Classes with N_r > 1, and classes with identical demand columns, collapse into a single subset of identical single-customer chains: only one representative per subset is analyzed and its per-chain measures are scaled by the class population, so the cost depends on the number D of distinct chains, not K.
- Parameters:
L (numpy.ndarray) – Service demand matrix of the SSFR queues (M x R)
N (numpy.ndarray) – Population vector (R,), finite and nonnegative
Z (numpy.ndarray | None) – Service demand matrix of the IS centers, (R,) or (Mz x R), one row per IS center, optional (default: zeros)
- Returns:
XN: Per-class throughput at the reference station (R,) QN: Per-class mean queue-length at the SSFR queues (M x R) UN: Per-class utilization, XN[r] * L[i,r] (M x R) CN: Per-class residence time, QN[i,r] / XN[r] (M x R)
- Return type:
Tuple of (XN, QN, UN, CN)
References
A. E. Conway, E. de Souza e Silva and S. S. Lavenberg, “Mean Value Analysis by Chain of Product Form Queueing Networks”, IEEE Trans. Computers, 38(3):432-442, 1989. Original MATLAB: matlab/src/api/pfqn/pfqn_mvac.m
- pfqn_mvacld(L, N, Z=None, mu=None)[source]
MVAC for closed product-form networks with queue-length dependent centers.
Exact mean value analysis by chain of a closed multichain product-form queueing network that may contain queue-length dependent (QLD) service centers. This is the Section V extension of Conway, de Souza e Silva and Lavenberg (1989); pfqn_mvac implements Sections II-IV, which cover single-server fixed-rate (SSFR) and infinite-server (IS) centers only.
Where pfqn_mvac propagates the MEAN queue-lengths L^k_j(v) through eq. (7) and closes the recursion with the arrival-theorem identity (10), the QLD extension propagates the MARGINAL queue-length DISTRIBUTIONS P^k_j(n,v) instead. That is forced by load dependence – the rate seen by a job depends on the whole occupancy, so a mean no longer suffices – but it also SIMPLIFIES the recursion: eq. (21)-(25) read level k-1 only at the shifted vectors v + 1_i, so the basic step sweeps v in I_k alone, where pfqn_mvac must sweep the larger I_k u … u I_K. The marginals come almost for free and are returned as a first-class output.
Notation follows pfqn_mvac: j, i index centers (j = 1,…,J1 the QLD centers of L, j = J1+1,…,J the IS centers of Z), k, l index the single-customer chains, a_jk = theta_jk T_jk is the demand of chain k at center j, K = sum(N) and I_k = {v : sum_j v_j = K - k} with v_j the number of self-looping single-customer (SCSL) chains pinned at center j. P^k_j(n,v) is the probability of n customers at center j – EXCLUDING the v_j SCSL customers there – in the network with normalizing constant G_k(v). Writing tau_k(v,i) for the throughput of an SCSL chain that replaces chain k at center i:
- tau_k(v,i) = T_ik^-1 sum_{n=0}^{k-1} P^{k-1}_i(n,v+1_i)
mu_i(n+v_i+1)/(n+v_i+1) (21)
tau_k(v,i) = T_ik^-1, i IS (22) L^k_{jk}(v) = theta_jk tau_k(v,j)^-1 / sum_m theta_mk tau_k(v,m)^-1 (23) lambda^k_k(v) = tau_k(v,j(k)) L^k_{j(k)k}(v) (24) P^k_j(n,v) = L^k_{jk}(v) P^{k-1}_j(n-1,v+1_j)
sum_{m != j} L^k_{mk}(v) P^{k-1}_j(n,v+1_m) (25)
with P^0_j(0,v) = 1 and P^{k-1}_j(n,.) = 0 for n < 0 or n > k-1. Eq. (21) is just “the mean rate at which an SCSL chain is served”: given n other customers the processor-sharing rate share is mu_i(n+v_i+1)/(n+v_i+1), averaged over the distribution of those others. The queueing discipline may be assumed PS with no loss of generality, since product-form measures do not depend on it.
This implementation writes (23)-(24) in the reference-station-free form
- c_i(k,v) = sum_{n=0}^{k-1} P^{k-1}_i(n,v+1_i)
mu_i(n+v_i+1)/(n+v_i+1)
L^k_{jk}(v) = (a_jk/c_j) / sum_m (a_mk/c_m) lambda^k_k(v) = 1 / sum_m (a_mk/c_m)
which follows from theta_jk tau_k(v,j)^-1 = a_jk/c_j and theta_{j(k)k} = 1, so only the demands a_jk are needed and the visit ratios never appear separately. For an IS center c_i = 1 identically, which is exactly (22). Eq. (25) is self-normalizing, sum_n P^k_j(n,v) = sum_m L^k_{mk}(v) = 1, so no normalizing constant is formed and the recursion involves only positive quantities: unlike the classic load-dependent MVA of pfqn_mvald it cannot produce negative probabilities and needs no stabilization.
Parts 2 and 3 are unchanged from pfqn_mvac, since eq. (6) holds verbatim in the presence of QLD centers: part 2 resolves the chains that visit at least one IS center, and the chains that visit no IS center are resolved by re-executing part 1 with their label interchanged with K.
- Parameters:
L (numpy.ndarray) – Service demand matrix of the QLD centers (M x R)
N (numpy.ndarray) – Population vector (R,), finite and nonnegative
Z (numpy.ndarray | None) – Demand matrix of the IS centers, (R,) or (Mz x R), one row per center, optional (default: zeros)
mu (numpy.ndarray | None) – Load-dependent rates (M x Nt) with Nt >= sum(N); mu[j,n-1] is the total service rate of center j with n jobs present. mu[j,:] = 1 is a single-server fixed-rate queue, mu[j,n-1] = min(n,c) a c-server queue, mu[j,n-1] = n an infinite server. Optional (default: ones, i.e. all centers SSFR, in which case results agree with pfqn_mvac)
- Returns:
XN: Per-class throughput at the reference station (R,) QN: Per-class mean queue-length at the QLD centers (M x R) UN: Utilization of each center (M,), 1 - P_j(0). PER-STATION, not
per-class, as in pfqn_mvald and pfqn_dac: for a load-dependent center the per-class product XN[r]*L[j,r] of pfqn_mvac is NOT the utilization
- CN: Per-class cycle time exclusive of think time (R,),
N[r]/XN[r]-Z[r], as in pfqn_mvald and pfqn_dac. NOT the (M x R) per-station residence time of pfqn_mvac: the whole LD family reports a cycle time here
- pij: Marginal queue-length probabilities (M x (sum(N)+1)),
pij[j,n] = P(n jobs at center j)
- Return type:
Tuple of (XN, QN, UN, CN, pij)
References
A. E. Conway, E. de Souza e Silva and S. S. Lavenberg, “Mean Value Analysis by Chain of Product Form Queueing Networks”, IEEE Trans. Computers, 38(3):432-442, 1989, Section V. Original MATLAB: matlab/src/api/pfqn/pfqn_mvacld.m
- pfqn_mvaldmx(lam, D, N, Z, mu=None, S=None)[source]
Load-dependent MVA for mixed open/closed networks with limited load dependence.
Implements the MVALDMX algorithm for analyzing mixed queueing networks with load-dependent service rates using limited load dependence.
- Parameters:
lam (numpy.ndarray) – Arrival rate vector (R,) - non-zero for open classes
D (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,) - inf for open classes
Z (numpy.ndarray) – Think time vector (R,)
mu (numpy.ndarray | None) – Load-dependent rate matrix (M x Nt), optional
S (numpy.ndarray | None) – Number of servers per station (M,), optional
- Returns:
XN: System throughput (R,) QN: Mean queue lengths (M, R) UN: Utilization (M, R) CN: Cycle times (M, R) lGN: Logarithm of normalizing constant Pc: Marginal queue-length probabilities (M, 1+Ntot, prod(1+Nc))
- Return type:
Tuple of (XN, QN, UN, CN, lGN, Pc)
References
Original MATLAB: matlab/src/api/pfqn/pfqn_mvaldmx.m
- pfqn_ldmx_ec(lam, D, mu)[source]
Compute effective capacity terms for MVALDMX solver.
Calculates the effective capacity E, E’, and EC terms needed for load-dependent MVA with limited load dependence.
- Parameters:
lam (numpy.ndarray) – Arrival rate vector (R,)
D (numpy.ndarray) – Service demand matrix (M x R)
mu (numpy.ndarray) – Load-dependent rate matrix (M x Nt)
- Returns:
EC: Effective capacity matrix (M x Nt) E: E-function values (M x (1+Nt)) Eprime: E-prime function values (M x (1+Nt)) Lo: Open class load vector (M,)
- Return type:
Tuple of (EC, E, Eprime, Lo)
References
Original MATLAB: matlab/src/api/pfqn/pfqn_ldmx_ec.m
- pfqn_mvaldms(lam, D, N, Z, S)[source]
Load-dependent MVA for multiserver mixed networks.
Wrapper for pfqn_mvaldmx that adjusts utilizations to account for multi-server stations.
- Parameters:
lam (numpy.ndarray) – Arrival rate vector (R,)
D (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,)
S (numpy.ndarray) – Number of servers per station (M,)
- Returns:
XN: System throughput (R,) QN: Mean queue lengths (M, R) UN: Utilization (M, R) - adjusted for multiservers CN: Cycle times (M, R) lGN: Logarithm of normalizing constant
- Return type:
Tuple of (XN, QN, UN, CN, lGN)
References
Original MATLAB: matlab/src/api/pfqn/pfqn_mvaldms.m
- pfqn_linearizerms(L, N, Z, nservers, type_sched=None, tol=1e-8, maxiter=1000, QN0=None)[source]
Multiserver Linearizer (Krzesinski/Conway/De Souza-Muntz).
Extends the Linearizer algorithm to handle multi-server stations in product-form queueing networks.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,)
nservers (numpy.ndarray) – Number of servers per station (M,)
type_sched (numpy.ndarray | None) – Scheduling strategy per station (M,), optional (default: PS)
tol (float) – Convergence tolerance (default: 1e-8)
maxiter (int) – Maximum iterations (default: 1000)
- Returns:
Q: Mean queue lengths (M, R) U: Utilization (M, R) R: Residence times (M, R) C: Cycle times (R,) X: System throughput (R,) totiter: Total iterations performed
- Return type:
Tuple of (Q, U, R, C, X, totiter)
References
Original MATLAB: matlab/src/api/pfqn/pfqn_linearizerms.m
- pfqn_linearizermx(lambda_arr, L, N, Z, nservers, sched_type, tol=1e-8, maxiter=1000, method='egflin', QN0=None)[source]
Linearizer for mixed open/closed queueing networks.
This function extends the linearizer algorithm to handle networks with both open classes (with external arrivals) and closed classes (with fixed populations).
- Parameters:
lambda_arr (numpy.ndarray) – Arrival rate vector (R,). For closed classes, should be 0 or inf.
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,). Inf for open classes, finite for closed.
Z (numpy.ndarray) – Think time vector (R,) or matrix
nservers (numpy.ndarray) – Number of servers per station (M,)
sched_type (List[str]) – Scheduling strategy per station (list of strings)
tol (float) – Convergence tolerance
maxiter (int) – Maximum iterations
method (str) – Linearizer variant (‘lin’, ‘gflin’, ‘egflin’)
- Returns:
Mean queue lengths (M x R) UN: Utilization (M x R) WN: Waiting times (M x R) TN: Throughputs (M x R) CN: Cycle times (1 x R) XN: System throughput (R,) totiter: Total iterations
- Return type:
QN
References
MATLAB: matlab/src/api/pfqn/pfqn_linearizermx.m
- pfqn_conwayms(L, N, Z, nservers, type_sched=None, tol=1e-8, maxiter=1000, QN0=None)[source]
Conway (1989) multiserver Linearizer approximation for FCFS queues.
Implements the algorithm from Conway (1989), “Fast Approximate Solution of Queueing Networks with Multi-Server Chain-Dependent FCFS Queues”.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,)
nservers (numpy.ndarray) – Number of servers per station (M,)
type_sched (numpy.ndarray | None) – Scheduling strategy per station (M,), optional (default: FCFS)
tol (float) – Convergence tolerance (default: 1e-8)
maxiter (int) – Maximum iterations (default: 1000)
- Returns:
Q: Mean queue lengths (M, R) U: Utilization (M, R) R: Residence times (M, R) C: Cycle times (R,) X: System throughput (R,) totiter: Total iterations performed
- Return type:
Tuple of (Q, U, R, C, X, totiter)
References
Conway, A. E., “Fast Approximate Solution of Queueing Networks with Multi-Server Chain-Dependent FCFS Queues”, Performance Evaluation, Vol. 8, 1989, pp. 141-159.
- ljd_linearize(nvec, cutoffs)[source]
Convert per-class population vector to linearized index.
Maps a multi-dimensional population vector to a single linear index for efficient lookups in tabulated scaling tables.
Index formula: idx = 1 + n1 + n2*(N1+1) + n3*(N1+1)*(N2+1) + …
- Parameters:
nvec (numpy.ndarray) – Per-class populations [n1, n2, …, nK]
cutoffs (numpy.ndarray) – Per-class cutoffs [N1, N2, …, NK]
- Returns:
1-based linearized index
- Return type:
References
Original MATLAB: matlab/src/api/pfqn/ljd_linearize.m
- infradius_h(x, L, N, alpha)[source]
Helper function for infinite radius computation with logistic transformation.
Used in normalizing constant computation via integration methods.
- Parameters:
x (numpy.ndarray) – Logistic transformation parameters
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
alpha (numpy.ndarray) – Load-dependent rate matrix
- Returns:
Evaluated function value for integration
- Return type:
References
Original MATLAB: matlab/src/api/pfqn/infradius_h.m
- infradius_hnorm(x, L, N, alpha)[source]
Helper function for infinite radius computation with normal CDF (probit) transformation.
Uses normcdf/normpdf transformation instead of logistic (used in infradius_h).
- Parameters:
x (numpy.ndarray) – Normal CDF transformation parameters
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
alpha (numpy.ndarray) – Load-dependent rate matrix
- Returns:
Evaluated function value for integration
- Return type:
References
Original MATLAB: matlab/src/api/pfqn/infradius_hnorm.m
- pfqn_kt(L, N, Z=None)[source]
Knessl-Tier asymptotic expansion for normalizing constant.
Computes the normalizing constant using Knessl-Tier’s asymptotic expansion, which is particularly accurate for large populations.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray | None) – Think time vector (R,), optional (default: zeros)
- Returns:
G: Normalizing constant lG: Logarithm of normalizing constant X: System throughput (R,) Q: Mean queue lengths (M, R)
- Return type:
Tuple of (G, lG, X, Q)
References
Original MATLAB: matlab/src/api/pfqn/pfqn_kt.m
- pfqn_ab_amva(D, N, V, nservers, sched, fcfs_schmidt=False, marginal_prob_method='ab')[source]
Akyildiz-Bolch AMVA method for multi-server BCMP networks.
- Parameters:
D (numpy.ndarray) – Service time matrix (M x K)
N (numpy.ndarray) – Population vector (1 x K)
V (numpy.ndarray) – Visit ratio matrix (M x K)
nservers (numpy.ndarray) – Number of servers at each station (M x 1)
sched (numpy.ndarray) – Scheduling strategies for each station (M x 1)
fcfs_schmidt (bool) – Whether to use Schmidt formula for FCFS stations
marginal_prob_method (str) – Method for marginal probability (‘ab’ or ‘scat’)
- Returns:
AbAmvaResult containing queue lengths, utilization, residence times, cycle times, throughput, and iteration count.
- Return type:
- pfqn_ab_core(K, M, population, nservers, sched_type, v, s, maxiter, D_frac, l_in, fcfs_schmidt=False, marginal_prob_method='ab')[source]
Akyildiz-Bolch core method for multi-server BCMP networks.
Public wrapper for the internal core algorithm of the Akyildiz-Bolch linearizer method.
- Parameters:
K (int) – Number of classes
M (int) – Number of stations
population (numpy.ndarray) – Population vector (K,)
nservers (numpy.ndarray) – Number of servers at each station (M,)
sched_type (numpy.ndarray) – Scheduling strategies for each station (M,)
v (numpy.ndarray) – Visit ratio matrix (M x K)
s (numpy.ndarray) – Service time matrix (M x K)
maxiter (int) – Maximum iterations
D_frac (numpy.ndarray) – Fractional changes matrix (M x K x K)
l_in (numpy.ndarray) – Initial queue length matrix (M x K)
fcfs_schmidt (bool) – Whether to use Schmidt formula for FCFS stations
marginal_prob_method (str) – Method for marginal probability (‘ab’ or ‘scat’)
- Returns:
QN: Queue lengths (M x K) UN: Utilization (M x K) RN: Residence times (M x K) CN: Cycle times (K,) XN: Throughput (K,) totiter: Total iterations
- Return type:
Tuple of (QN, UN, RN, CN, XN, totiter)
References
Akyildiz, I.F. and Bolch, G., “Mean Value Analysis Approximation for Multiple Server Queueing Networks”, Performance Evaluation, 1988.
- class AbAmvaResult(QN, UN, RN, CN, XN, totiter)[source]
Bases:
objectResult from Akyildiz-Bolch AMVA algorithm.
- QN: numpy.ndarray
- UN: numpy.ndarray
- RN: numpy.ndarray
- CN: numpy.ndarray
- XN: numpy.ndarray
- pfqn_rd(L, N, Z, mu=None, options=None)[source]
Reduction Heuristic (RD) method for load-dependent networks.
Computes the logarithm of the normalizing constant using the reduction heuristic method, which handles load-dependent service rates.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (1 x R)
Z (numpy.ndarray) – Think time vector (1 x R)
mu (numpy.ndarray | None) – Load-dependent rate matrix (M x sum(N)). If None, assumes load-independent rates (all 1.0).
options (RdOptions | None) – Solver options
- Returns:
lGN: Logarithm of normalizing constant Cgamma: Gamma correction factor
- Return type:
Tuple of (lGN, Cgamma) where
- pfqn_nrl(L, N, Z=None, alpha=None)[source]
Norlund-Rice Logit (NRL) approximation for normalizing constant.
Computes the logarithm of the normalizing constant using Laplace approximation with logistic transformation.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,) - optional
alpha (numpy.ndarray) – Load-dependent rate matrix (M x Ntot) - optional
- Returns:
Logarithm of normalizing constant
- Return type:
lG
References
Original MATLAB: matlab/src/api/pfqn/pfqn_nrl.m
- pfqn_nrp(L, N, Z=None, alpha=None)[source]
Norlund-Rice Probit (NRP) approximation for normalizing constant.
Computes the logarithm of the normalizing constant using Laplace approximation with probit (normalized) transformation.
- Parameters:
L (numpy.ndarray) – Service demand matrix (M x R)
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,) - optional
alpha (numpy.ndarray) – Load-dependent rate matrix (M x Ntot) - optional
- Returns:
Logarithm of normalizing constant
- Return type:
lG
References
Original MATLAB: matlab/src/api/pfqn/pfqn_nrp.m
- pfqn_lap(L, N, Z)[source]
Laplace approximation for normalizing constant.
Computes the logarithm of the normalizing constant using the classical Laplace approximation with root finding.
This method uses a saddle-point approximation to estimate the normalizing constant integral representation.
- Parameters:
L (numpy.ndarray) – Service demand vector (R,) - single station
N (numpy.ndarray) – Population vector (R,)
Z (numpy.ndarray) – Think time vector (R,)
- Returns:
Logarithm of normalizing constant approximation
- Return type:
lG
References
Original MATLAB: matlab/src/api/pfqn/pfqn_lap.m
- laplaceapprox(h, x0, tol=1e-5)[source]
Laplace approximation for multidimensional integrals.
- Approximates I = ∫ h(x) dx using the Laplace method:
I ≈ h(x0) * sqrt((2π)^d / det(-H))
where H is the Hessian of log(h) at x0.
- Parameters:
h (Callable) – Function to integrate (must be positive)
x0 (numpy.ndarray) – Point for Laplace approximation (typically the mode)
tol (float) – Tolerance for numerical Hessian computation
- Returns:
I: Approximate integral value H: Hessian matrix at x0 logI: Logarithm of integral value (more stable)
- Return type:
Tuple (I, H, logI) where
- num_hess(f, x0, tol=1e-5)[source]
Compute numerical Hessian matrix using finite differences.
Uses central differences for improved accuracy.
- Parameters:
f (Callable) – Function to differentiate (maps x -> scalar)
x0 (numpy.ndarray) – Point at which to compute Hessian
tol (float) – Step size for finite differences
- Returns:
Hessian matrix (d x d) where d = len(x0)
- Return type:
- pfqn_stdf(L, N, Z, S, fcfs_nodes, rates, tset)[source]
Compute sojourn time distribution for multiserver FCFS nodes.
Implements McKenna’s method for computing the response time distribution at multiserver FCFS stations in closed queueing networks.
- Parameters:
L (numpy.ndarray) – Load matrix (M x R) - service demands
N (numpy.ndarray) – Population vector (R,) - number of jobs per class
Z (numpy.ndarray) – Think time vector (R,) or matrix (1 x R)
S (numpy.ndarray) – Number of servers at each station (M,)
fcfs_nodes (numpy.ndarray) – Array of FCFS station indices (1-indexed as in MATLAB)
rates (numpy.ndarray) – Service rates matrix (M x R)
tset (numpy.ndarray) – Time points at which to evaluate the distribution
- Returns:
Dictionary with (station, class) tuples as keys and response time distribution arrays as values. Each array has shape (len(tset), 2) with:
column 0: CDF values
column 1: time points
- Return type:
Dict[Tuple[int, int], numpy.ndarray]
Examples
>>> L = np.array([[0.5, 0.3], [0.2, 0.4]]) >>> N = np.array([2, 3]) >>> Z = np.array([1.0, 1.0]) >>> S = np.array([2, 1]) >>> fcfs_nodes = np.array([0]) # 0-indexed >>> rates = np.array([[1.0, 1.0], [2.0, 2.0]]) >>> tset = np.linspace(0.1, 5.0, 50) >>> RD = pfqn_stdf(L, N, Z, S, fcfs_nodes, rates, tset)
- pfqn_stdf_heur(L, N, Z, S, fcfs_nodes, rates, tset)[source]
Heuristic sojourn time distribution for multiserver FCFS nodes.
Implements a variant of McKenna’s 1987 method that uses per-class service rate weighting for improved accuracy in multiclass networks.
Unlike pfqn_stdf which uses a simpler Erlang model for the waiting component, this heuristic accounts for class-dependent waiting times based on the expected queue composition.
- Parameters:
L (numpy.ndarray) – Load matrix (M x R) - service demands
N (numpy.ndarray) – Population vector (R,) - number of jobs per class
Z (numpy.ndarray) – Think time vector (R,) or matrix (1 x R)
S (numpy.ndarray) – Number of servers at each station (M,)
fcfs_nodes (numpy.ndarray) – Array of FCFS station indices (0-indexed)
rates (numpy.ndarray) – Service rates matrix (M x R)
tset (numpy.ndarray) – Time points at which to evaluate the distribution
- Returns:
Dictionary with (station, class) tuples as keys and response time distribution arrays as values. Each array has shape (len(tset), 2) with:
column 0: CDF values
column 1: time points
- Return type:
Dict[Tuple[int, int], numpy.ndarray]
References
McKenna, J. “Mean Value Analysis for networks with service-time-dependent queue disciplines.” Performance Evaluation, 1987.
- pfqn_cftp(L, N, S=None, nsamples=1, method='cftp')[source]
Exact (perfect) stationary state sampling for closed single-class multiserver product-form networks via monotone Coupling From The Past.
- Parameters:
L (numpy.ndarray) – Service demands (stations,), L[i] = theta_i / mu_i
N (int) – Total closed population (scalar)
S (numpy.ndarray) – Number of servers per station (default 1; use np.inf for infinite server). If None, defaults to ones.
nsamples (int) – Number of independent samples to draw (default 1)
method (str) – ‘cftp’ for exact/perfect sampling (default) or ‘approx’ for rapidly-mixing approximate sampler M_A
- Returns:
Empirical mean queue length per station (1 x stations) X: Sampled states, one per row (nsamples x stations), each row sums to N T: Per-sample coalescence horizon (‘cftp’) or mixing steps used
(‘approx’), as (nsamples,)
- Return type:
Q
- Raises:
ValueError – If less than 2 stations or non-positive demands
Matrix-Analytic Methods (line_solver.api.mam)
Matrix-Analytic Methods (MAM) for MAP/PH distributions.
Native Python implementations for analyzing Markovian Arrival Processes (MAPs), Phase-Type (PH) distributions, and related matrix-analytic methods.
- Key algorithms:
map_piq: CTMC steady-state of MAP map_pie: Embedded DTMC steady-state map_lambda: Arrival rate computation map_mean, map_var, map_scv: Moment computations solver_mam_map_bmap_1: MAP/BMAP/1 queue solver using GI/M/1-type ETAQA solver_mam_bmap_map_1: BMAP/MAP/1 queue solver using M/G/1-type ETAQA
- map_infgen(D0, D1)[source]
Compute the infinitesimal generator of a MAP.
The generator Q = D0 + D1 represents the underlying CTMC.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix (non-arrival transitions)
D1 (numpy.ndarray) – Visible transition matrix (arrival transitions)
- Returns:
Infinitesimal generator matrix Q = D0 + D1
- Return type:
- map_piq(D0, D1=None)[source]
Compute steady-state distribution of the underlying CTMC of a MAP.
Solves πQ = 0 where Q = D0 + D1 is the generator.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix, or stacked [D0, D1] if D1 is None
D1 (numpy.ndarray) – Visible transition matrix (optional)
- Returns:
Steady-state probability vector π
- Return type:
- map_prob(D0, D1=None)[source]
Stationary distribution of the underlying CTMC of a MAP (alias of
map_piq(), matching the MATLABmap_probname).
- map_pie(D0, D1=None)[source]
Compute equilibrium distribution of embedded DTMC.
The embedded DTMC has transition matrix P = (-D0)^{-1} * D1. Its steady-state is π_e = π * D1 / (π * D1 * e).
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix, or stacked [D0, D1] if D1 is None
D1 (numpy.ndarray) – Visible transition matrix (optional)
- Returns:
Equilibrium distribution of embedded DTMC
- Return type:
- map_lambda(D0, D1=None)[source]
Compute the arrival rate (λ) of a MAP.
The arrival rate is λ = π * D1 * e where π is the steady-state and e is the column vector of ones.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix, or stacked [D0, D1] if D1 is None
D1 (numpy.ndarray) – Visible transition matrix (optional)
- Returns:
Arrival rate λ
- Return type:
- map_mean(D0, D1=None)[source]
Compute mean inter-arrival time of a MAP.
The mean is 1/λ where λ is the arrival rate.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix, or stacked [D0, D1] if D1 is None
D1 (numpy.ndarray) – Visible transition matrix (optional)
- Returns:
Mean inter-arrival time
- Return type:
- map_var(D0, D1=None)[source]
Compute variance of inter-arrival times of a MAP.
Var[X] = E[X²] - E[X]²
Uses map_moment for consistency with Kotlin implementation.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix, or stacked [D0, D1] if D1 is None
D1 (numpy.ndarray) – Visible transition matrix (optional)
- Returns:
Variance of inter-arrival times
- Return type:
- map_scv(D0, D1=None)[source]
Compute squared coefficient of variation (SCV) of a MAP.
SCV = Var[X] / E[X]² = (E[X²] - E[X]²) / E[X]²
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix, or stacked [D0, D1] if D1 is None
D1 (numpy.ndarray) – Visible transition matrix (optional)
- Returns:
Squared coefficient of variation
- Return type:
- map_moment(D0, D1, k)[source]
Compute the k-th moment of inter-arrival time distribution.
E[X^k] = k! * π_e * (-D0)^{-k} * e
where π_e is the embedded DTMC steady-state.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
k (int) – Moment order (k >= 1)
- Returns:
k-th raw moment
- Return type:
- map_scale(D0, D1, factor)[source]
Scale a MAP by a given factor.
Scaling changes the time scale: D0’ = factor * D0, D1’ = factor * D1.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
factor (float) – Scaling factor (> 0)
- Returns:
Tuple of scaled (D0’, D1’)
- Return type:
- map_normalize(D0, D1)[source]
Normalize a MAP to have unit mean inter-arrival time.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
- Returns:
Tuple of normalized (D0’, D1’)
- Return type:
- map_isfeasible(D0, D1, tolerance=1e-10)[source]
Check if (D0, D1) form a valid MAP.
A valid MAP requires: - D0 has non-positive diagonal and non-negative off-diagonal - D1 has non-negative elements - D0 + D1 is a valid generator (row sums = 0)
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
tolerance (float) – Numerical tolerance
- Returns:
True if valid MAP
- Return type:
- exp_map(lambda_rate)[source]
Create a MAP representation of an exponential distribution.
- Parameters:
lambda_rate (float) – Rate parameter (λ > 0)
- Returns:
Tuple of (D0, D1) matrices representing Exp(λ)
- Return type:
- erlang_map(k, lambda_rate)[source]
Create a MAP representation of an Erlang-k distribution.
- Parameters:
- Returns:
Tuple of (D0, D1) matrices representing Erlang(k, k*λ)
- Return type:
- hyperexp_map(probs, rates)[source]
Create a MAP representation of a hyperexponential distribution.
- Parameters:
probs (numpy.ndarray) – Probability vector for choosing each phase
rates (numpy.ndarray) – Rate parameters for each phase
- Returns:
Tuple of (D0, D1) matrices representing hyperexponential
- Return type:
- map_exponential(mean)[source]
Create a MAP representation of an exponential distribution (MATLAB-style).
This is a MATLAB-compatible wrapper that takes mean instead of rate.
- Parameters:
mean (float) – Mean inter-arrival time (= 1/λ)
- Returns:
Tuple of (D0, D1) matrices representing Exp(1/mean)
- Return type:
Examples
>>> D0, D1 = map_exponential(2) # Poisson process with rate λ=0.5
- map_erlang(mean, k)[source]
Create a MAP representation of an Erlang-k distribution (MATLAB-style).
This is a MATLAB-compatible wrapper that takes mean as first argument.
- Parameters:
- Returns:
Tuple of (D0, D1) matrices representing Erlang-k with given mean
- Return type:
Examples
>>> D0, D1 = map_erlang(2, 3) # Erlang-3 with mean 2
- map_hyperexp(probs, means)[source]
Create a MAP representation of a hyperexponential distribution (MATLAB-style).
This is a MATLAB-compatible wrapper that takes means instead of rates.
- Parameters:
probs (numpy.ndarray) – Probability vector for choosing each phase
means (numpy.ndarray) – Mean values for each phase (1/rates)
- Returns:
Tuple of (D0, D1) matrices representing hyperexponential
- Return type:
- map_gamma(D0, D1, limit=1000)[source]
Estimate the autocorrelation decay rate of a MAP.
Mirrors MATLAB map_gamma. For MAPs of order higher than 2 the ACF is not geometric, so the decay rate is obtained by fitting rho_k = RHO0*gamma^k in the least-squares sense, with RHO0 = (1 - 1/SCV)/2 held fixed.
This is NOT a Gamma-distribution constructor; use map_erlang for that. It is also distinct from map_gamma2, which returns the second largest eigenvalue of the embedded DTMC (the two agree for order 2 only).
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
limit (int) – Maximum lag considered when fitting (default: 1000)
- Returns:
Autocorrelation decay rate
- Return type:
- map_sumind(maps)[source]
Compute the sum of independent MAPs.
Creates a MAP representing the sum (concatenation) of independent random variables represented by the input MAPs.
- Parameters:
maps (list) – List of MAPs, each as (D0, D1) tuple
- Returns:
Tuple of (D0, D1) matrices representing the sum
- Return type:
Examples
>>> # Sum of exponential and Erlang-2 >>> MAP1 = map_exponential(1.0) >>> MAP2 = map_erlang(1.0, 2) >>> D0, D1 = map_sumind([MAP1, MAP2])
- map_cdf(D0, D1, points)[source]
Compute cumulative distribution function of inter-arrival times.
F(t) = 1 - π_e * exp(D0*t) * e
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
points (numpy.ndarray) – Time points at which to evaluate CDF
- Returns:
CDF values at specified points
- Return type:
Examples
>>> map_cdf(D0, D1, 1.0) # Returns P(T <= 1) >>> map_cdf(D0, D1, [1.0, 5.0]) # Returns [P(T<=1), P(T<=5)]
- map_pdf(D0, D1, points)[source]
Compute probability density function of inter-arrival times.
f(t) = π_e * exp(D0*t) * (-D0) * e
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
points (numpy.ndarray) – Time points at which to evaluate PDF
- Returns:
PDF values at specified points
- Return type:
Examples
>>> map_pdf(D0, D1, [0.5, 1.0, 2.0])
- map_sample(D0, D1, n_samples, rng=None)[source]
Generate random samples from a MAP distribution.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
n_samples (int) – Number of samples to generate
rng (numpy.random.Generator | None) – Optional random number generator
- Returns:
Array of inter-arrival times
- Return type:
- map_skew(D0, D1)[source]
Compute skewness of inter-arrival times.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
- Returns:
Skewness of inter-arrival times
- Return type:
- map_kurt(D0, D1)[source]
Compute kurtosis of inter-arrival times.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
- Returns:
Kurtosis of inter-arrival times
- Return type:
- map_acf(D0, D1, lags=1)[source]
Compute autocorrelation coefficients of inter-arrival times.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
lags (int | numpy.ndarray) – Lag(s) at which to compute autocorrelation (default: 1)
- Returns:
Array of autocorrelation coefficients at specified lags
- Return type:
Examples
>>> map_acf(D0, D1) # lag-1 autocorrelation >>> map_acf(D0, D1, np.arange(1, 11)) # first 10 autocorrelations
- map_acfc(D0, D1, kset, u)[source]
Compute autocorrelation of counting process at given lags.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
kset (numpy.ndarray) – Set of lags
u (float) – Length of timeslot (time scale)
- Returns:
Autocorrelation coefficients at specified lags
- Return type:
- map_idc(D0, D1)[source]
Compute the asymptotic index of dispersion.
I = SCV * (1 + 2 * sum_{k=1}^{inf} rho_k)
where SCV is the squared coefficient of variation and rho_k is the lag-k autocorrelation coefficient.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
- Returns:
Asymptotic index of dispersion
- Return type:
- map_count_mean(D0, D1, t)[source]
Compute mean of counting process at resolution t.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
t (numpy.ndarray) – Time period(s) for counting
- Returns:
Mean arrivals in (0, t]
- Return type:
- map_count_var(D0, D1, t)[source]
Compute variance of counting process at resolution t.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
t (numpy.ndarray) – Time period(s) for counting
- Returns:
Variance of arrivals in (0, t]
- Return type:
- Reference:
He and Neuts, “Markov chains with marked transitions”, 1998
- map_count_idc(D0, D1, t)[source]
Index of dispersion for counts (IDC) of a MAP at time point(s) t.
The IDC of the counting process A(t) associated to the MAP is I_a(t) = Var(A(t)) / E[A(t)], t > 0, i.e. the scaled variance-time curve. It interpolates between I_a(0+) = SCV of the interarrival time (renewal MAP) and the asymptotic value I_a(inf) = map_idc(MAP).
- Reference:
W. Whitt and W. You, “A Robust Queueing Network Analyzer Based on Indices of Dispersion”, eq. (1).
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
t (numpy.ndarray) – Time period(s)
- Returns:
Column vector of IDC values, one per element of t.
- Return type:
- map_varcount(D0, D1, tset)[source]
Compute variance of counting process (alternative implementation).
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
tset (numpy.ndarray) – Set of time points
- Returns:
Variance at each time point
- Return type:
- map_count_moment(D0, D1, t, orders)[source]
Compute power moments of counts at resolution t.
Uses numerical differentiation of the moment generating function.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
t (float) – Resolution (time period)
orders (numpy.ndarray) – Orders of moments to compute
- Returns:
Power moments of counts
- Return type:
- map_mmpp2(mean, scv, skew=-1, acf1=-1)[source]
Fit an MMPP(2) as a MAP.
Matches the requested mean, SCV, skewness and lag-1 autocorrelation exactly. Raises ValueError when the request lies outside the MMPP(2) feasible set rather than returning a non-MAP.
- Parameters:
- Returns:
Tuple of (D0, D1) matrices
- Return type:
Examples
>>> D0, D1 = map_mmpp2(1, 2, -1, 0.2) # Minimal skewness, ACF=0.2 >>> D0, D1 = map_mmpp2(1, 2, -1, -1) # Minimal skewness, max ACF
- map_gamma2(D0, D1)[source]
Compute the second largest eigenvalue of embedded DTMC.
This is the autocorrelation decay rate.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
- Returns:
Second largest eigenvalue (gamma_2)
- Return type:
- map_rand(k=2)[source]
Generate a random MAP of order k.
- Parameters:
k (int) – Order of the MAP (default: 2)
- Returns:
Tuple of (D0, D1) matrices
- Return type:
- map_randn(k, mu=(1.0, 1.0), sigma=(0.5, 0.5))[source]
Generate a random MAP with normally distributed elements.
- Parameters:
- Returns:
Tuple of (D0, D1) matrices
- Return type:
- map_renewal(D0, D1)[source]
Remove all correlations from a MAP, creating a renewal process.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
- Returns:
Renewal MAP with same CDF but no correlations
- Return type:
- map_embedded(D0, D1)[source]
Compute embedded discrete-time transition matrix.
P = (-D0)^{-1} * D1
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
- Returns:
Transition matrix of embedded DTMC
- Return type:
- map_sum(D0, D1, n)[source]
Create MAP for sum of n IID random variables.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
n (int) – Number of variables to sum
- Returns:
Tuple of (D0_new, D1_new) for the sum
- Return type:
- map_super(D0_a, D1_a, D0_b, D1_b)[source]
Create superposition of two MAPs.
- Parameters:
D0_a (numpy.ndarray) – First MAP
D1_a (numpy.ndarray) – First MAP
D0_b (numpy.ndarray) – Second MAP
D1_b (numpy.ndarray) – Second MAP
- Returns:
Superposed MAP (D0, D1)
- Return type:
- map_mixture(alpha, maps)[source]
Create probabilistic mixture of MAPs.
- Parameters:
alpha (numpy.ndarray) – Probability vector for choosing each MAP
maps (list) – List of MAPs as (D0, D1) tuples
- Returns:
Mixture MAP (D0, D1)
- Return type:
- map_max(D0_a, D1_a, D0_b, D1_b)[source]
Create MAP for max(X, Y) where X ~ MAP_A and Y ~ MAP_B.
The phase space is ordered as [(i,j) pairs, B-only phases, A-only phases]: in the first block both A and B are still running, in the second block A has already completed and B is awaited, in the third block B has completed and A is awaited. An arrival is recorded when the second of the two completes, i.e. only out of the last two blocks.
- Parameters:
D0_a (numpy.ndarray) – First MAP
D1_a (numpy.ndarray) – First MAP
D0_b (numpy.ndarray) – Second MAP
D1_b (numpy.ndarray) – Second MAP
- Returns:
MAP for the maximum (D0, D1)
- Return type:
- map_timereverse(D0, D1)[source]
Compute time-reversed MAP.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
- Returns:
Time-reversed MAP (D0_r, D1_r)
- Return type:
- map_mark(D0, D1, prob)[source]
Mark arrivals from a MAP according to given probabilities.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
prob (numpy.ndarray) – Marking probabilities (prob[k] = P(mark type k))
- Returns:
MMAP as list [D0, D1_class1, D1_class2, …]
- Return type:
- map_stochcomp(D0, D1, retain_idx)[source]
Stochastic complementation to reduce MAP order.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
retain_idx (numpy.ndarray) – Indices of states to retain (0-indexed)
- Returns:
Reduced MAP (D0_new, D1_new)
- Return type:
- map_kpc(maps)[source]
Kronecker product composition of MAPs.
- Parameters:
maps (list) – List of MAPs as (D0, D1) tuples
- Returns:
Composed MAP (D0, D1)
- Return type:
- map_bernstein(f, n=20)[source]
Convert distribution to MAP via Bernstein approximation.
- Parameters:
f – PDF function handle
n (int) – Number of phases (default: 20)
- Returns:
MAP representation (D0, D1)
- Return type:
- map_pntiter(D0, D1, na, t, M=None)[source]
Compute probability of na arrivals in interval [0, t].
Uses iterative bisection method (Neuts and Li).
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
na (int) – Number of arrivals
t (float) – Time interval length
M (int | None) – Bisection depth (auto-computed if None)
- Returns:
Matrix of probabilities
- Return type:
- map_pntquad(D0, D1, na, t)[source]
Compute probability of na arrivals using ODE solver.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
na (int) – Number of arrivals
t (float) – Time interval length
- Returns:
Matrix P_n(t)
- Return type:
- map2_fit(e1, e2, e3=-1.0, g2=0.0)[source]
Fit a MAP(2) distribution to moments and autocorrelation.
Based on: A. Heindl, G. Horvath, K. Gross “Explicit inverse characterization of acyclic MAPs of second order”
- Parameters:
- Returns:
MAP: Tuple (D0, D1) if successful, None if failed
error_code: 0 for success, >0 for various errors
- Return type:
Tuple of (MAP, error_code) where
- Error codes:
0: Success 10: Mean out of bounds 20: Correlated exponential 30: h2 out of bounds 40: h3 out of bounds 51-54: g2 out of bounds
- map_joint(D0, D1, a, i)[source]
Compute joint moments of a MAP.
E[(X_{a1})^{i1} * (X_{a1+a2})^{i2} * …]
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix
a (numpy.ndarray) – Vector of inter-arrival lags
i (numpy.ndarray) – Vector of powers
- Returns:
Joint moment
- Return type:
- map_issym(D0, D1=None)[source]
Check if MAP contains symbolic elements.
In Python, this always returns False as we use numpy arrays.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D1 (numpy.ndarray) – Visible transition matrix (optional)
- Returns:
False (Python arrays are always numeric)
- Return type:
- map_feastol()[source]
Get the feasibility tolerance exponent for MAPs.
This is the exponent k of the toolbox feasibility tolerance 10^-k, so the tolerance itself is 10^-8. It is NOT the tolerance: map_feastol() == 8.
- Returns:
Tolerance exponent k, to be used as 10**(-map_feastol())
- Return type:
- map_feasblock(E1, E2, E3, G2, opt='')[source]
Fit the most similar feasible MAP(2).
- Parameters:
- Returns:
Feasible MAP (D0, D1)
- Return type:
- map_block(E1, E2, E3, G2, opt='')[source]
Construct a MAP(2) from moments and autocorrelation.
- Parameters:
- Returns:
MAP (D0, D1)
- Return type:
- map_largemap()[source]
Get threshold for “large” MAP where exact computation is expensive.
- Returns:
- Return type:
Order threshold (default
- mmap_infgen(D0, D_list)[source]
Compute the infinitesimal generator of an MMAP.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix (non-arrival transitions)
D_list (List[numpy.ndarray]) – List of arrival marking matrices [D1, D2, …, Dm]
- Returns:
Infinitesimal generator Q = D0 + D1 + D2 + … + Dm
- Return type:
- mmap_normalize(D0, D_list)[source]
Fix MMAP feasibility by clamping negative values and closing the generator.
Port of matlab/src/api/mam/mmap_normalize.m (mirrored by the JAR jline.api.mam.Mmap_normalize). The MMAP is [D0] + D_list with D_list = [D1, D21, …, D2C], i.e. the aggregate D1 followed by the C per-class marking matrices, so C = len(D_list) - 1. This is the layout produced by _mmap_to_tuple and by the mmap_super / mmap_max callers, which pass result[1:].
The aggregate D1 is recomputed as the sum of the per-class matrices, and the diagonal of D0 closes each row of the generator D0 + D1:
D0[k,k] = -sum_{j!=k} D0[k,j] - sum_j D1[k,j]
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D_list (List[numpy.ndarray]) – [D1, D21, …, D2C], the aggregate followed by the per-class marking matrices
- Returns:
Tuple of (normalized_D0, normalized_D_list) in the same layout
- Return type:
- mmap_super_safe(mmap_list, maxorder=1000, method='default')[source]
Safely superpose multiple MMAPs into a single MMAP.
Combines multiple MMAPs while ensuring the order of the resulting MMAP does not exceed maxorder. If combining would exceed maxorder, alternative methods are used (fitting to exponential or simplified MAP).
- Parameters:
mmap_list (List[Tuple[numpy.ndarray, List[numpy.ndarray]]]) – List of (D0, D_list) tuples, one per MMAP
maxorder (int) – Maximum allowed order (state space size) for result
method (str) – Combination method (“default” or “match”)
- Returns:
Tuple of (D0_super, D_list_super) for the superposed MMAP
- Return type:
- Algorithm:
Sort MMAPs by squared coefficient of variation (SCV) of unmarked process
Iteratively combine: start with simplest, add others in order
If Kronecker product would exceed maxorder, use simpler approximations
- mmap_mark(D0, D_list, prob)[source]
Reclassify arrivals in an MMAP according to a probability matrix.
Converts an MMAP with K classes to one with R classes based on a KxR probability matrix that describes how arrivals are reclassified.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D_list (List[numpy.ndarray]) – List of K arrival marking matrices [D1, D2, …, DK]
prob (numpy.ndarray) – K x R probability matrix where prob[k,r] is the probability that a class-k arrival in the original MMAP becomes a class-r arrival in the new MMAP
- Returns:
Tuple of (D0_new, D_list_new) where D_list_new has R matrices
- Return type:
Example
If prob = [[0.8, 0.2], [0.3, 0.7]], a 2-class MMAP becomes a 2-class MMAP where 80% of class-1 arrivals are now class-1, 20% become class-2, etc.
- mmap_scale(D0, D_list, M, max_iter=30)[source]
Scale the mean inter-arrival times of an MMAP.
Adjusts all matrices to achieve specified mean inter-arrival times.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D_list (List[numpy.ndarray]) – List of arrival marking matrices
M (float | numpy.ndarray) – Desired mean inter-arrival times. Can be: - Single float: uniform scaling of all classes - Array of K values: individual scaling per class
max_iter (int) – Maximum iterations for optimization (only for vector M)
- Returns:
Tuple of (D0_scaled, D_list_scaled)
- Return type:
- Algorithm:
For single M: Scale all matrices uniformly by ratio = M_old / M For vector M: Use iterative coordinate descent to find scaling factors
- mmap_hide(D0, D_list, types)[source]
Hide (remove) specified arrival classes from an MMAP.
The hidden classes are set to zero matrices, effectively removing them from observation while maintaining the underlying stochastic process.
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D_list (List[numpy.ndarray]) – List of arrival marking matrices
types (int | List[int] | numpy.ndarray) – Indices of classes to hide. Can be single int or list of ints. 0-indexed (class 1 is index 0)
- Returns:
Tuple of (D0_hidden, D_list_hidden) where specified classes are zero
- Return type:
Example
mmap_hide(D0, [D1, D2, D3], types=[1]) hides class 2 (index 1)
- aph2_assemble(l1, l2, p1)[source]
Build the APH(2) with the given parameters. Mirrors aph2_assemble.m.
- Parameters:
- Returns:
The APH(2) as [D0, D1].
- Return type:
- aph2_fitall(M1, M2, M3)[source]
Fit every APH(2) matching the given first three moments. Mirrors aph2_fitall.m.
Returns a list of 1 or 2 APH(2) fits. It is never empty: when no APH(2) solution is feasible the general APH fitter aph_fit(M1, M2, M3, 2) supplies a fallback, exactly as in the MATLAB and JAR sources.
- aph2_adjust(M1, M2, M3, method='simple')[source]
Find the APH(2)-feasible (M2, M3) closest to the given pair, holding M1 fixed. Mirrors the ‘simple’ branch of aph2_adjust.m [Telek and Heindl, 2002], which is the only branch aph2_fit uses.
- aph2_fit(M1, M2, M3)[source]
Fit an APH(2) to the first three moments, adjusting M2/M3 if they are infeasible. Mirrors aph2_fit.m.
M1 is always matched exactly: aph2_adjust never alters it, and the aph_fit fallback rescales its result to mean M1.
- Parameters:
- Returns:
The fitted APH(2) as [D0, D1].
- Return type:
- mmap_compress(D0, D_list, method='default', target_order=None)[source]
Compress an MMAP using various approximation methods.
Reduces the state space of an MMAP while preserving key statistical properties (moments, inter-arrival time distribution, etc.).
The MMAP is [D0] + D_list with D_list = [D1, D11, …, D1C], i.e. the aggregate D1 followed by the C per-class marking matrices, so C = len(D_list) - 1. This is the layout of mmap_normalize and of every caller (npfqn_traffic_merge, mmap_fj), which pass mmap[1:].
- Parameters:
D0 (numpy.ndarray) – Hidden transition matrix
D_list (List[numpy.ndarray]) – [D1, D11, …, D1C], the aggregate followed by the per-class marking matrices
method (str) – Compression method. Options: - “default”, “mixture”, “mixture.order1”: order-1 mixture fitting - “exponential”: Fit to single-state Poisson
target_order (int | None) – If given, skip compression when the MMAP order is already at most this value. There is no implicit size guard: the order-1 mixture is a lossy approximation with a contract (see _compress_mixture_order1), and callers rely on it holding regardless of the input order.
- Returns:
Tuple of (D0_compressed, D_list_compressed) in the same layout.
- Return type:
- mmap_exponential(lambda_rate, nclasses=None)[source]
Create an exponential MMAP (Poisson arrival process).
- Parameters:
lambda_rate (float | numpy.ndarray) – Arrival rate (scalar) or rate per class (vector)
nclasses (int | None) – Number of classes (if lambda_rate is scalar)
- Returns:
Tuple of (D0, D_list) representing exponential MMAP
- Return type:
- mmap_issym(mmap)[source]
Check if an MMAP contains symbolic elements.
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
- Returns:
True if any matrix in the MMAP contains sympy symbolic expressions
- Return type:
- mmap_isfeasible(mmap, tol=None)[source]
Check whether an MMAP is feasible up to the given tolerance.
Checks: - Elements are real (no imaginary parts) - D0 + D1 rows sum to zero (generator property) - Diagonal of D0 is negative - Off-diagonal of D0 is non-negative - All D1c matrices are non-negative - D1 = D11 + D12 + … + D1C
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
tol (float) – Tolerance for feasibility checks (default: 1e-6)
- Returns:
True if MMAP is feasible, False otherwise
- Return type:
- mmap_lambda(mmap)[source]
Compute the arrival rate of each class in an MMAP.
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
- Returns:
Array of arrival rates, one per class
- Return type:
- mmap_count_lambda(mmap)[source]
Compute the arrival rate of the counting process for each class.
The rate for class k is λ_k = π * D_k * e where π is the steady-state of the underlying CTMC.
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
- Returns:
Array of arrival rates, one per class
- Return type:
- mmap_pie(mmap)[source]
Compute the stationary probability of the DTMC embedded at restart instants after an arrival of each class.
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
- Returns:
Matrix of shape (m, n) where row c is the steady-state for class c
- Return type:
- mmap_pc(mmap)[source]
Compute the arrival probabilities of each class for the given MMAP.
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
- Returns:
Array of arrival probabilities, one per class
- Return type:
- mmap_embedded(mmap)[source]
Compute the embedded DTMC transition matrices for each class.
For class k, the embedded matrix is Pc_k = (-D0)^{-1} * D_{2+k}
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
- Returns:
List of embedded DTMC transition matrices, one per class
- Return type:
- mmap_sample(mmap, n_samples, pi=None, seed=None)[source]
Generate samples from a Marked MAP.
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
n_samples (int) – Number of random samples to collect
pi (numpy.ndarray) – Initial probability (if None, uses steady-state)
seed (int) – Random seed for reproducibility
- Returns:
T: Array of inter-arrival times
A: Array of class labels (1-indexed for MATLAB compatibility)
- Return type:
Tuple of (T, A) where
- mmap_rand(order, classes)[source]
Generate a random MMAP with given order and number of classes.
- Parameters:
- Returns:
List of matrices [D0, D1, D21, D22, …, D2K]
- Return type:
- mmap_timereverse(mmap)[source]
Compute the time-reversed MMAP.
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
- Returns:
Time-reversed MMAP
- Return type:
- mmap_sum(mmap, n)[source]
Create an MMAP representing the sum of n identical MMAPs (n-fold sum).
This creates an MMAP whose inter-arrival times are distributed as the sum of n inter-arrival times from the original MMAP.
- Parameters:
mmap (List[numpy.ndarray]) – Original MMAP
n (int) – Number of copies to sum
- Returns:
Summed MMAP
- Return type:
- mmap_super(mmap_a, mmap_b=None, opt='default')[source]
Superpose two or more MMAPs.
- Parameters:
mmap_a (List[numpy.ndarray]) – First MMAP (or list of MMAPs if mmap_b is None)
mmap_b (List[numpy.ndarray]) – Second MMAP (optional)
opt (str) – “default” - each class in MMAPa and MMAPb is distinct in result “match” - class c in both maps is mapped to class c in result
- Returns:
Superposed MMAP
- Return type:
- mmap_mixture(alpha, maps)[source]
Create a probabilistic mixture of MAPs.
Each MAP in the list is selected with probability alpha[i].
- Parameters:
alpha (numpy.ndarray) – Array of mixing probabilities
maps (List) – List of MAPs (each MAP is [D0, D1])
- Returns:
Mixed MMAP with len(maps) classes
- Return type:
- mmap_max(mmap_a, mmap_b, k)[source]
Create MMAP for the maximum of arrivals from two synchronized MMAPs.
This models a synchronization queue where arrivals from both sources must be paired before release.
- Parameters:
mmap_a (List[numpy.ndarray]) – First MMAP
mmap_b (List[numpy.ndarray]) – Second MMAP
k (int) – Length of synchronization queue
- Returns:
MMAP for the synchronized (maximum) process
- Return type:
- mmap_maps(mmap)[source]
Extract K MAPs, one for each class of the MMAP[K] process.
For class k, the MAP is {D0 + D1 - D_{2+k}, D_{2+k}}
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D21, D22, …, D2K]
- Returns:
List of MAPs, one per class
- Return type:
- mmap_count_mean(mmap, t)[source]
Compute the mean of the counting process at resolution t.
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
t (float) – Time period for counting
- Returns:
Array of mean counts, one per class
- Return type:
- mmap_count_var(mmap, t)[source]
Compute the variance of the counting process at resolution t.
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
t (float) – Time period for counting
- Returns:
Array of variances, one per class
- Return type:
- mmap_count_idc(mmap, t)[source]
Compute the per-class Index of Dispersion of Counts at resolution t.
IDC = Var[N(t)] / E[N(t)]
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
t (float) – Time period
- Returns:
Array of IDC values, one per class
- Return type:
- mmap_count_mcov(mmap, t)[source]
Compute the count covariance between each pair of classes at time scale t.
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
t (float) – Time scale
- Returns:
m x m covariance matrix
- Return type:
- mmap_idc(mmap)[source]
Compute the asymptotic Index of Dispersion of Counts for each class.
This is the limit of IDC(t) as t -> infinity.
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
- Returns:
Array of asymptotic IDC values, one per class
- Return type:
- mmap_sigma(mmap)[source]
Compute one-step class transition probabilities.
p_{i,j} = P(C_k = j | C_{k-1} = i)
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
- Returns:
C x C matrix of transition probabilities
- Return type:
- mmap_sigma2(mmap)[source]
Compute two-step class transition probabilities.
p_{i,j,h} = P(C_k = h | C_{k-1} = j, C_{k-2} = i)
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
- Returns:
C x C x C 3D array of transition probabilities
- Return type:
- mmap_forward_moment(mmap, orders, norm=True)[source]
Compute the theoretical forward moments of an MMAP.
Forward moments are E[X^k | previous arrival was class c].
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
orders (numpy.ndarray) – Array of moment orders to compute
norm (bool) – If True, normalize by class probability
- Returns:
Matrix of shape (C, len(orders)) where element (c, k) is the order-k forward moment for class c
- Return type:
- mmap_backward_moment(mmap, orders, norm=True)[source]
Compute the theoretical backward moments of an MMAP.
Backward moments are E[X^k | next arrival will be class c].
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
orders (numpy.ndarray) – Array of moment orders to compute
norm (bool) – If True, normalize by class probability
- Returns:
Matrix of shape (C, len(orders)) where element (c, k) is the order-k backward moment for class c
- Return type:
- mmap_cross_moment(mmap, k)[source]
Compute the k-th order moment of inter-arrival times between class pairs.
Computes E[X^k | previous = class i, next = class j] for all i, j.
- Parameters:
mmap (List[numpy.ndarray]) – List of matrices [D0, D1, D2, …, Dm]
k (int) – Order of the moment
- Returns:
C x C matrix where element (i, j) is the k-th moment for transitions i->j
- Return type:
- mmap_modulate(P, HT, MMAP)[source]
Modulate MMAPs in continuous time according to holding time distributions.
Creates an MMAP that switches between different MMAPs according to a continuous-time Markov modulated process.
- Parameters:
P (numpy.ndarray) – J x J transition probability matrix between states
HT (List) – List of phase-type distributions for holding time in each state
MMAP (List) – List of MMAPs, one for each state
- Returns:
Modulated MMAP
- Return type:
- ldqbd(Q0, Q1, Q2, options=None)[source]
Solve a level-dependent QBD process.
- Parameters:
Q0 (List[numpy.ndarray]) – List of upward transition matrices [Q0^(0), Q0^(1), …, Q0^(N-1)] Q0^(n) has shape (states_n, states_{n+1})
Q1 (List[numpy.ndarray]) – List of local transition matrices [Q1^(0), Q1^(1), …, Q1^(N)] Q1^(n) has shape (states_n, states_n)
Q2 (List[numpy.ndarray]) – List of downward transition matrices [Q2^(1), Q2^(2), …, Q2^(N)] Q2^(n) has shape (states_n, states_{n-1})
options (LdqbdOptions | None) – LdqbdOptions instance (uses defaults if None)
- Returns:
LdqbdResult containing rate matrices R and stationary distribution pi
- Return type:
- Algorithm:
Compute rate matrices backward using continued fraction recursion
Compute stationary distribution forward using R matrices
- class LdqbdResult(R, pi)[source]
Bases:
objectResult of LDQBD solver.
- R
List of rate matrices R^(1), R^(2), …, R^(N)
- Type:
List[numpy.ndarray]
- pi
Stationary distribution vector [pi_0, pi_1, …, pi_N]
- Type:
- R: List[numpy.ndarray]
- pi: numpy.ndarray
- class LdqbdOptions(epsilon=1e-10, max_iter=1000, verbose=False)[source]
Bases:
objectOptions for LDQBD solver.
- class MAPBMAP1Result(mean_queue_length, utilization, mean_response_time, throughput, pi, R, mean_batch_size)[source]
Bases:
objectResult of MAP/BMAP/1 queue analysis.
- pi: numpy.ndarray
Aggregated stationary probabilities [pi0, pi1, piStar]
- R: numpy.ndarray
R matrix
- solver_mam_map_bmap_1(C0, C1, D)[source]
Solve a MAP/BMAP/1 queue using GI/M/1-type matrix-analytic methods.
The MAP is specified by matrices (C0, C1) where: - C0: transitions without arrivals - C1: transitions triggering arrivals
The BMAP for service is specified by matrices {D0, D1, D2, …, DK} where: - D0: transitions without service completions - Dk: transitions triggering batch service of k customers (k >= 1)
The GI/M/1-type structure for MAP/BMAP/1 is: ```
B1 A0 0 0 … B2 A1 A0 0 …
- Q = B3 A2 A1 A0 …
…
- Where:
A0 = C1 otimes I_ms (MAP arrival, level +1) A1 = C0 otimes I_ms + I_ma otimes D0 (phase changes, level 0) A_{k+1} = I_ma otimes D_k (batch size k service, level -k)
- Parameters:
C0 (numpy.ndarray) – MAP matrix for transitions without arrivals
C1 (numpy.ndarray) – MAP matrix for arrivals
D (List[numpy.ndarray]) – BMAP service matrices as list [D0, D1, D2, …, DK]
- Returns:
MAPBMAP1Result with performance metrics
- Return type:
- class BMAPMAP1Result(mean_queue_length, utilization, mean_response_time, throughput, pi, G, mean_batch_size)[source]
Bases:
objectResult of BMAP/MAP/1 queue analysis.
- pi: numpy.ndarray
Aggregated stationary probabilities [pi0, pi1, piStar]
- G: numpy.ndarray
G matrix
- solver_mam_bmap_map_1(D, S0, S1)[source]
Solve a BMAP/MAP/1 queue using M/G/1-type matrix-analytic methods.
The BMAP is specified by matrices {D0, D1, D2, …, DK} where: - D0: transitions without arrivals - Dk: transitions triggering batch size k arrivals (k >= 1)
The MAP for service is specified by matrices (S0, S1) where: - S0: transitions without service completions - S1: transitions triggering service completions
The M/G/1-type structure for BMAP/MAP/1 is: ```
A0 = I_ma otimes S1 (service completion, level -1) A1 = D0 otimes I_ms + I_ma otimes S0 (phase changes, level 0) A_{k+1} = D_k otimes I_ms (batch arrival size k, level +k)
- Parameters:
D (List[numpy.ndarray]) – BMAP matrices as list [D0, D1, D2, …, DK]
S0 (numpy.ndarray) – MAP service matrix for transitions without service completions
S1 (numpy.ndarray) – MAP service matrix for service completions
- Returns:
BMAPMAP1Result with performance metrics
- Return type:
- class QBDResult(R, G=None, U=None, eta=None)[source]
Bases:
objectResult of QBD analysis.
- G: numpy.ndarray | None = None
- U: numpy.ndarray | None = None
- class QbdRapResult(levelProb, QN, R, G, U, spr, pqueue, pi0)[source]
Bases:
objectResult of the equilibrium analysis of a QBD with RAP components.
- levelProb
Marginal level probabilities, levels 0..numLevels
- Type:
- R
Rate matrix R = A0*inv(-U)
- Type:
- G
Matrix G solving A0*G^2 + A1*G + A2 = 0
- Type:
- U
Matrix U = A1 + A0*G
- Type:
- pqueue
(numLevels+1) x m array whose n-th row is the level vector pi_n
- Type:
- pi0
Level-0 vector pi_0, the boundary vector of Theorem 7
- Type:
- levelProb: numpy.ndarray
- pqueue: numpy.ndarray
- pi0: numpy.ndarray
- qbd_R(B, L, F, iter_max=100000, tol=1e-12)[source]
Compute QBD rate matrix R using successive substitutions.
- Solves the matrix quadratic equation:
R^2 * A_{-1} + R * A_0 + A_1 = 0
where A_{-1} = B, A_0 = L, A_1 = F.
- Parameters:
B (numpy.ndarray) – Backward transition block A_{-1}
L (numpy.ndarray) – Local transition block A_0
F (numpy.ndarray) – Forward transition block A_1
iter_max (int) – Maximum iterations (default: 100000)
tol (float) – Convergence tolerance (default: 1e-12)
- Returns:
Rate matrix R
- Return type:
References
Original MATLAB: matlab/src/api/mam/qbd_R.m
- qbd_R_logred(B, L, F, iter_max=1000, tol=1e-14)[source]
Compute QBD rate matrix R using logarithmic reduction.
Uses the logarithmic reduction algorithm which has quadratic convergence compared to linear convergence of successive substitutions.
- Parameters:
B (numpy.ndarray) – Backward transition block A_{-1}
L (numpy.ndarray) – Local transition block A_0
F (numpy.ndarray) – Forward transition block A_1
iter_max (int) – Maximum iterations (default: 1000)
tol (float) – Convergence tolerance (default: 1e-14)
- Returns:
Rate matrix R
- Return type:
References
Original MATLAB: matlab/src/api/mam/qbd_R_logred.m Latouche & Ramaswami, Ch. 8
- qbd_rg(B, L, F, method='logred', iter_max=1000, tol=1e-14)[source]
Compute both R and G matrices for a QBD process.
- G is the minimal non-negative solution to:
A_1 * G^2 + A_0 * G + A_{-1} = 0
- R is the minimal non-negative solution to:
R^2 * A_{-1} + R * A_0 + A_1 = 0
- Parameters:
B (numpy.ndarray) – Backward transition block A_{-1}
L (numpy.ndarray) – Local transition block A_0
F (numpy.ndarray) – Forward transition block A_1
method (str) – ‘logred’ or ‘successive’ (default: ‘logred’)
iter_max (int) – Maximum iterations
tol (float) – Convergence tolerance
- Returns:
QBDResult with R, G, U, and eta (caudal characteristic)
- Return type:
References
Original MATLAB: matlab/src/api/mam/qbd_rg.m
- qbd_blocks_mapmap1(D0_arr, D1_arr, D0_srv, D1_srv)[source]
Construct QBD blocks for a MAP/MAP/1 queue.
Builds the backward (B), local (L), and forward (F) transition blocks for the QBD representation of a MAP/MAP/1 queue.
- Parameters:
D0_arr (numpy.ndarray) – Arrival MAP D0 matrix
D1_arr (numpy.ndarray) – Arrival MAP D1 matrix
D0_srv (numpy.ndarray) – Service MAP D0 matrix
D1_srv (numpy.ndarray) – Service MAP D1 matrix
- Returns:
Tuple of (B, L, F) QBD blocks
- Return type:
References
Original MATLAB: matlab/src/api/mam/qbd_mapmap1.m
- qbd_bmapbmap1(MAPa, pbatcha, MAPs)[source]
Compute QBD blocks for a BMAP/BMAP/1 queue.
Constructs the QBD (Quasi-Birth-Death) transition blocks for a BMAP/BMAP/1 queue with batch arrivals.
- Parameters:
MAPa (Tuple[numpy.ndarray, numpy.ndarray]) – Arrival process MAP as (D0, D1)
pbatcha (numpy.ndarray) – Probability distribution of batch sizes (array of length maxbatch)
MAPs (Tuple[numpy.ndarray, numpy.ndarray]) – Service process MAP as (D0, D1)
- Returns:
A0: Local transition block A_1: Downward transition block A1_list: List of upward transition blocks for each batch size B0: Initial boundary local block B1_list: List of boundary upward blocks for each batch size
- Return type:
Tuple of (A0, A_1, A1_list, B0, B1_list) where
References
Original MATLAB: matlab/src/api/mam/qbd_bmapbmap1.m
- qbd_mapmap1(MAPa, MAPs, util=None)[source]
Analyze a MAP/MAP/1 queue using QBD methods.
Solves a MAP/MAP/1 queue using Quasi-Birth-Death process methods, computing throughput, queue length, utilization, and other metrics.
- Parameters:
MAPa (Tuple[numpy.ndarray, numpy.ndarray]) – Arrival process MAP as (D0, D1)
MAPs (Tuple[numpy.ndarray, numpy.ndarray]) – Service process MAP as (D0, D1)
util (float | None) – Optional target utilization to scale service rate
- Returns:
Tuple of (XN, QN, UN, pqueue, R, eta, G, A_1, A0, A1, U, MAPs_scaled) where:
XN: System throughput QN: Mean queue length UN: Utilization pqueue: Queue length distribution R: Rate matrix R eta: Caudal characteristic (spectral radius of R) G: Rate matrix G A_1: Downward transition block A0: Local transition block A1: Upward transition block U: Matrix U MAPs_scaled: Scaled service process
- Return type:
Tuple[float, float, float, numpy.ndarray, numpy.ndarray, float | None, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, Tuple[numpy.ndarray, numpy.ndarray]]
References
Original MATLAB: matlab/src/api/mam/qbd_mapmap1.m
- qbd_rap(A0, A1, A2, B0=None, B1=None, numLevels=20)[source]
Equilibrium analysis of a Quasi-Birth-and-Death process with Rational Arrival Process (RAP) components.
The process is specified directly by its level-independent blocks (A0,A1,A2) and its boundary blocks (B0,B1), where A0 drives level increases, A2 drives level decreases and A1 the within-level evolution. Unlike a Markovian QBD the blocks need not be nonnegative: they are only required to be conservative, (A0+A1+A2)*e = 0, and to define a genuine RAP through the prediction-process interpretation. This makes qbd_rap strictly more general than qbd_raprap1, which builds a product-space QBD from two INDEPENDENT RAPs; here the arrival process and the sequence of service times may be driven from a shared phase space and therefore be cross-correlated.
This is the block-level core of the RAP QBD family. qbd_raprap1 is the thin wrapper over it that builds the product-space blocks of two independent RAPs; callers with a coupled model must call qbd_rap directly because no product form exists to factor out.
- Algorithm (Theorem 7 of the reference):
Solve A0*G^2 + A1*G + A2 = 0 for G.
U = A1 + A0*G.
R = A0*inv(-U).
Find the row vector pihat0 with pihat0*(B1 + R*A2) = 0, pihat0*e = 1.
pi0 = K*pihat0 with K chosen so that pi0*inv(I-R)*e = 1.
pi_n = pi0*R^n, and the marginal level probability is pi_n*e.
The process is positive recurrent iff Sp(R) < 1 and step 4 has a solution.
Computation of G: the blocks are not nonnegative, so the probabilistic iterations used for Markovian QBDs (logarithmic reduction, cyclic reduction) carry no convergence guarantee here, and the paper explicitly leaves the general case open (“The issue of justifying algorithms for the evaluation of the matrix G for such processes has not been undertaken”, Section 6). See qbd_rap_g: the rank-one closed form is used when it applies, otherwise functional iteration followed by Newton’s method, and an unconverged G is never returned.
References
N. G. Bean and B. F. Nielsen, “Quasi-Birth-and-Death Processes with Rational Arrival Process Components”, Stochastic Models, 26(3), 2010, pp. 309-334 (DTU technical report IMM-2007-20). The argument rests on the prediction-process interpretation of a RAP due to Asmussen and Bladt, which is what allows a QBD argument to be carried over to matrices that are not nonnegative; the same prediction process underlies the conditional-vector RAP sampler in RAP.sample.
Original MATLAB: matlab/src/api/mam/qbd_rap.m
- Parameters:
A0 (numpy.ndarray) – Level-up block (m x m)
A1 (numpy.ndarray) – Local block (m x m)
A2 (numpy.ndarray) – Level-down block (m x m)
B0 (numpy.ndarray | None) – Boundary level-up block, defaults to A0
B1 (numpy.ndarray | None) – Boundary local block, defaults to A1
numLevels (int) – Highest level reported, default 20
- Returns:
QbdRapResult with levelProb, QN, R, G, U, spr, pqueue and pi0
- Raises:
ValueError – if the blocks are not conservative, if the process is not positive recurrent, or if G cannot be computed
- Return type:
- qbd_rap_g(A0, A1, A2, block_scale)[source]
Solve A0*G^2 + A1*G + A2 = 0 for the matrix G.
Uses the exact rank-one closed form when A2 has rank one, and otherwise natural functional iteration as a warm start followed by Newton’s method on the Sylvester-form Jacobian. Never returns an unconverged iterate.
- Parameters:
A0 (numpy.ndarray) – Level-up block
A1 (numpy.ndarray) – Local block
A2 (numpy.ndarray) – Level-down block
block_scale (float) – Scale of the blocks, used to set the residual tolerance
- Returns:
The matrix G
- Raises:
ValueError – if G cannot be computed to roundoff level
- Return type:
- qbd_raprap1(RAPa, RAPs, util=None)[source]
Analyze a RAP/RAP/1 queue using QBD methods.
Solves a RAP/RAP/1 queue (Rational Arrival Process) using QBD methods, computing throughput, queue length, utilization, and other metrics.
References
N. G. Bean and B. F. Nielsen, “Quasi-Birth-and-Death Processes with Rational Arrival Process Components”, Stochastic Models, 26(3), 2010, pp. 309-334. The analysis rests on the prediction-process interpretation of a RAP due to Asmussen and Bladt, which is what allows a QBD argument to be carried over to matrices that are not nonnegative. The same prediction process underlies the conditional-vector RAP sampler in RAP.sample.
- Parameters:
RAPa (Tuple[numpy.ndarray, numpy.ndarray]) – Arrival process RAP as (H0, H1)
RAPs (Tuple[numpy.ndarray, numpy.ndarray]) – Service process RAP as (H0, H1)
util (float | None) – Optional target utilization to scale service rate
- Returns:
XN: System throughput QN: Mean queue length UN: Utilization pqueue: Queue length distribution R: Rate matrix R eta: Caudal characteristic G: Rate matrix G B: Backward transition block L: Local transition block F: Forward transition block
- Return type:
Tuple of (XN, QN, UN, pqueue, R, eta, G, B, L, F) where
References
Original MATLAB: matlab/src/api/mam/qbd_raprap1.m
- qbd_setupdelayoff(lambda_val, mu, alpharate, alphascv, betarate, betascv)[source]
Analyze queue with setup delay and turn-off phases.
Performs queue-length analysis for a queueing system with setup delay (warm-up) and turn-off periods using QBD methods.
The system operates as follows: 1. When empty and job arrives, server enters setup phase 2. After setup, server becomes active and serves jobs 3. When queue empties, server enters turn-off phase 4. After turn-off, server becomes idle
- Parameters:
- Returns:
Average queue length QN
- Return type:
References
Original MATLAB: matlab/src/api/mam/qbd_setupdelayoff.m
- qbd_depproc_etaqa(MAPa, MAPs, n)[source]
Construct MAP departure process for MAP/MAP/1-FCFS via ETAQA truncation.
Builds a Markovian Arrival Process (MAP) approximation of the departure process from a single-server FCFS queue with MAP arrival process and MAP service process. The QBD is truncated at level n using ETAQA boundary corrections.
- Parameters:
MAPa – Arrival MAP as list [D0, D1] of numpy arrays.
MAPs – Service MAP as list [D0, D1] of numpy arrays.
n – Truncation level (number of QBD levels beyond level 0).
- Returns:
List [D0, D1] representing the departure MAP, where D0 and D1 are numpy arrays of size (n+1)*lvlsz x (n+1)*lvlsz.
- qbd_depproc_etaqa_ps(MAPa, MAPs, n)[source]
Construct MAP departure process for MAP/MAP/1-PS via ETAQA truncation.
Same as qbd_depproc_etaqa but for Processor Sharing (PS) discipline. Under PS, when j customers are present, each is served at rate mu/j. This leads to rate-dependent service completion splitting in D0 and D1.
- Parameters:
MAPa – Arrival MAP as list [D0, D1] of numpy arrays.
MAPs – Service MAP as list [D0, D1] of numpy arrays.
n – Truncation level (number of QBD levels beyond level 0).
- Returns:
List [D0, D1] representing the departure MAP, where D0 and D1 are numpy arrays of size (n+1)*lvlsz x (n+1)*lvlsz.
- qbd_depproc_jointmom(MAPa, MAPs, iset)[source]
Compute joint moments E[X_0^i * X_1^j] of consecutive inter-departure times.
Uses matrix-analytic methods on the QBD representation of a MAP/MAP/1 queue to compute joint factorial moments of pairs of consecutive inter-departure times.
- Parameters:
MAPa – Arrival MAP as list [D0, D1] of numpy arrays.
MAPs – Service MAP as list [D0, D1] of numpy arrays.
iset – Array of shape (K, 2) where each row [i, j] specifies the moment orders for E[X_0^i * X_1^j].
- Returns:
1D numpy array of length K with the computed joint moments.
- map_ccdf_derivative(MAP, i)[source]
Compute derivative at zero of a MAP’s complementary CDF.
Calculates the i-th derivative at t=0 of the complementary cumulative distribution function (CCDF) of the inter-arrival time distribution.
Formula: ν_i = π_e * D_0^i * e
where π_e is the embedded stationary vector and e is the column vector of ones.
- Parameters:
MAP (List[numpy.ndarray]) – Markovian Arrival Process as [D0, D1]
i (int) – Order of the derivative
- Returns:
Value of the i-th derivative at zero
- Return type:
References
Original MATLAB: matlab/src/api/mam/map_ccdf_derivative.m A. Horvath et al., “A Joint Moments Based Analysis of Networks of MAP/MAP/1 Queues”
- map_jointpdf_derivative(MAP, iset)[source]
Compute partial derivative at zero of a MAP’s joint PDF.
Calculates the partial derivative at t=0 of the joint probability density function of consecutive inter-arrival times.
For index set {i_1, i_2, …, i_k}: γ = π_e * D_0^{i_1} * D_1 * D_0^{i_2} * D_1 * … * D_0^{i_k} * D_1 * e
- Parameters:
MAP (List[numpy.ndarray]) – Markovian Arrival Process as [D0, D1]
iset (List[int] | numpy.ndarray) – Vector of indices defining the partial derivative orders
- Returns:
Value of the partial derivative at zero
- Return type:
References
Original MATLAB: matlab/src/api/mam/map_jointpdf_derivative.m A. Horvath et al., “A Joint Moments Based Analysis of Networks of MAP/MAP/1 Queues”
- map_factorial_moment(MAP, k)[source]
Compute the k-th factorial moment of a MAP.
The k-th factorial moment is computed using derivatives of the inter-arrival time distribution.
- Parameters:
MAP (List[numpy.ndarray]) – Markovian Arrival Process as [D0, D1]
k (int) – Order of the factorial moment
- Returns:
k-th factorial moment
- Return type:
References
Based on MAP moment formulas from matrix-analytic methods
- map_joint_moment(MAP, k, l)[source]
Compute the (k,l)-th joint moment of consecutive inter-arrival times.
E[X_n^k * X_{n+1}^l] for a MAP with inter-arrival times X_n.
- Parameters:
MAP (List[numpy.ndarray]) – Markovian Arrival Process as [D0, D1]
k (int) – Power for first inter-arrival time
l (int) – Power for second inter-arrival time
- Returns:
Joint moment E[X_n^k * X_{n+1}^l]
- Return type:
References
Based on joint moment formulas for MAPs
- map_m1ps_cdf_respt(C, D, mu, x, epsilon=1e-11, epsilon_prime=1e-10)[source]
Compute complementary sojourn time CDF for MAP/M/1-PS queue.
- Based on:
Masuyama, H., & Takine, T. (2003). Sojourn time distribution in a MAP/M/1 processor-sharing queue.
- Parameters:
C (numpy.ndarray | list) – MAP C matrix (transitions without arrivals).
D (numpy.ndarray | list) – MAP D matrix (transitions with arrivals).
mu (float) – Service rate (must be > 0).
x (numpy.ndarray | list) – Time points for CDF evaluation.
epsilon (float) – Queue length truncation parameter.
epsilon_prime (float) – Uniformization truncation parameter.
- Returns:
Complementary CDF values W_bar(x) = Pr[W > x] at each point in x.
- Return type:
Example
>>> # Exponential arrivals (Poisson process with rate lambda=0.5) >>> C = np.array([[-0.5]]) >>> D = np.array([[0.5]]) >>> mu = 1.0 >>> x = np.array([0.0, 0.5, 1.0, 2.0, 5.0]) >>> cdf = map_m1ps_cdf_respt(C, D, mu, x)
- map_compute_R(C, D, mu)[source]
Compute rate matrix R for MAP/M/1 queue.
- Computes the minimal nonnegative solution of the matrix equation:
D + R(C - mu*I) + mu*R^2 = 0
This matrix is used in the analysis of MAP/M/1 queues based on quasi-birth-death processes.
- Parameters:
C (numpy.ndarray | list) – M x M matrix governing MAP transitions without arrivals
D (numpy.ndarray | list) – M x M matrix governing MAP transitions with arrivals
mu (float) – Service rate (scalar)
- Returns:
M x M rate matrix (minimal nonnegative solution)
- Return type:
References
Original MATLAB: matlab/src/api/map/map_compute_R.m Masuyama, H., & Takine, T. (2003). Sojourn time distribution in a MAP/M/1 processor-sharing queue.
- map_m1ps_h_recursive(C, D, mu, N, K)[source]
Recursive computation of h_{n,k} coefficients for MAP/M/1-PS.
- The h_{n,k} vectors satisfy the recursion (Theorem 1 in paper):
h_{n,0} = e (vector of ones), for n = 0, 1, … h_{n,k+1} = 1/(theta+mu) * [n*mu/(n+1) * h_{n-1,k} + (theta*I + C) * h_{n,k}
D * h_{n+1,k}]
where h_{-1,k} = 0 for all k
- Parameters:
C (numpy.ndarray | list) – M x M matrix governing MAP transitions without arrivals
D (numpy.ndarray | list) – M x M matrix governing MAP transitions with arrivals
mu (float) – Service rate (scalar)
N (int) – Maximum value of n to compute (determines rows)
K (int) – Maximum value of k to compute (determines columns)
- Returns:
2D list h[n][k] of (M,1) arrays containing h_{n,k}
- Return type:
References
Original MATLAB: matlab/src/api/map/map_m1ps_h_recursive.m Masuyama, H., & Takine, T. (2003).
- map_m1ps_sojourn(C, D, mu, x, epsilon=1e-11, epsilon_prime=1e-10)[source]
Compute sojourn time distribution in MAP/M/1-PS queue.
Alias for map_m1ps_cdf_respt.
- Parameters:
C (numpy.ndarray | list) – MAP C matrix (transitions without arrivals)
D (numpy.ndarray | list) – MAP D matrix (transitions with arrivals)
mu (float) – Service rate (must be > 0)
x (numpy.ndarray | list) – Time points for CDF evaluation
epsilon (float) – Queue length truncation parameter
epsilon_prime (float) – Uniformization truncation parameter
- Returns:
Complementary CDF values W_bar(x) = Pr[W > x]
- Return type:
References
Original MATLAB: matlab/src/api/map/map_m1ps_sojourn.m
- mmdp_isfeasible(Q, R, tol=1e-10)[source]
Check if (Q, R) defines a valid MMDP.
Requirements: - Q must be a valid generator (square, row sums = 0, proper signs) - R must be diagonal with non-negative entries - Q and R must have compatible dimensions
- Parameters:
Q (numpy.ndarray) – Generator matrix (n x n)
R (numpy.ndarray) – Rate matrix (n x n diagonal) or rate vector (n,)
tol (float) – Numerical tolerance for validation
- Returns:
True if (Q, R) defines a valid MMDP, False otherwise
- Return type:
Examples
>>> Q = np.array([[-0.5, 0.5], [0.3, -0.3]]) >>> R = np.array([[2.0, 0], [0, 5.0]]) >>> mmdp_isfeasible(Q, R) True
Markov Chain API (line_solver.api.mc)
Markov Chain analysis algorithms.
Native Python implementations for continuous-time and discrete-time Markov chain analysis.
- Key algorithms:
ctmc_solve: CTMC steady-state distribution ctmc_transient: CTMC transient analysis ctmc_uniformization: Uniformization method for transient analysis ctmc_foxglynn: Fox-Glynn uniformization for transient analysis ctmc_gmres: Restarted GMRES with ILUT preconditioning ctmc_stochcomp: Stochastic complementation dtmc_solve: DTMC steady-state distribution
- ctmc_solve(Q, method=None)[source]
Solve for steady-state probabilities of a CTMC.
Computes the stationary distribution π by solving πQ = 0 with normalization constraint Σπ = 1.
Handles reducible CTMCs by decomposing into strongly connected components and solving each separately.
- Parameters:
Q (numpy.ndarray) – Infinitesimal generator matrix (row sums should be zero)
method (str | None) – ‘gmres’ or ‘direct’ to force a solution method; None or ‘default’ selects by size, GMRES above GMRES_MIN_STATES states
- Returns:
Steady-state probability distribution (1D array)
- Return type:
- ctmc_solve_reducible(Q, pin=None)[source]
Solve reducible CTMCs by converting to DTMC via uniformization.
Port of MATLAB ctmc_solve_reducible.m, which is a thin delegate to dtmc_solve_reducible(ctmc_randomization(Q), pin, tol=1e-12). The whole convention for a reducible chain therefore lives in dtmc_solve_reducible: the limiting vector of a chain with several closed communicating classes is NOT unique, and it is resolved by starting uniformly over the SCCs and propagating through the lumped limiting matrix (so, when every SCC is closed, each class carries equal weight).
This formerly delegated to ctmc_solve, which just returns whichever null vector the linear solver happens to land on – for two closed classes that is all the mass on the first, disagreeing with MATLAB and the JAR.
- Parameters:
Q (numpy.ndarray) – Infinitesimal generator matrix (possibly reducible)
pin (numpy.ndarray | None) – Initial probability vector, or None when not available
- Returns:
Steady-state probability vector
- Return type:
- ctmc_makeinfgen(Q)[source]
Convert a matrix into a valid infinitesimal generator for a CTMC.
An infinitesimal generator has: - Row sums equal to zero - Non-positive diagonal elements - Non-negative off-diagonal elements
- Parameters:
Q – Candidate infinitesimal generator matrix
- Returns:
Valid infinitesimal generator matrix with corrected diagonal
- ctmc_transient(Q, initial_dist, time_points, method='expm')[source]
Compute transient probabilities of a CTMC.
Calculates time-dependent state probabilities π(t) for specified time points using matrix exponential methods.
- Parameters:
Q (numpy.ndarray) – Infinitesimal generator matrix
initial_dist (numpy.ndarray) – Initial probability distribution π(0)
time_points (float | numpy.ndarray) – Array of time points to evaluate, or single time value
method (str) – ‘expm’ for matrix exponential, ‘ode’ for ODE solver
- Returns:
Transient probabilities at each time point. Shape: (len(time_points), n) if multiple times, (n,) if single time
- Return type:
- ctmc_timeaverage(pi0, Q, t, tol=1e-12, maxiter=100)[source]
Time-averaged transient distribution of a CTMC over [0, t] via uniformization.
Companion of the endpoint pi0*exp(Q*t); additionally returns the time average
piTimeAvg = pi0 * (1/t) * int_0^t exp(Q*tau) d(tau)
as well as the endpoint piExit = pi0*exp(Q*t), both from the same Jensen uniformization series. Used by the SolverENV state-vector analyzer (deterministic-sojourn option). Mirrors matlab ctmc_timeaverage.m.
- Returns:
(piTimeAvg, piExit) as 1D arrays.
- ctmc_uniformization(Q, lambda_rate=None)[source]
Uniformize CTMC generator matrix.
Converts CTMC to an equivalent uniformized discrete-time chain for numerical analysis and simulation purposes.
The uniformized DTMC has transition matrix P = I + Q/λ where λ is the uniformization rate (max exit rate).
- Parameters:
Q (numpy.ndarray) – Infinitesimal generator matrix
lambda_rate (float | None) – Uniformization rate (optional, auto-computed if None)
- Returns:
‘P’: Uniformized transition matrix
’lambda’: Uniformization rate
- Return type:
dict containing
- ctmc_foxglynn(pi0, Q, t, tol=1e-12, maxiter=-1)[source]
Transient distribution of a CTMC by Fox-Glynn uniformization.
- Parameters:
pi0 (numpy.ndarray) – Initial probability distribution
Q (numpy.ndarray) – Infinitesimal generator matrix
t (float) – Transient analysis period boundary [0,t]
tol (float) – Poisson tail-mass truncation tolerance
maxiter (int) – Maximum truncation depth; pass a nonpositive value to let the Fox-Glynn right truncation point size it
- Returns:
Transient probability vector at time t
- Return type:
- ctmc_foxglynn_weights(lam, tol=1e-12, maxiter=-1)[source]
Fox-Glynn truncation window and normalized Poisson weights.
Following Fox-Glynn, the weights are built by the two-sided recursion w[k-1] = w[k]*k/lam and w[k+1] = w[k]*lam/(k+1) anchored at the mode, so neither exp(-lam) nor lam^k/k! is ever evaluated and the overflow and underflow that limit the direct series cannot occur. Anchoring at w[mode] = 1 keeps the extreme weights near tol, far above the denormal threshold, making Fox and Glynn’s rescaling of the mode weight unnecessary here. The normalizing sum is accumulated in increasing order of magnitude.
- Parameters:
- Returns:
Tuple of (left truncation point, right truncation point, weights)
- Return type:
Tuple[int, int, numpy.ndarray]
- ctmc_gmres(A, b, tol=None, restart=None, maxit=None, x0=None)[source]
Solve the sparse nonsymmetric system A*x = b by restarted GMRES.
- Parameters:
A – Coefficient matrix, dense or sparse. Converted to CSC internally.
b – Right-hand side
tol (float | None) – Relative residual tolerance (default 1e-12)
restart (int | None) – Krylov subspace dimension between restarts (default min(n, 50))
maxit (int | None) – Maximum number of restart cycles (default ceil(n/restart))
x0 – Initial guess (default uniform 1/n)
- Returns:
(x, flag, relres, iter), where flag follows the MATLAB gmres convention: 0 converged, 1 iteration limit reached, 2 preconditioner ill-conditioned, 3 stagnation or breakdown. Callers must check flag and fall back to the direct solve when it is nonzero.
- Return type:
Tuple[numpy.ndarray, int, float, int]
- ctmc_gmres_multi(A, B, tol=None, restart=None, maxit=None)[source]
Solve A*X = B for every column of B, reusing one ILUT factorization across all of them and starting each column from the previous solution.
This is the shape of the stochastic complement, whose right-hand side is a whole block of the generator: refactorizing per column would cost more than the direct solve it replaces.
- Parameters:
- Returns:
(X, flag). flag is 0 only if every column converged; on any other value X is None and the caller must fall back to the direct solve. Returning a partial block would leave that fallback ambiguous.
- ctmc_randomization(Q, initial_dist, time_points, precision=1e-10)[source]
Compute CTMC transient probabilities using randomization.
Uses Jensen’s randomization method (uniformization) to compute transient probabilities by converting the CTMC to a uniformized DTMC.
This method is numerically stable and avoids matrix exponentials.
- Parameters:
Q (numpy.ndarray) – Infinitesimal generator matrix
initial_dist (numpy.ndarray) – Initial probability distribution
time_points (numpy.ndarray) – Array of time points to evaluate
precision (float) – Numerical precision for truncation (Poisson tail)
- Returns:
Transient probabilities at each time point
- Return type:
- ctmc_stochcomp(Q, I=None)[source]
Compute stochastic complement of CTMC.
Reduces the CTMC by eliminating states not in I while preserving the steady-state distribution restricted to the kept states.
- Parameters:
Q (numpy.ndarray) – Infinitesimal generator matrix
I (numpy.ndarray | None) – States to retain (array of indices). If None, defaults to 0..ceil(n/2)-1 (matching JAR/MATLAB).
- Returns:
‘S’: Stochastic complement (reduced generator)
’Q11’: Submatrix for kept states
’Q12’: Transitions from kept to eliminated
’Q21’: Transitions from eliminated to kept
’Q22’: Submatrix for eliminated states
’T’: Transient contribution matrix
- Return type:
dict containing
- ctmc_timereverse(Q, pi=None)[source]
Compute time-reversed CTMC generator.
The time-reversed generator Q* has elements: Q*_{ij} = π_j * Q_{ji} / π_i
- Parameters:
Q (numpy.ndarray) – Original infinitesimal generator matrix
pi (numpy.ndarray | None) – Steady-state distribution (optional, computed if None)
- Returns:
Time-reversed generator matrix
- Return type:
- ctmc_rand(n, density=0.3, max_rate=10.0)[source]
Generate random CTMC generator matrix.
- Parameters:
- Returns:
Random infinitesimal generator matrix
- Return type:
- ctmc_simulate(Q, initial_state, max_time, max_events=10000, seed=None)[source]
Simulate CTMC sample path using Gillespie algorithm.
Generates a realization of the continuous-time Markov chain using the next-reaction method.
- Parameters:
Q (numpy.ndarray) – Infinitesimal generator matrix
initial_state (int) – Starting state (integer index)
max_time (float) – Maximum simulation time
max_events (int) – Maximum number of transitions (default: 10000)
seed (int | None) – Random seed for reproducibility (optional)
- Returns:
‘states’: Array of visited states
’times’: Array of transition times
’sojourn_times’: Time spent in each state
- Return type:
dict with
- ctmc_isfeasible(Q, tolerance=1e-10)[source]
Check if matrix is a valid CTMC infinitesimal generator.
Validates: - Off-diagonal elements are non-negative - Row sums are zero - Diagonal elements are non-positive
- Parameters:
Q (numpy.ndarray) – Candidate generator matrix
tolerance (float) – Numerical tolerance (default: 1e-10)
- Returns:
True if matrix is valid CTMC generator
- Return type:
- ctmc_ssg(sn, options=None)[source]
Generate complete CTMC state space for a queueing network.
Creates all possible network states including those not reachable from the initial state. For open classes, a cutoff parameter limits the maximum population to keep state space finite.
The state space is aggregated to show per-station-class job counts.
- Parameters:
- Returns:
state_space: Complete state space matrix (rows=states, cols=state components)
state_space_aggr: Aggregated state space (rows=states, cols=stations*classes)
state_space_hashed: Hashed state indices for lookup
node_state_space: Dictionary of per-node state spaces
sn: Updated network structure with space field populated
- Return type:
CtmcSsgResult containing
References
MATLAB: matlab/src/api/mc/ctmc_ssg.m
- ctmc_ssg_reachability(sn, options=None)[source]
Generate reachable CTMC state space for a queueing network.
Creates only the states reachable from the initial state through valid transitions. This is more efficient than ctmc_ssg for networks with constrained reachability.
- Parameters:
- Returns:
state_space: Reachable state space matrix
state_space_aggr: Aggregated state space (per station-class)
state_space_hashed: Hashed state indices
node_state_space: Dictionary of per-node state spaces
sn: Updated network structure
- Return type:
CtmcSsgResult containing
References
MATLAB: matlab/src/api/mc/ctmc_ssg_reachability.m
- ctmc_memory_gate(log_nstates, force=False, verbose=False, safety_fraction=0.6)[source]
Hardware-aware, profiling-calibrated CTMC memory pre-gate.
Decides whether a CTMC steady-state solve of a state space of worst-case size exp(log_nstates) is safe on the current host. The budget is a fraction of available memory; the per-state cost is calibrated by profiling sparse LU factorization and cached per machine.
- Parameters:
- Returns:
ok (bool): True if solve is safe, False if memory exceeded (and force=False)
msg (str): Status or warning message
- Return type:
Tuple (ok, msg) where
- class CtmcSsgResult(state_space, state_space_aggr, state_space_hashed, node_state_space, sn)[source]
Bases:
objectResult from CTMC state space generation.
- state_space: numpy.ndarray
- state_space_aggr: numpy.ndarray
- state_space_hashed: numpy.ndarray
- node_state_space: Dict[int, numpy.ndarray]
- dtmc_solve(P)[source]
Solve for steady-state probabilities of a DTMC.
Computes the stationary distribution π by solving π(P - I) = 0 with normalization constraint Σπ = 1.
This leverages the CTMC solver by treating (P - I) as an infinitesimal generator.
- Parameters:
P (numpy.ndarray) – Transition probability matrix (row stochastic)
- Returns:
Steady-state probability distribution (1D array)
- Return type:
- dtmc_solve_reducible(P, pin=None)[source]
Solve reducible DTMCs with transient states.
Handles DTMCs with multiple recurrent classes and transient states by: 1. Decomposing into strongly connected components (SCCs) 2. Identifying recurrent vs transient SCCs 3. Computing limiting distribution considering absorption from transient states
For a reducible DTMC with a single transient SCC, this computes the limiting distribution when starting from the transient states (e.g., class switching networks where jobs start in a transient class).
- Parameters:
P (numpy.ndarray) – Transition probability matrix (possibly reducible)
pin (numpy.ndarray) – Initial probability vector (optional)
- Returns:
Steady-state probability vector
- Return type:
- dtmc_makestochastic(A)[source]
Convert matrix to row-stochastic transition matrix.
Normalizes each row to sum to 1. Rows with zero sum are replaced with uniform distribution.
- Parameters:
A (numpy.ndarray) – Input matrix to normalize
- Returns:
Row-stochastic matrix
- Return type:
- dtmc_isfeasible(P, tolerance=1e-10)[source]
Check if matrix is a valid DTMC transition matrix.
Validates: - All elements are non-negative - All row sums equal 1
- Parameters:
P (numpy.ndarray) – Candidate transition matrix
tolerance (float) – Numerical tolerance (default: 1e-10)
- Returns:
True if matrix is valid DTMC transition matrix
- Return type:
- dtmc_simulate(P, initial_state, num_steps, seed=None)[source]
Simulate DTMC sample path.
Generates a realization of the discrete-time Markov chain for a specified number of steps.
- Parameters:
P (numpy.ndarray) – Transition probability matrix
initial_state (int) – Starting state index
num_steps (int) – Number of simulation steps
- Returns:
Array of visited states (length num_steps + 1)
- Return type:
- dtmc_rand(n, density=0.5)[source]
Generate random DTMC transition matrix.
- Parameters:
- Returns:
Random transition probability matrix
- Return type:
- dtmc_timereverse(P, pi=None)[source]
Compute time-reversed DTMC transition matrix.
The time-reversed chain has transition probabilities: P*_{ij} = π_j * P_{ji} / π_i
- Parameters:
P (numpy.ndarray) – Original transition matrix
pi (numpy.ndarray | None) – Steady-state distribution (optional, computed if None)
- Returns:
Time-reversed transition matrix
- Return type:
- dtmc_stochcomp(P, keep_states, eliminate_states=None)[source]
Compute stochastic complement of DTMC.
Reduces the DTMC by eliminating specified states while preserving the steady-state distribution restricted to the kept states.
- Parameters:
P (numpy.ndarray) – Transition probability matrix
keep_states (numpy.ndarray) – States to retain in reduced model
eliminate_states (numpy.ndarray | None) – States to eliminate (optional, inferred if None)
- Returns:
Reduced transition matrix (stochastic complement)
- Return type:
- dtmc_transient(P, initial_dist, steps)[source]
Compute transient probabilities of a DTMC.
Calculates π(n) = π(0) * P^n for each step from 0 to steps.
- Parameters:
P (numpy.ndarray) – Transition probability matrix
initial_dist (numpy.ndarray) – Initial probability distribution π(0)
steps (int) – Number of time steps
- Returns:
Array of shape (steps+1, n) with transient probabilities
- Return type:
- dtmc_hitting_time(P, target_states)[source]
Compute mean hitting times to target states.
Calculates the expected number of steps to reach any target state from each starting state.
- Parameters:
P (numpy.ndarray) – Transition probability matrix
target_states (numpy.ndarray) – Array of target state indices
- Returns:
Array of mean hitting times from each state
- Return type:
- class CourtoisResult(p, Qperm, Qdec, eps, epsMAX, P, B, q)[source]
Bases:
objectResult of Courtois decomposition.
- Qperm: numpy.ndarray
- Qdec: numpy.ndarray
- class KMSResult(p, p_1, Qperm, eps, epsMAX, pcourt)[source]
Bases:
objectResult of KMS aggregation-disaggregation.
- p_1: numpy.ndarray
- Qperm: numpy.ndarray
- pcourt: numpy.ndarray
- class TakahashiResult(p, p_1, pcourt, Qperm, eps, epsMAX)[source]
Bases:
objectResult of Takahashi aggregation-disaggregation.
- p_1: numpy.ndarray
- pcourt: numpy.ndarray
- Qperm: numpy.ndarray
- ctmc_courtois(Q, MS, q=None)[source]
Courtois decomposition for near-completely decomposable CTMCs.
Decomposes a large CTMC into macrostates and computes approximate steady-state probabilities using hierarchical aggregation.
- Parameters:
Q (numpy.ndarray) – Infinitesimal generator matrix
MS (List[List[int]]) – List where MS[i] is the list of state indices in macrostate i
q (float | None) – Randomization coefficient (optional)
- Returns:
CourtoisResult with approximate solution and diagnostics
- Return type:
References
Original MATLAB: matlab/src/api/mc/ctmc_courtois.m Courtois, “Decomposability: Queueing and Computer System Applications”, 1977
- ctmc_kms(Q, MS, numSteps=10)[source]
Koury-McAllister-Stewart aggregation-disaggregation method.
Iteratively refines the Courtois decomposition solution using aggregation and disaggregation steps.
- Parameters:
Q (numpy.ndarray) – Infinitesimal generator matrix
MS (List[List[int]]) – List where MS[i] is the list of state indices in macrostate i
numSteps (int) – Number of iterative steps (default: 10)
- Returns:
KMSResult with refined solution
- Return type:
References
Original MATLAB: matlab/src/api/mc/ctmc_kms.m Koury, McAllister, Stewart, “Iterative Methods for Computing Stationary Distributions of Nearly Completely Decomposable Markov Chains”, 1984
- ctmc_takahashi(Q, MS, numSteps=10)[source]
Takahashi’s aggregation-disaggregation method.
Iteratively refines the Courtois decomposition solution using a different aggregation-disaggregation scheme.
- Parameters:
Q (numpy.ndarray) – Infinitesimal generator matrix
MS (List[List[int]]) – List where MS[i] is the list of state indices in macrostate i
numSteps (int) – Number of iterative steps (default: 10)
- Returns:
TakahashiResult with refined solution
- Return type:
References
Original MATLAB: matlab/src/api/mc/ctmc_takahashi.m Takahashi, “A Lumping Method for Numerical Calculations of Stationary Distributions of Markov Chains”, 1975
Queueing Systems (line_solver.api.qsys)
Native Python implementations for queueing system analysis.
This module provides pure Python/NumPy implementations for analyzing single queueing systems, including basic queues (M/M/1, M/M/k, M/G/1), G/G/1 approximations, MAP-based queues, and scheduling disciplines.
- Key algorithms:
Basic queues: qsys_mm1, qsys_mmk, qsys_mg1, qsys_gm1, qsys_mminf, qsys_mginf G/G/1 approximations: Allen-Cunneen, Kingman, Marchal, Whitt, Heyman, etc. G/G/k approximations: qsys_gigk_approx MAP/D queues: qsys_mapdc, qsys_mapd1 MAP/PH queues: qsys_phph1, qsys_mapph1, qsys_mapm1, qsys_mapmc, qsys_mapmap1 Scheduling: qsys_mg1_prio, qsys_mg1_srpt, qsys_mg1_fb, etc. Loss systems: qsys_mm1k_loss, qsys_mg1k_loss, qsys_mxm1 Discrete time (slotted): qsys_geogeo1, qsys_geoxgeo1
- qsys_mapdc(D0, D1, s, c, max_num_comp=1000, num_steps=1, verbose=0)[source]
Analyze MAP/D/c queue (MAP arrivals, deterministic service, c servers).
Uses Non-Skip-Free (NSF) Markov chain analysis embedding at deterministic service intervals. Multiple arrivals can occur per interval.
- Parameters:
D0 (numpy.ndarray) – MAP hidden transition matrix (n x n).
D1 (numpy.ndarray) – MAP arrival transition matrix (n x n).
s (float) – Deterministic service time (positive scalar).
c (int) – Number of servers.
max_num_comp (int) – Maximum number of queue length components (default 1000).
num_steps (int) – Number of waiting time distribution points per interval (default 1).
verbose (int) – Verbosity level (default 0).
- Returns:
- Performance metrics including:
mean_queue_length: Mean number of customers in system
mean_waiting_time: Mean waiting time in queue
mean_sojourn_time: Mean sojourn time (waiting + service)
utilization: Server utilization (per server)
queue_length_dist: Queue length distribution P(Q=n)
waiting_time_dist: Waiting time CDF at discrete points
analyzer: Analyzer identifier
- Return type:
- qsys_mapd1(D0, D1, s, max_num_comp=1000, num_steps=1)[source]
Analyze MAP/D/1 queue (single-server convenience function).
- Parameters:
D0 (numpy.ndarray) – MAP hidden transition matrix.
D1 (numpy.ndarray) – MAP arrival transition matrix.
s (float) – Deterministic service time.
max_num_comp (int) – Maximum number of queue length components.
num_steps (int) – Number of waiting time points per interval.
- Returns:
Performance metrics (see qsys_mapdc).
- Return type:
- qsys_mdc_crommelin(lambda_arr, s, c, truncation=-1)[source]
Solve M/D/c via Crommelin’s embedded DTMC.
- Parameters:
- Returns:
mean_queue_length: E[N] (number in system) mean_waiting_queue: Lq = E[(N-c)+] mean_waiting_time: Wq = Lq / lambda mean_sojourn_time: W = Wq + s utilization: rho = lambda * s / c
- Return type:
dict with keys
- qsys_dmc(lambda_arr, mu, c, truncation=-1, quad_steps=200)[source]
Solve D/M/c via embedded DTMC at arrival epochs.
- Parameters:
- Returns:
dict with mean_queue_length, mean_waiting_queue, mean_waiting_time, mean_sojourn_time, utilization.
- Return type:
- qsys_phmc(alpha, T, mu, c, max_iter=50000, tol=1e-14)[source]
Solve PH/M/c via matrix-geometric.
- Parameters:
- Returns:
dict with mean_queue_length, mean_waiting_queue, mean_waiting_time, mean_sojourn_time, utilization.
- Return type:
- qsys_geogeo1(a, s, convention=LAS_DA)[source]
Analyze a discrete-time Geo/Geo/1 queue.
In each slot an arrival occurs with probability
aand, if the server is engaged, a service completion occurs with probabilitys, independently of everything else. The system content at slot boundaries is a discrete birth-death chain with a geometric stationary distribution.The two conventions are not two systems. They are one system, Daduna’s LA-rule (events at the end of their slot) with the D/A-rule (departure resolved before arrival), observed at two instants. With
X(t+1) = X(t) - D(t) + A(t),LAS_DAis the law ofX, taken after both events, andEASis the law ofY(t) = X(t) - D(t), taken after the departure and before the arrival. They are one departure apart, so the mean contents differ by exactlyaand the sojourn times by one slot; the queueing delay is the same under both.- Parameters:
- Returns:
convention: epoch used
arrivalProb, serviceProb: the inputs
utilization: a/s
throughput: a
emptyProb: probability the system is empty at the epoch
ratio: geometric decay ratio r = a(1-s)/(s(1-a))
meanQueueLength, meanWaitingQueue
meanSojournTime, meanWaitingTime, meanServiceTime
pmf: callable n -> stationary probability of n jobs
analyzer: ‘qsys_geogeo1’
- Return type:
dict with keys
Example
>>> r = qsys_geogeo1(0.2, 0.5) >>> print(f"{r['meanSojournTime']:.4f}") 2.6667
- qsys_geoxgeo1(a, beta, s, convention=LAS_DA)[source]
Analyze a discrete-time Geo^X/Geo/1 queue with geometric batch sizes.
In each slot a batch arrives with probability
a; the batch size is geometric on {1,2,…} with parameterbeta, soE[X] = 1/betaandE[X(X-1)] = 2(1-beta)/beta**2. Stability requireslambda = a*E[X] < s. Atbeta == 1the batch is always a single job and the result equalsqsys_geogeo1().- Parameters:
- Returns:
dict, see
qsys_geoxgeo1_moments()- Return type:
Example
>>> r = qsys_geoxgeo1(0.1, 0.5, 0.9) >>> print(f"{r['arrivalRate']:.4f}") 0.2000
- qsys_geoxgeo1_moments(a, batch_mean, batch_second_factorial, s, convention=LAS_DA)[source]
Analyze a discrete-time Geo^X/Geo/1 queue for an arbitrary batch law.
The batch enters the solution only through its first two factorial moments, so specifying those is fully general. With
A(z) = 1-a+a*X(z)the pgf of the number of jobs arriving in one slot, the slot-boundary content obeysX(t+1) = X(t) - D(t) + A(t)with the departure resolved first, giving:P(z) = p0 s (z-1) A(z) / ( z - A(z)(s+(1-s)z) ), p0 = 1 - lambda/s E[N] = lambda + ( a E[X(X-1)]/2 + lambda(1-s) ) / (s - lambda)
- Parameters:
a (float) – Per-slot probability that a batch arrives, 0 < a <= 1
batch_mean (float) – E[X], at least 1 since an arriving batch carries a job
batch_second_factorial (float) – E[X(X-1)], non-negative and at least
batch_mean**2 - batch_means (float) – Per-slot service completion probability, 0 < s <= 1
convention (str) – Observation epoch, ‘LAS_DA’ (default) or ‘EAS’
- Returns:
convention, batchArrivalProb, batchMean, batchSecondFactorialMoment, serviceProb
arrivalRate, throughput: lambda = a*E[X]
utilization: lambda/s
boundaryEmptyProb: 1 - lambda/s, the empty probability AT THE SLOT BOUNDARY under both conventions
meanQueueLength, meanWaitingQueue
meanSojournTime, meanWaitingTime, meanServiceTime
pgf: callable (z, A_of_z) -> P(z), defined for 0 < z <= 1
analyzer: ‘qsys_geoxgeo1’
- Return type:
dict with keys
No pmf is returned: for a general batch law the stationary distribution has no elementary closed form, so only the generating function is exact.
- qsys_mm1(lambda_val, mu)[source]
Analyze M/M/1 queue (Poisson arrivals, exponential service).
- Parameters:
- Returns:
- Performance measures including:
L: Mean number in system
Lq: Mean number in queue
W: Mean response time (time in system)
Wq: Mean waiting time (time in queue)
rho: Utilization (lambda/mu)
- Return type:
Example
>>> result = qsys_mm1(0.5, 1.0) >>> print(f"Utilization: {result['rho']:.2f}") Utilization: 0.50
- qsys_mmk(lambda_val, mu, k)[source]
Analyze M/M/k queue (Poisson arrivals, k exponential servers).
- Parameters:
- Returns:
- Performance measures including:
L: Mean number in system
Lq: Mean number in queue
W: Mean response time
Wq: Mean waiting time
rho: Utilization per server (lambda/(k*mu))
P0: Probability of empty system
- Return type:
Example
>>> result = qsys_mmk(2.0, 1.0, 3) >>> print(f"Utilization: {result['rho']:.2f}") Utilization: 0.67
- qsys_mmck(lambda_val, mu, c, K)[source]
Exact closed-form analysis of an M/M/c/K queue (finite capacity K, c servers).
- Port of MATLAB qsys_mmck.m. Stationary distribution (truncated Erlang form):
a = lambda/mu, rho = a/c p_n = a^n/n! * p0 for 0 <= n <= c p_n = a^c/c! * rho^(n-c) * p0 for c <= n <= K
with p0 normalizing the (K+1)-point distribution.
- Parameters:
- Returns:
dict with L, Lq, W, Wq, rho, P0 plus MATLAB-style aliases (meanQueueLength, meanQueueLengthQ, meanWaitingTime, meanSojournTime, utilization, throughput, lossProbability, queueLengthDist).
- Return type:
- qsys_mg1(lambda_val, mu, cs)[source]
Analyze M/G/1 queue using Pollaczek-Khinchine formula.
- Parameters:
- Returns:
- Performance measures including:
L: Mean number in system
Lq: Mean number in queue
W: Mean response time
Wq: Mean waiting time
rho: Utilization (lambda/mu)
- Return type:
Example
>>> result = qsys_mg1(0.5, 1.0, 1.0) # cs=1 is exponential (M/M/1)
- qsys_gm1(sigma, mu)[source]
Analyze G/M/1 queue (general arrivals, exponential service).
Matches MATLAB qsys_gm1(sigma, mu) and JAR Qsys_gm1: the number of customers found by an arrival is geometric with parameter sigma, so the mean response time (time in system) is W = 1/(mu*(1-sigma)).
- Parameters:
- Returns:
{‘W’: mean response time}
- Return type:
Note
To obtain sigma from the first two moments of the interarrival time, use qsys_gg1(lambda_val, mu, ca2, 1.0), which fits a two-moment renewal process and solves the fixed point.
- qsys_mminf(lambda_val, mu)[source]
Analyze M/M/inf queue (infinite servers / delay station).
- Parameters:
- Returns:
- Performance measures including:
L: Mean number in system (= lambda/mu)
Lq: Mean number in queue (= 0)
W: Mean time in system (= 1/mu)
Wq: Mean waiting time (= 0)
P0: Probability of empty system
- Return type:
- qsys_mginf(lambda_val, mu, k=None)[source]
Analyze M/G/inf queue (infinite servers, general service).
Performance is independent of service time distribution shape. Number of customers follows Poisson distribution.
- Parameters:
- Returns:
- Performance measures including:
L: Mean number in system
Lq: Mean number in queue (= 0)
W: Mean time in system (= 1/mu)
Wq: Mean waiting time (= 0)
P0: Probability of empty system
Pk: Probability of k customers (if k provided)
- Return type:
- qsys_mmcc_retrial_fp(lambda_val, mu, c, tol=1e-10, maxiter=10000)[source]
Fixed-point approximation for M/M/c/c retrial queue.
Customers arrive at rate lambda to a system with c servers (no waiting room), each with service rate mu. Blocked customers join an orbit and retry. Under the assumption that the retrial rate is small relative to the service rate, the total arrival flow (fresh + retrial) is approximated by a Poisson process with rate lambda + r, where r satisfies the fixed-point equation:
r = (lambda + r) * B((lambda + r) / mu, c)
and B(a, c) is the Erlang-B blocking probability for offered load a and c servers.
- Parameters:
- Returns:
- Performance measures including:
blocProb: Blocking probability
r: Additional arrival rate due to retrials
niter: Number of iterations to converge
rho: Offered load (lambda / (c * mu))
L: Mean number of busy servers
- Return type:
References
Cohen (1957), fixed-point approximation for M/M/c/c retrial queues. Phung-Duc, “Retrial Queueing Models: A Survey on Theory and Applications”, 2019, Eq. (1).
Example
>>> result = qsys_mmcc_retrial_fp(2.0, 1.0, 3) >>> print(f"Blocking: {result['blocProb']:.4f}")
- qsys_gig1_rq(rho, mu, cs2, IaFun)[source]
Robust Queueing (RQ) approximation for a single G/GI/1 queue partially characterized by its arrival rate, index of dispersion for counts (IDC) and the first two moments of the service time. Implements the mean steady-state workload
Z* = sup_{x>=0} { -(1-rho) x + sqrt( 2 rho x (I_a(x) + c2_s) / mu ) }
and the derived steady-state performance measures.
- Reference:
W. Whitt and W. You (2018), “A Robust Queueing Network Analyzer Based on Indices of Dispersion”, eqs. (13),(16)-(18).
- Parameters:
- Returns:
Tuple (Z, W, Q, X) with mean workload E[Z], waiting time E[W], queue length E[Q] (waiting + in service), and number in system E[X].
- qsys_gig1_approx_allencunneen(lambda_val, mu, ca, cs)[source]
Allen-Cunneen approximation for G/G/1 queue.
Matches MATLAB qsys_gig1_approx_allencunneen.m exactly.
- Parameters:
- Returns:
W: Mean response time (time in system) rhohat: Effective utilization (so that M/M/1 formulas still hold)
- Return type:
Tuple of (W, rhohat) where
- qsys_gig1_approx_kingman(lambda_val, mu, ca, cs)[source]
Kingman’s upper bound approximation for G/G/1 queue.
Note: alias of qsys_gig1_ubnd_kingman (‘gig1.kingman’ method).
- Parameters:
- Returns:
W: Upper bound on mean response time (time in system) rhohat: Effective utilization (so that M/M/1 formulas still hold)
- Return type:
Tuple of (W, rhohat) where
- qsys_gig1_approx_marchal(lambda_val, mu, ca, cs)[source]
Marchal’s approximation for G/G/1 queue.
Matches MATLAB qsys_gig1_approx_marchal.m exactly. Note: MATLAB formula uses ca (not ca^2) in the numerator factor.
- Parameters:
- Returns:
W: Mean response time (time in system) rhohat: Effective utilization (so that M/M/1 formulas still hold)
- Return type:
Tuple of (W, rhohat) where
- qsys_gig1_approx_whitt(lambda_val, mu, ca, cs)[source]
Whitt’s approximation for G/G/1 queue.
Uses QNA (Queueing Network Analyzer) approximation. Note: No direct MATLAB counterpart (qsys_gig1_approx_whitt.m does not exist).
- Parameters:
- Returns:
W: Mean response time (time in system) rhohat: Effective utilization (so that M/M/1 formulas still hold)
- Return type:
Tuple of (W, rhohat) where
- qsys_gig1_approx_heyman(lambda_val, mu, ca, cs)[source]
Heyman’s approximation for G/G/1 queue.
Matches MATLAB qsys_gig1_approx_heyman.m exactly.
- Parameters:
- Returns:
W: Mean response time (time in system) rhohat: Effective utilization (so that M/M/1 formulas still hold)
- Return type:
Tuple of (W, rhohat) where
- qsys_gig1_approx_kobayashi(lambda_val, mu, ca, cs)[source]
Kobayashi’s approximation for G/G/1 queue.
Matches MATLAB qsys_gig1_approx_kobayashi.m exactly.
- Parameters:
- Returns:
W: Mean response time (time in system) rhohat: Effective utilization
- Return type:
Tuple of (W, rhohat) where
- qsys_gig1_approx_klb(lambda_val, mu, ca, cs)[source]
Kraemer-Langenbach-Belz (KLB) approximation for G/G/1 queue.
Matches MATLAB qsys_gig1_approx_klb.m exactly.
- Parameters:
- Returns:
W: Mean response time (time in system) rhohat: Effective utilization (so that M/M/1 formulas still hold)
- Return type:
Tuple of (W, rhohat) where
- qsys_gig1_approx_gelenbe(lambda_val, mu, ca, cs)[source]
Gelenbe’s diffusion approximation for G/G/1 with instantaneous-return boundary:
p(0) = 1-rho, p(n) = rho*(1-rhat)*rhat^(n-1), n>=1 rhat = exp(-2*(1-rho)/(rho*ca^2+cs^2))
hence E[N] = rho/(1-rhat) and the mean response time (time in system) is W = E[N]/lambda = 1/(mu*(1-rhat)).
- Parameters:
- Returns:
W: Mean response time (time in system) rhohat: Effective utilization (so that M/M/1 formulas still hold)
- Return type:
Tuple of (W, rhohat) where
References
Gelenbe, E. (1975). “On approximate computer system models”. Journal of the ACM 22(2), 261-269.
- qsys_gig1_approx_kimura(lambda_val, mu, ca, cs)[source]
- Kimura’s diffusion-interpolation approximation for G/G/1:
Wq = rho*(ca^2+cs^2)/(mu*(1-rho)*(1+ca^2))
exact for M/M/1 and M/G/1. The returned W adds the mean service time (response time, time in system).
- Parameters:
- Returns:
W: Mean response time (time in system) rhohat: Effective utilization (so that M/M/1 formulas still hold)
- Return type:
Tuple of (W, rhohat) where
References
Kimura, T. (1986). “A two-moment approximation for the mean waiting time in the GI/G/s queue”. Management Science 32(6), 751-763.
- qsys_gig1_approx_myskja(lambda_val, mu, ca, cs, q0, qa)[source]
- Myskja’s third-moment approximation for G/G/1:
Wq = rho/(2*mu*(1-rho))*((1+cs^2)+(q0/qa)^(1/rho-rho)*(1/rho)*(ca^2-1))
exact for M/G/1 (ca=1). The returned W adds the mean service time (response time, time in system).
Reference: Myskja, A. (1991). “An Experimental Study of a H₂/H₂/1 Queue”. Stochastic Models, 7(4), 571-595.
- Parameters:
lambda_val (float) – Arrival rate
mu (float) – Service rate
ca (float) – Coefficient of variation of inter-arrival time
cs (float) – Coefficient of variation of service time
q0 (float) – Lowest relative third moment for given mean and SCV
qa (float) – Third relative moment E[X^3]/6/E[X]^3 of inter-arrival time
- Returns:
W: Mean response time (time in system) rhohat: Effective utilization (so that M/M/1 formulas still hold)
- Return type:
Tuple of (W, rhohat) where
- qsys_gig1_approx_myskja2(lambda_val, mu, ca, cs, q0, qa)[source]
Modified Myskja (Myskja2) approximation for G/G/1, returning the mean response time (time in system). For ca=1 the interpolation parameter theta is a 0/0 form, so the exact M/G/1 result is returned instead (also the interpolation anchor of the method).
Reference: Myskja, A. (1991). “An Experimental Study of a H₂/H₂/1 Queue”. Stochastic Models, 7(4), 571-595.
- Parameters:
lambda_val (float) – Arrival rate
mu (float) – Service rate
ca (float) – Coefficient of variation of inter-arrival time
cs (float) – Coefficient of variation of service time
q0 (float) – Lowest relative third moment for given mean and SCV
qa (float) – Third relative moment E[X^3]/6/E[X]^3 of inter-arrival time
- Returns:
W: Mean response time (time in system) rhohat: Effective utilization (so that M/M/1 formulas still hold)
- Return type:
Tuple of (W, rhohat) where
- qsys_gg1(lambda_val, mu, ca2, cs2)[source]
G/G/1 queue analysis using exact methods for special cases and Allen-Cunneen approximation for the general case. In the G/M/1 case, the interarrival-time distribution is fitted from (lambda, ca2) by a two-moment renewal process (H2 with balanced means for ca2>1, mixed Erlang for ca2<1) and sigma is the root of sigma = A*(mu*(1-sigma)), with A* the interarrival-time LST.
- Parameters:
- Returns:
W: Mean response time (time in system) rhohat: Effective utilization
- Return type:
Tuple of (W, rhohat) where
References
Original MATLAB: matlab/src/api/qsys/qsys_gg1.m
- qsys_gig1_lbnd(lambda_val, mu, ca, cs)[source]
Fundamental theoretical lower bounds for G/G/1 queues.
These are the minimum possible values that performance measures cannot fall below for any realization of the arrival and service processes.
- Parameters:
- Returns:
W: Lower bound on mean response time (= 1/mu) rhohat: Effective utilization
- Return type:
Tuple of (W, rhohat) where
References
Original JAR: jar/src/main/kotlin/jline/api/qsys/Qsys_gig1_lbnd.kt
- qsys_gigk_approx(lambda_val, mu, ca, cs, k)[source]
Approximation for G/G/k queue.
Matches MATLAB qsys_gigk_approx.m formula using alpha-factor correction.
- Parameters:
- Returns:
W: Approximate mean response time rhohat: Effective utilization
- Return type:
Tuple of (W, rhohat) where
- qsys_gigk_approx_cosmetatos(lambda_val, mu, ca, cs, k)[source]
GI/G/k approximation by interpolation of the M/M/k, M/D/k and D/M/k queues (Cosmetatos 1982; Page 1982):
- Wq = [ca^2*cs^2 + ca^2*(1-cs^2)*phi1/2
(1-ca^2)*cs^2*phi3/2] * Wq(M/M/k)
where phi1 and phi3 are the Cosmetatos (1975) correction factors for M/D/k and D/M/k, with the safeguards of Whitt (1993). The D/D/k corner has Wq=0. The interpolation requires ca^2<=1 and cs^2<=1; outside this region the Lee-Longton scaling Wq = ((ca^2+cs^2)/2)*Wq(M/M/k) is used.
- Parameters:
- Returns:
W: Approximate mean response time (time in system) rhohat: Effective utilization
- Return type:
Tuple of (W, rhohat) where
References
Cosmetatos, G.P. (1975). “Approximate explicit formulae for the average queueing time in the processes (M/D/r) and (D/M/r)”. INFOR 13, 328-331. Page, E. (1982). “Tables of waiting times for M/M/n, M/D/n and D/M/n and their use to give approximate waiting times in more general queues”. J. Opl. Res. Soc. 33, 453-473.
- qsys_gigk_approx_whitt(lambda_val, mu, ca, cs, k)[source]
- GI/G/k approximation of Whitt (1993), eqs. (2.16)-(2.25):
Wq = phi(rho,ca^2,cs^2,k) * ((ca^2+cs^2)/2) * Wq(M/M/k)
where phi interpolates the Cosmetatos M/D/k (phi1) and D/M/k (phi3) correction factors. Exact for M/M/k; reduces to the Cosmetatos M/D/k approximation for cs=0. Implements eq. (2.25) as printed, which was validated against the paper’s Tables 5-7 (New column).
- Parameters:
- Returns:
W: Approximate mean response time (time in system) rhohat: Effective utilization
- Return type:
Tuple of (W, rhohat) where
References
Whitt, W. (1993). “Approximations for the GI/G/m queue”. Production and Operations Management 2(2), 114-161.
- qsys_gig1_ubnd_kingman(lambda_val, mu, ca, cs)[source]
- Kingman’s upper bound on the mean waiting time of a G/G/1 queue:
Wq <= lambda*(sa^2+ss^2)/(2*(1-rho)),
with sa^2=ca^2/lambda^2 and ss^2=cs^2/mu^2. The returned W adds the mean service time, so it upper-bounds the mean response time (time in system).
- Parameters:
- Returns:
W: Upper bound on mean response time rhohat: Effective utilization (so M/M/1 formulas still hold)
- Return type:
Tuple of (W, rhohat) where
References
Kingman, J.F.C. (1962). “Some inequalities for the queue GI/G/1”. Biometrika 49(3/4), 315-324. Original MATLAB: matlab/src/api/qsys/qsys_gig1_ubnd_kingman.m
- qsys_gigk_approx_kingman(lambda_val, mu, ca, cs, k)[source]
Kingman’s approximation for G/G/k queue waiting time.
Extends Kingman’s approximation to multi-server queues using M/M/k waiting time as a base.
- Parameters:
- Returns:
W: Approximate mean response time rhohat: Effective utilization
- Return type:
Tuple of (W, rhohat) where
References
Original MATLAB: matlab/src/api/qsys/qsys_gigk_approx_kingman.m
- qsys_mg1_prio(lambda_vec, mu_vec, cs_vec)[source]
Analyze M/G/1 queue with non-preemptive (Head-of-Line) priorities.
Matches MATLAB qsys_mg1_prio.m exactly.
- Parameters:
lambda_vec (numpy.ndarray) – Vector of arrival rates per priority class (class 1 = highest)
mu_vec (numpy.ndarray) – Vector of service rates per priority class
cs_vec (numpy.ndarray) – Vector of coefficients of variation per priority class
- Returns:
W: Vector of mean response times per priority class rho: System utilization (rhohat = Q/(1+Q) format)
- Return type:
Tuple of (W, rho)
- qsys_mm1_dps(lambda_vec, mu_vec, w_vec, tol=1e-10, max_cutoff=2048)[source]
Numerically exact M/M/1 Discriminatory Processor Sharing (DPS) queue.
Solves the multiclass DPS continuous-time Markov chain on the per-class population vector (n_1..n_K): arrivals lambda_k, class-k service completion rate mu_k * n_k * w_k / sum_j n_j * w_j. The state space is truncated at a total population level chosen from the geometric tail bound (the total-count process is stochastically dominated by the M/M/1 with rate min_k mu_k), and the truncation level is doubled until the mean queue lengths are stable to the requested tolerance – so the result is exact to solver precision and conserves the M/M/1 total for equal service rates by construction.
- Parameters:
lambda_vec (numpy.ndarray) – Per-class Poisson arrival rates (K,)
mu_vec (numpy.ndarray) – Per-class exponential service rates (K,)
w_vec (numpy.ndarray) – Per-class DPS weights (K,), positive
tol (float) – Convergence tolerance on the per-class mean counts
max_cutoff (int) – Hard bound on the total-population truncation level
- Returns:
per-class mean response times (K,) via Little’s law, and the total utilization sum_k lambda_k/mu_k.
- Return type:
Tuple of (T, rho)
- qsys_mg1_srpt(lambda_vec, mu_vec, cs_vec)[source]
Analyze M/G/1 queue with Shortest Remaining Processing Time (SRPT).
SRPT is a size-based policy: it always serves the job with the smallest remaining processing time, preempting whenever a shorter job arrives. The class-conditional mean response time follows the Schrage-Miller formula (Bansal-Harchol-Balter, SIGMETRICS 2001, Sec. 4, Eqs (1)-(3), after Schrage-Miller 1966). For a job of size x:
E[T(x)] = E[W(x)] + E[R(x)] E[W(x)] = lambda*(m2(x) + x^2*(1-F(x))) / (2*(1-rho(x))^2) E[R(x)] = integral_0^x dt/(1-rho(t))
with f the mixture job-size density, F its CDF, rho(x)=lambda*int_0^x t f(t)dt and m2(x)=int_0^x t^2 f(t)dt. The per-class mean is E[T_r]=int_0^inf E[T(x)] f_r(x) dx; since E[T(x)] depends only on the job size (SRPT is size-based) this is exact. Integrals use cumulative trapezoidal quadrature on a common grid. Each class is matched to its (mean=1/mu, scv=cs^2): exponential for cs=1, a two-phase balanced hyperexponential for cs>1, and a Tijms Erlang-(k-1)/Erlang-k mixture for cs<1. The fully exponential case reproduces the exact M/M/1/SRPT result.
Matches MATLAB qsys_mg1_srpt.m.
- Parameters:
lambda_vec (numpy.ndarray) – Vector of arrival rates per class
mu_vec (numpy.ndarray) – Vector of service rates per class
cs_vec (numpy.ndarray) – Vector of coefficients of variation per class
- Returns:
W: Vector of mean response times per class (original class order) rho: System load measure Q/(1+Q) with Q = sum(lambda.*W)
- Return type:
Tuple of (W, rho)
- qsys_mg1_fb(lambda_vec, mu_vec, cs_vec)[source]
Analyze M/G/1 queue with Foreground-Background (FB/LAS) scheduling.
Matches MATLAB qsys_mg1_fb.m exactly: - Exponential case: numerical integration of E[T(x)] * f_k(x) - General case: class-based approximation
- Parameters:
lambda_vec (numpy.ndarray) – Vector of arrival rates per class
mu_vec (numpy.ndarray) – Vector of service rates per class
cs_vec (numpy.ndarray) – Vector of coefficients of variation per class
- Returns:
W: Vector of mean response times per class rho: System utilization (rhohat format)
- Return type:
Tuple of (W, rho)
- qsys_mg1_lrpt(lambda_vec, mu_vec, cs_vec)[source]
Analyze M/G/1 queue with Longest Remaining Processing Time (LRPT).
Matches MATLAB qsys_mg1_lrpt.m exactly: - Exponential case: numerical integration of E[T(x)] * f_k(x) - General case: preemptive priority with descending service time ordering
- Parameters:
lambda_vec (numpy.ndarray) – Vector of arrival rates per class
mu_vec (numpy.ndarray) – Vector of service rates per class
cs_vec (numpy.ndarray) – Vector of coefficients of variation per class
- Returns:
W: Vector of mean response times per class rho: System utilization (rhohat format)
- Return type:
Tuple of (W, rho)
- qsys_mg1_psjf(lambda_vec, mu_vec, cs_vec)[source]
Analyze M/G/1 queue with Preemptive Shortest Job First (PSJF).
Matches MATLAB qsys_mg1_psjf.m exactly: - Exponential case: numerical integration of E[T(x)] * f_k(x) - General case: class-based truncated moment formula
- Parameters:
lambda_vec (numpy.ndarray) – Vector of arrival rates per class
mu_vec (numpy.ndarray) – Vector of service rates per class
cs_vec (numpy.ndarray) – Vector of coefficients of variation per class
- Returns:
W: Vector of mean response times per class rho: System utilization (rhohat format)
- Return type:
Tuple of (W, rho)
- qsys_mg1_setf(lambda_vec, mu_vec, cs_vec)[source]
Analyze M/G/1 queue with Shortest Expected Time First (SETF).
Matches MATLAB qsys_mg1_setf.m exactly: SETF = FB/LAS + residual service time penalty (non-preemptive).
- Parameters:
lambda_vec (numpy.ndarray) – Vector of arrival rates per class
mu_vec (numpy.ndarray) – Vector of service rates per class
cs_vec (numpy.ndarray) – Vector of coefficients of variation per class
- Returns:
W: Vector of mean response times per class rho: System utilization (rhohat format)
- Return type:
Tuple of (W, rho)
- qsys_mm1k_loss(lambda_val, mu, K)[source]
Compute loss probability for M/M/1/K queue.
Uses the closed-form formula for the M/M/1/K loss system where customers are rejected when the buffer (capacity K) is full.
- Parameters:
- Returns:
lossprob: Probability that an arriving customer is rejected rho: Offered load (lambda/mu)
- Return type:
Tuple of (lossprob, rho)
References
Original MATLAB: matlab/src/api/qsys/qsys_mm1k_loss.m
- qsys_mg1k_loss(lambda_val, service_pdf, K, max_t=None)[source]
Exact M/G/1/K loss probability via the Markov chain embedded at service-start epochs (transform-free analysis in the spirit of Niu-Cooper).
State: number of customers waiting in the queue immediately after a service start, q in {0,…,K-2} (capacity K includes the job in service; just after a departure at most K-1 jobs remain, one of which enters service). With a_j = P(j Poisson arrivals during a service time):
- q=0if no arrival occurs during the service the system empties and
the next service starts with the next arrival (q’=0), so both a_0 and a_1 lead to q’=0 and j>=2 arrivals lead to q’=j-1;
- q>=1: q’ = q-1+j, with arrivals beyond the free capacity lost
(aggregated in the last column).
- The loss probability follows from the renewal-reward argument
E[cycle] = E[S] + sigma_0*a_0/lambda, lambda_eff = 1/E[cycle], P_loss = 1 - lambda_eff/lambda = 1 - 1/(rho + sigma_0*a_0)
where sigma is the stationary distribution at service-start epochs.
- Parameters:
lambda_val (float) – Arrival rate
service_pdf (Callable[[float], float]) – Probability density function of service time f(t)
K (int) – Buffer capacity (including the customer in service)
max_t (float | None) – Maximum integration time (default: smallest horizon covering the service-time distribution mass to within 1e-10)
- Returns:
- sigma0: Stationary probability of an empty queue at service-start
epochs
rho: Offered load lossprob: Probability of loss
- Return type:
Tuple of (sigma0, rho, lossprob)
References
Original MATLAB: matlab/src/api/qsys/qsys_mg1k_loss.m Niu-Cooper, “Transform-Free Analysis of M/G/1/K”, 1993
- qsys_mg1k_loss_mgs(lambda_val, mu, mu_scv, K)[source]
Compute loss probability for M/G/1/K using MacGregor Smith approximation.
Matches MATLAB qsys_mg1k_loss_mgs.m exactly.
- Parameters:
- Returns:
lossprob: Probability of loss rho: Offered load
- Return type:
Tuple of (lossprob, rho)
References
Original MATLAB: matlab/src/api/qsys/qsys_mg1k_loss_mgs.m J. MacGregor Smith, “Optimal Design and Performance Modelling of M/G/1/K Queueing Systems”
- qsys_mxm1(lambda_batch, mu, E_X_or_batch_sizes, E_X2_or_pmf, mode=None)[source]
Analyze MX/M/1 queue with batch arrivals.
Matches MATLAB qsys_mxm1.m exactly.
- Three input formats:
Moment-based: qsys_mxm1(lambda_batch, mu, E_X, E_X2)
PMF-based: qsys_mxm1(lambda_batch, mu, batch_sizes, pmf)
Variance: qsys_mxm1(lambda_batch, mu, E_X, Var_X, ‘variance’)
- Parameters:
- Returns:
W: Mean time in system Wq: Mean waiting time in queue U: Server utilization Q: Mean queue length (including service)
- Return type:
Tuple of (W, Wq, U, Q)
References
Original MATLAB: matlab/src/api/qsys/qsys_mxm1.m
- class QueueResult(meanQueueLength, meanWaitingTime, meanSojournTime, utilization, queueLengthDist=None, queueLengthMoments=None, sojournTimeMoments=None, analyzer='native')[source]
Bases:
objectResult structure for queue analysis.
- queueLengthDist: numpy.ndarray | None = None
- queueLengthMoments: numpy.ndarray | None = None
- sojournTimeMoments: numpy.ndarray | None = None
- ph_to_map(alpha, T)[source]
Convert a PH distribution to its equivalent MAP representation.
- For a PH renewal process, the MAP has:
D0 = T (transitions within the PH, no arrival) D1 = t * alpha where t = -T*e (exit rates times restart distribution)
- Parameters:
alpha (numpy.ndarray) – Initial probability vector (1 x n)
T (numpy.ndarray) – Sub-generator matrix (n x n)
- Returns:
D0: MAP hidden transition matrix D1: MAP observable transition matrix
- Return type:
Tuple of (D0, D1)
- qsys_phph1(alpha, T, beta, S, numQLMoms=3, numQLProbs=100, numSTMoms=3)[source]
Analyze a PH/PH/1 queue using matrix-analytic methods.
Converts the arrival PH to MAP representation and uses the MMAPPH1FCFS solver from BuTools.
- Parameters:
alpha (numpy.ndarray) – Arrival PH initial probability vector (1 x n)
T (numpy.ndarray) – Arrival PH generator matrix (n x n)
beta (numpy.ndarray) – Service PH initial probability vector (1 x m)
S (numpy.ndarray) – Service PH generator matrix (m x m)
numQLMoms (int) – Number of queue length moments to compute (default: 3)
numQLProbs (int) – Number of queue length probabilities (default: 100)
numSTMoms (int) – Number of sojourn time moments (default: 3)
- Returns:
QueueResult with queue performance metrics
- Return type:
References
Original MATLAB: matlab/src/api/qsys/qsys_phph1.m
- qsys_mapph1(D0, D1, beta, S, numQLMoms=3, numQLProbs=100, numSTMoms=3)[source]
Analyze a MAP/PH/1 queue.
- Parameters:
D0 (numpy.ndarray) – MAP hidden transition matrix
D1 (numpy.ndarray) – MAP observable transition matrix
beta (numpy.ndarray) – Service PH initial probability vector
S (numpy.ndarray) – Service PH generator matrix
numQLMoms (int) – Number of queue length moments
numQLProbs (int) – Number of queue length probabilities
numSTMoms (int) – Number of sojourn time moments
- Returns:
QueueResult with queue performance metrics
- Return type:
References
Original MATLAB: matlab/src/api/qsys/qsys_mapph1.m
- qsys_mapm1(D0, D1, mu)[source]
Analyze a MAP/M/1 queue.
- Parameters:
D0 (numpy.ndarray) – MAP hidden transition matrix
D1 (numpy.ndarray) – MAP observable transition matrix
mu (float) – Service rate
- Returns:
QueueResult with queue performance metrics
- Return type:
References
Original MATLAB: matlab/src/api/qsys/qsys_mapm1.m
- qsys_mapmc(D0, D1, mu, c)[source]
Analyze a MAP/M/c queue.
- Parameters:
D0 (numpy.ndarray) – MAP hidden transition matrix
D1 (numpy.ndarray) – MAP observable transition matrix
mu (float) – Service rate per server
c (int) – Number of servers
- Returns:
QueueResult with queue performance metrics
- Return type:
References
Original MATLAB: matlab/src/api/qsys/qsys_mapmc.m
- qsys_mapmap1(D0_arr, D1_arr, D0_srv, D1_srv)[source]
Analyze a MAP/MAP/1 queue.
Both arrival and service processes are Markovian Arrival Processes.
- Parameters:
D0_arr (numpy.ndarray) – Arrival MAP hidden transition matrix
D1_arr (numpy.ndarray) – Arrival MAP observable transition matrix
D0_srv (numpy.ndarray) – Service MAP hidden transition matrix
D1_srv (numpy.ndarray) – Service MAP observable transition matrix
- Returns:
QueueResult with queue performance metrics
- Return type:
References
Original MATLAB: matlab/src/api/qsys/qsys_mapmap1.m
- qsys_mapg1(D0, D1, service_moments, num_ql_moms=3, num_ql_probs=100, num_st_moms=3)[source]
Analyze a MAP/G/1 queue using BuTools MMAPPH1FCFS.
The general service time distribution is fitted to a Phase-Type (PH) distribution using moment matching before analysis.
- Parameters:
D0 (numpy.ndarray) – MAP hidden transition matrix (n x n)
D1 (numpy.ndarray) – MAP arrival transition matrix (n x n)
service_moments (numpy.ndarray) – First k raw moments of service time [E[S], E[S^2], …] (k = 2 or 3 for best accuracy)
num_ql_moms (int) – Number of queue length moments to compute (default: 3)
num_ql_probs (int) – Number of queue length probabilities (default: 100)
num_st_moms (int) – Number of sojourn time moments to compute (default: 3)
- Returns:
QueueResult with queue performance metrics
- Return type:
References
Original MATLAB: matlab/src/api/qsys/qsys_mapg1.m
Note
Uses the MMAPPH1FCFS solver from BuTools after fitting the general service distribution to a PH distribution.
- class QueueType(*values)[source]
Bases:
EnumQueueing system topology types.
- STANDARD = 'standard'
- RETRIAL = 'retrial'
- RENEGING = 'reneging'
- RETRIAL_RENEGING = 'retrial_reneging'
- class BmapMatrix(D0, D_batch)[source]
Bases:
objectBatch Markovian Arrival Process matrix representation.
D₀ = drift matrix (no arrivals) D₁, D₂, …, Dₖ = batch arrival matrices for batch sizes 1, 2, …, K
- Properties:
order: Dimension of the BMAP num_batches: Maximum batch size arrival_rate: Overall arrival rate
- property arrival_rate: float
Compute overall arrival rate of the BMAP.
lambda = theta * (-D0) * e where theta is stationary distribution of BMAP Markov chain and e is unit vector.
- D0: numpy.ndarray
- D_batch: List[numpy.ndarray]
- class PhDistribution(beta, S)[source]
Bases:
objectPhase-Type (PH) distribution representation.
Beta = initial probability vector (shape: m,) S = transient generator matrix (shape: m x m)
where m is the number of phases.
- Properties:
mean: Mean of PH distribution (1/mu in queue notation) scv: Squared coefficient of variation num_phases: Number of phases
- property mean_squared: float
Compute second moment of PH distribution.
E[X²] = 2 * beta * S^{-2} * e
- beta: numpy.ndarray
- class QbdStatespace(A0, A1, A2, B0, max_level)[source]
Bases:
objectQuasi-Birth-Death Markov chain state space representation.
For a QBD process, states are of the form (n, i) where: - n = level (number of retrying customers in orbit) - i = phase (service phase or phase-type stage)
Generator matrix has block structure: Q = | B_0 A_0 0 0 … |
A_2 A_1 A_0 0 … |0 A_2 A_1 A_0 … |… |- Properties:
max_level: Maximum retrial orbit size (truncation level) phase_dim: Number of phases at each level total_states: Total state space dimension
- property binomial_state_dimension: int
Compute state space dimension using binomial coefficient formula.
For a retrial queue with N total customers and m servers, dimension = C(N + m - 1, m - 1)
This is a rough upper bound for QBD truncation.
- A0: numpy.ndarray
- A1: numpy.ndarray
- A2: numpy.ndarray
- B0: numpy.ndarray
- class RetrialQueueResult(queue_type, L_orbit, N_server, utilization, throughput, P_idle, P_empty_orbit, stationary_dist=None, truncation_level=0, converged=False, iterations=0, error=numpy.inf)[source]
Bases:
objectAnalysis results for BMAP/PH/N/N retrial queue.
- queue_type
Type of queue (retrial, reneging, etc.)
- stationary_dist
Stationary distribution vector
- Type:
numpy.ndarray | None
- stationary_dist: numpy.ndarray | None = None
- class RetrialQueueAnalyzer(sn, options=None)[source]
Bases:
objectFramework for analyzing BMAP/PH/N/N retrial queues.
This class provides the foundation for future full solver implementation, including topology detection, parameter extraction, and QBD setup.
Example
analyzer = RetrialQueueAnalyzer(model) queue_type = analyzer.detect_queue_type() if queue_type == QueueType.RETRIAL:
result = analyzer.analyze()
Initialize retrial queue analyzer.
- Parameters:
- analyze()[source]
Analyze the retrial queue.
This is the main entry point for analysis: 1. Detect queue type 2. Extract arrival and service parameters 3. Build QBD state space 4. Solve for stationary distribution using matrix-analytic methods 5. Compute performance metrics
- Returns:
RetrialQueueResult with performance metrics
- Return type:
- build_qbd_statespace(bmap, ph_service, retrial_params)[source]
Build QBD state space for the retrial queue.
This constructs the generator matrix blocks for the QBD process following the BMAP/PH/N/N retrial queue formulation.
- Parameters:
bmap (BmapMatrix) – BMAP arrival process
ph_service (PhDistribution) – PH service distribution
retrial_params (Dict[str, float]) – Retrial parameters (alpha, gamma, p, R, N)
- Returns:
QbdStatespace instance or None if construction fails
- Return type:
QbdStatespace | None
- detect_queue_type()[source]
Detect the type of queueing system from topology.
- Returns:
QueueType enum indicating retrial, reneging, or combination
- Return type:
- extract_bmap()[source]
Extract BMAP parameters from arrival process.
LINE stores arrival processes in MAP format: {D0, D1, D2, …} where D0 is the “hidden” generator and D1, D2, … are arrival matrices.
- Returns:
BmapMatrix instance or None if arrival is not BMAP/MAP
- Return type:
BmapMatrix | None
- extract_ph_service()[source]
Extract Phase-Type service parameters.
LINE stores PH in MAP format: {D0, D1} D0 = T (subgenerator matrix) D1 = S0 * alpha (exit rate times initial prob)
- Returns:
PhDistribution instance or None if service is not PH
- Return type:
PhDistribution | None
- qsys_bmapphnn_retrial(arrival_matrix, service_params, N, retrial_params=None, options=None)[source]
Analyze BMAP/PH/N/N bufferless retrial queue.
Implements the algorithm from Dudin et al., “Analysis of BMAP/PH/N-Type Queueing System with Flexible Retrials Admission Control”, Mathematics 2025, 13(9), 1434.
- Parameters:
arrival_matrix (Dict[str, numpy.ndarray]) – Dict with ‘D0’, ‘D1’, … for BMAP matrices. D0: hidden transition matrix (V x V). D1, …, DK: arrival matrices for batch sizes 1, …, K.
service_params (Dict[str, numpy.ndarray]) – Dict with ‘beta’ (initial prob vector, 1xM) and ‘S’ (PH subgenerator matrix, MxM).
N (int) – Number of servers (also capacity, hence bufferless).
retrial_params (Dict[str, float] | None) – Dict with ‘alpha’ (retrial rate per customer), ‘gamma’ (impatience/abandonment rate), ‘p’ (batch rejection probability), ‘R’ (admission threshold, scalar or 1xV).
options (Dict | None) – Dict with optional keys: ‘MaxLevel’: max orbit level for truncation (default: auto). ‘Tolerance’: convergence tolerance (default: 1e-10). ‘Verbose’: print progress (default: False).
- Returns:
RetrialQueueResult with performance metrics.
- Return type:
References
Dudin, A., Klimenok, V., & Vishnevsky, V. (2020). Port from: matlab/src/api/qsys/qsys_bmapphnn_retrial.m
- qsys_is_retrial(sn)[source]
Check if network is a valid BMAP/PH/N/N bufferless retrial queue.
Validates that the network structure matches the requirements for the BMAP/PH/N/N retrial queue solver: - Single bufferless queue (capacity == number of servers) - Retrial drop strategy configured - BMAP/MAP arrival process at source - PH/Exp service at queue - Open class model
Based on: Dudin et al., “Analysis of BMAP/PH/N-Type Queueing System with Flexible Retrials Admission Control”, Mathematics 2025, 13(9), 1434.
- Parameters:
sn (Any) – NetworkStruct object
- Returns:
is_retrial: True if network is valid BMAP/PH/N/N retrial topology retrial_info: RetrialInfo with parameters for the retrial solver
- Return type:
Tuple of (is_retrial, retrial_info) where
References
Original MATLAB: matlab/src/api/qsys/qsys_is_retrial.m
- class RetrialInfo(is_retrial, station_idx=None, node_idx=None, source_idx=None, class_idx=None, error_msg='', N=None, alpha=0.1, gamma=0.0, p=0.0, R=None)[source]
Bases:
objectInformation about a valid retrial queue topology.
- class RenegingInfo(is_reneging, source_idx=None, queue_idx=None, class_idx=None, n_servers=None, service_rate=None, error_msg='')[source]
Bases:
objectInformation about a valid reneging queue topology.
- detect_reneging_topology(sn)[source]
Detect if model is suitable for MAP/M/s+G (MAPMsG) reneging solver.
Requirements: - Open model, single class - Single queue station with reneging/patience configured - MAP/BMAP arrival at source - Exponential service at queue (single-phase PH) - FCFS scheduling
- Parameters:
sn (Any) – NetworkStruct object
- Returns:
Tuple of (is_reneging, reneging_info)
- Return type:
References
Original MATLAB: matlab/src/solvers/MAM/solver_mam_retrial.m (detectRenegingTopology)
- has_reneging_patience(sn)[source]
Check if model has reneging/patience configured on any queue station.
Returns True if any queue station has ImpatienceType.RENEGING configured with a patience distribution.
- Parameters:
sn (Any) – NetworkStruct object
- Returns:
True if reneging patience is configured
- Return type:
References
Original MATLAB: matlab/src/solvers/MAM/solver_mam_analyzer.m (hasRenegingPatience)
- extract_bmap_matrices(proc)[source]
Extract BMAP matrices {D0, D1, …} from LINE process representation.
LINE stores arrival processes in MAP format: {D0, D1, D2, …} where D0 is the “hidden” generator and D1, D2, … are arrival matrices. May also be in PH format {alpha, T} which is converted to MAP.
- Parameters:
proc (Any) – Process representation from sn.proc[station][class]
- Returns:
List of numpy arrays [D0, D1, …] or None if extraction fails
- Return type:
List[numpy.ndarray] | None
References
Original MATLAB: matlab/src/solvers/MAM/solver_mam_retrial.m (extractBMAPMatrices)
- extract_ph_params(proc)[source]
Extract PH parameters (beta, S) from LINE process representation.
LINE stores PH in MAP format: {D0, D1} where D0=T (subgenerator), D1=S0*alpha (exit rate times initial prob).
- Parameters:
proc (Any) – Process representation from sn.proc[station][class]
- Returns:
Tuple of (beta, S) where beta is initial probability vector and S is subgenerator matrix. Returns (None, None) if extraction fails.
- Return type:
Tuple[numpy.ndarray | None, numpy.ndarray | None]
References
Original MATLAB: matlab/src/solvers/MAM/solver_mam_retrial.m (extractPHParams)
- convert_patience_to_regimes(patience_proc, options=None)[source]
Convert patience distribution to piecewise-constant abandonment regimes for MAPMsG.
Converts a patience distribution (in MAP/PH format) to boundary levels and abandonment function values for the MRMFQ solver.
- Parameters:
- Returns:
boundary_levels: Array of regime boundary time points ga: Array of abandonment probabilities at each regime quantization: Number of regimes
- Return type:
Tuple of (boundary_levels, ga, quantization) where
References
Original MATLAB: matlab/src/solvers/MAM/solver_mam_retrial.m (convertPatienceToRegimes)
- solver_mam_retrial(sn, options=None)[source]
Solve queueing models with customer impatience (retrial or reneging).
Dispatches to either: 1. RETRIAL: BMAP/PH/N/N bufferless retrial solver 2. RENEGING: MAP/M/s+G solver (MAPMsG)
- Parameters:
- Returns:
QN: (M, K) queue lengths UN: (M, K) server utilizations RN: (M, K) response times TN: (M, K) throughputs CN: (1, K) cycle times XN: (1, K) system throughputs totiter: iteration/truncation level count
- Return type:
Tuple of (QN, UN, RN, TN, CN, XN, totiter) where
References
Original MATLAB: matlab/src/solvers/MAM/solver_mam_retrial.m
- qsys_ldps_workload(lambd, B, alpha, N, t=None, ngrid=None)[source]
Stationary distribution of the quantity of work in a single-stage load-dependent processor sharing station with Poisson arrivals and blocking.
Assumed model (Cohen 1979, Sect. 9; the model of Sect. 7 with one stage): a single service stage fed by a Poisson arrival stream of rate lambd; a blocking capacity N, so that a request arriving when N requests are already present is lost and leaves no trace on the state; generalized processor sharing, so that when x requests are present each accrues service at rate f(x) and the stage completes work at total rate x*f(x); and required service times i.i.d. with absolutely continuous distribution B of finite mean beta. The station is parametrized by the LINE load-dependent total rate scaling alpha(x)=x*f(x), the argument of setLoadDependence at a PS station.
With psi the total amount of service still to be given to the requests present, Cohen eqs. (9.1)-(9.3) give
Pr{psi < y} = sum_{h=0}^{N} p_h Psi^{h*}(y) p_h = (rho^h/h!) phi(h) / sum_k (rho^k/k!) phi(k), rho = lambd*beta phi(h) = 1/prod_{k=1}^{h} f(k), phi(0)=1 Psi(y) = int_0^y (1-B(v))/beta dv
with Psi^{h*} the h-fold convolution of Psi and Psi^{0*} degenerate at zero. Substituting f(k)=alpha(k)/k the factorial cancels, leaving p_h proportional to rho^h/prod_{k=1}^{h} alpha(k), the familiar load-dependent birth-death form. Psi is the equilibrium (residual life) distribution of B, so psi is a mixture of h-fold convolutions of residual service times with an atom p_0 at zero.
This is the model of Cohen (1979) Sect. 9 only. It is not the weighted GPS/DPS discipline of SchedStrategy.GPS, whose per-class weights this formula does not represent.
- Parameters:
lambd – rate of the Poisson arrival stream (finite, positive)
B – required service time Distribution (continuous, finite positive mean)
alpha – rate scaling alpha(n)=n*f(n) for n=1..N (finite, positive)
N – blocking capacity (finite positive integer)
t – optional grid at which the CDF is returned. Default: an automatically sized grid covering the bulk of the distribution.
ngrid – optional number of points of the internal uniform quadrature grid on which the convolutions are formed. Default 2001. Accuracy is second order in the step for an absolutely continuous B, the case Cohen assumes, and falls back to first order when B has an atom so that 1-B is discontinuous; raise ngrid for those.
- Returns:
(F, t, p) where F[j] = Pr{psi <= t[j]}, t is the grid F is reported on, and p[h] = Pr{x = h} for h = 0..N. Note F[0] = p[0] = Pr{psi = 0} when t[0] = 0, since the workload has an atom at zero.
Stochastic Networks (line_solver.api.sn)
Service Network (SN) utilities.
Native Python implementations for stochastic network structure analysis, validation, and parameter extraction.
- Key classes:
NetworkStruct: Data structure summarizing network characteristics SnGetDemandsResult: Result of sn_get_demands_chain calculation
- Key functions:
sn_get_demands_chain: Aggregate class-level parameters into chain-level sn_has_*: Network property predicates sn_is_*: Model type checks sn_get_*: Parameter extraction sn_validate: Network validation
- class MatrixArray(input_array)[source]
Bases:
ndarrayNumpy array subclass with .get() and .set() methods for API compatibility.
This class provides compatibility with the wrapper mode that uses JLine’s Matrix class which has get(i, j) and set(i, j, value) methods.
Create MatrixArray from existing array.
- __getitem__(key)[source]
Override indexing to handle 2D indexing on 1D arrays.
This provides compatibility with MATLAB-style row/column vectors where a 1D array can be indexed as (0, j) or (i, 0).
- class NetworkStruct(nstations=0, nstateful=0, nnodes=0, nclasses=0, nchains=0, nclosedjobs=0, njobs=<factory>, nservers=<factory>, cap=None, classcap=None, rates=<factory>, scv=<factory>, phases=None, phasessz=None, phaseshift=None, visits=<factory>, nodevisits=<factory>, inchain=<factory>, chains=<factory>, refstat=<factory>, refclass=<factory>, sched=<factory>, schedparam=None, routing=<factory>, rt=None, rtnodes=None, nodetype=<factory>, isstation=<factory>, isstateful=<factory>, isstatedep=None, isfunction=<factory>, nodeToStation=<factory>, nodeToStateful=<factory>, stationToNode=<factory>, stationToStateful=<factory>, statefulToNode=<factory>, statefulToStation=<factory>, state=<factory>, stateprior=<factory>, space=<factory>, lldscaling=None, cdscaling=None, cdscalingpeak=None, classprio=None, classdeadline=None, isslc=None, issignal=None, signaltarget=None, signaltype=None, syncreply=None, immfeed=None, signalremdist=None, signalrempolicy=None, iscatastrophe=None, connmatrix=None, nodenames=<factory>, classnames=<factory>, mu=None, phi=None, proc=None, pie=None, procid=None, lst=None, fj=None, fjsync=None, fjclassmap=None, isfjaugmented=False, droprule=None, nregions=0, region=None, regionrule=None, regionweight=None, regionsz=None, regionmaxmem=None, regionmembers=None, sync=None, gsync=None, nodeparam=None, routingweights=None, reward=None, rtorig=None, csmask=None, nvars=None, isbasblocking=None, impatienceType=None, impatienceMu=None, impatienceClass=None, impatiencePhi=None, impatiencePhases=None, impatienceProc=None, impatiencePie=None, impatienceDist=None, balkingStrategy=None, balkingThresholds=None, retrialType=None, retrialMu=None, retrialPhi=None, retrialProc=None, retrialMaxAttempts=None, orbitImpatience=None, varsparam=None, markidx=None)[source]
Bases:
objectData structure summarizing network characteristics.
This class is the Python equivalent in native Python. It contains all parameters needed by solvers to analyze a queueing network.
- njobs
(1, K) Population per class (inf for open classes)
- Type:
- nservers
(M, 1) Number of servers per station
- Type:
- rates
(M, K) Service rates
- Type:
- scv
(M, K) Squared coefficient of variation
- Type:
- visits
Dict[int, ndarray] - Chain ID -> (M, K) visit ratios
- Type:
Dict[int, numpy.ndarray]
- inchain
Dict[int, ndarray] - Chain ID -> class indices in chain
- Type:
Dict[int, numpy.ndarray]
- chains
(K, 1) Chain membership per class
- Type:
- refstat
(K, 1) Reference station per class
- Type:
- refclass
(1, C) Reference class per chain
- Type:
- routing
(N, K) Routing strategy matrix
- Type:
- rt
Routing probability matrix
- Type:
numpy.ndarray | None
- isstation
(N, 1) Boolean mask for stations
- Type:
- isstateful
(N, 1) Boolean mask for stateful nodes
- Type:
- isfunction
(M, 1) Boolean mask, STATION-indexed: queue stations that carry setup/delay-off times (function stations)
- Type:
- nodeToStation
(N, 1) Node index -> station index mapping
- Type:
- nodeToStateful
(N, 1) Node index -> stateful index mapping
- Type:
- stationToNode
(M, 1) Station index -> node index mapping
- Type:
- stationToStateful
(M, 1) Station index -> stateful index mapping
- Type:
- statefulToNode
(S, 1) Stateful index -> node index mapping
- Type:
- statefulToStation
(S, 1) Stateful index -> station index mapping
- Type:
- state
Dict State per stateful node
- Type:
Dict[int, numpy.ndarray]
- lldscaling
(M, Nmax) Load-dependent scaling matrix
- Type:
numpy.ndarray | None
- cdscaling
Class-dependent scaling functions
- Type:
Dict | None
- cap
(M, 1) Station capacities
- Type:
numpy.ndarray | None
- classcap
(M, K) Per-class capacities
- Type:
numpy.ndarray | None
- connmatrix
(N, N) Connection matrix
- Type:
numpy.ndarray | None
- __setattr__(name, value)[source]
Override to convert numpy arrays to MatrixArray for API compatibility.
- balkingStrategy: numpy.ndarray | None = None
- cap: numpy.ndarray | None = None
- cdscalingpeak: numpy.ndarray | None = None
- classcap: numpy.ndarray | None = None
- classdeadline: numpy.ndarray | None = None
- classprio: numpy.ndarray | None = None
- connmatrix: numpy.ndarray | None = None
- csmask: numpy.ndarray | None = None
- fj: numpy.ndarray | None = None
- fjclassmap: numpy.ndarray | None = None
- get_stateful_indices()[source]
Get indices of stateful nodes.
- Returns:
Array of node indices that are stateful
- Return type:
- get_station_indices()[source]
Get indices of station nodes.
- Returns:
Array of node indices that are stations
- Return type:
- immfeed: numpy.ndarray | None = None
- impatienceClass: numpy.ndarray | None = None
- impatienceMu: numpy.ndarray | None = None
- impatiencePhases: numpy.ndarray | None = None
- impatiencePhi: numpy.ndarray | None = None
- impatienceType: numpy.ndarray | None = None
- is_valid()[source]
Check if structure is valid.
- Returns:
True if structure passes validation, False otherwise
- Return type:
- isbasblocking: numpy.ndarray | None = None
- iscatastrophe: numpy.ndarray | None = None
- issignal: numpy.ndarray | None = None
- isslc: numpy.ndarray | None = None
- isstatedep: numpy.ndarray | None = None
- lldscaling: numpy.ndarray | None = None
- markidx: numpy.ndarray | None = None
- nvars: numpy.ndarray | None = None
- property obj
Return self for compatibility with wrapper code that accesses .obj
- phases: numpy.ndarray | None = None
- phaseshift: numpy.ndarray | None = None
- phasessz: numpy.ndarray | None = None
- regionrule: numpy.ndarray | None = None
- regionsz: numpy.ndarray | None = None
- regionweight: numpy.ndarray | None = None
- retrialMaxAttempts: numpy.ndarray | None = None
- retrialMu: numpy.ndarray | None = None
- retrialPhi: numpy.ndarray | None = None
- retrialType: numpy.ndarray | None = None
- rt: numpy.ndarray | None = None
- rtnodes: numpy.ndarray | None = None
- schedparam: numpy.ndarray | None = None
- signaltarget: numpy.ndarray | None = None
- syncreply: numpy.ndarray | None = None
- validate()[source]
Validate structural consistency.
- Raises:
ValueError – If structural consistency is violated
- varsparam: numpy.ndarray | None = None
- njobs: numpy.ndarray
- nservers: numpy.ndarray
- rates: numpy.ndarray
- scv: numpy.ndarray
- visits: Dict[int, numpy.ndarray]
- nodevisits: Dict[int, numpy.ndarray]
- inchain: Dict[int, numpy.ndarray]
- chains: numpy.ndarray
- refstat: numpy.ndarray
- refclass: numpy.ndarray
- routing: numpy.ndarray
- isstation: numpy.ndarray
- isstateful: numpy.ndarray
- isfunction: numpy.ndarray
- nodeToStation: numpy.ndarray
- nodeToStateful: numpy.ndarray
- stationToNode: numpy.ndarray
- stationToStateful: numpy.ndarray
- statefulToNode: numpy.ndarray
- statefulToStation: numpy.ndarray
- state: Dict[int, numpy.ndarray]
- stateprior: Dict[int, numpy.ndarray]
- space: Dict[int, numpy.ndarray]
- class NodeType(*values)[source]
Bases:
IntEnumNode types in a queueing network.
NOTE: Values must match lang/base.py NodeType enum.
- SOURCE = 0
- SINK = 1
- QUEUE = 2
- DELAY = 3
- JOIN = 5
- CACHE = 6
- ROUTER = 7
- CLASSSWITCH = 8
- PLACE = 9
- TRANSITION = 10
- LOGGER = 11
- FINITE_CAPACITY_REGION = 12
- class SchedStrategy(*values)[source]
Bases:
IntEnumScheduling strategies.
- LCFSPI = 3
- HOL = 9
- LPS = 17
- SETF = 18
- FCFSPR = 22
- EDF = 23
- JOIN = 25
- EDD = 27
- SRPT = 28
- SRPTPRIO = 29
- LCFSPRIO = 30
- LCFSPRPRIO = 31
- LCFSPIPRIO = 32
- FCFSPRPRIO = 33
- FCFSPIPRIO = 34
- FSP = 36
- PAS = 37
- OI = 38
- class RoutingStrategy(*values)[source]
Bases:
IntEnumRouting strategies.
Values must match MATLAB’s RoutingStrategy constants for JMT compatibility.
- RL = 7
- class DropStrategy(*values)[source]
Bases:
IntEnumDrop strategies for finite capacity.
Values match the MATLAB DropStrategy constants and the JAR jline.lang.constant.DropStrategy ids, which are the interchange encoding of sn.droprule and sn.regionrule. Keep the three Python definitions of this enum (here, lang/base.py, constants.py) numerically identical: they are written and read by different modules over the same sn fields.
- WAITQ = -1
- DROP = 1
- BAS = 2
- BBS = 3
- RSRD = 4
- RETRIAL = 5
- RETRIAL_WITH_LIMIT = 6
- sn_region_members(sn, f, Rmat, memvec)[source]
Station membership mask of finite capacity region f, as a bool array of length M.
Membership is read from sn.regionmembers[f], which the region refresh records directly from the region’s node list. It cannot be derived from sn.region[f]: -1 there means “unbounded”, which is indistinguishable from “not a member”, so a region constrained only by regionlincon (or only by a memory budget) reads as empty and is silently ignored.
Rmat and memvec provide the legacy derivation, used only for an sn built before regionmembers existed (for instance one deserialised from an older model file). That derivation carries the ambiguity above and is not equivalent.
- sn_get_demands_chain(sn)[source]
Calculate new queueing network parameters after aggregating classes into chains.
This function computes chain-level demands, service times, visit ratios, and other parameters by aggregating class-level data based on chain membership.
- Parameters:
sn (NetworkStruct) – NetworkStruct object for the queueing network model
- Returns:
Lchain: (M, C) chain-level demand matrix
STchain: (M, C) chain-level service time matrix
Vchain: (M, C) chain-level visit ratio matrix
alpha: (M, K) class-to-chain weighting matrix
Nchain: (1, C) population per chain
SCVchain: (M, C) chain-level squared coefficient of variation
refstatchain: (C, 1) reference station per chain
- Return type:
SnGetDemandsResult containing chain parameters
- class SnGetDemandsResult(Lchain, STchain, Vchain, alpha, Nchain, SCVchain, refstatchain)[source]
Bases:
objectResult of sn_get_demands_chain calculation.
- Lchain
(M, C) Chain-level demand matrix
- Type:
- STchain
(M, C) Chain-level service time matrix
- Type:
- Vchain
(M, C) Chain-level visit ratio matrix
- Type:
- alpha
(M, K) Class-to-chain weighting matrix
- Type:
- Nchain
(1, C) Population per chain
- Type:
- SCVchain
(M, C) Chain-level squared coefficient of variation
- Type:
- refstatchain
(C, 1) Reference station per chain
- Type:
- Lchain: numpy.ndarray
- STchain: numpy.ndarray
- Vchain: numpy.ndarray
- alpha: numpy.ndarray
- Nchain: numpy.ndarray
- SCVchain: numpy.ndarray
- refstatchain: numpy.ndarray
- sn_deaggregate_chain_results(sn, Lchain, ST, STchain, Vchain, alpha, Qchain, Uchain, Rchain, Tchain, Cchain, Xchain)[source]
Calculate class-based performance metrics from chain-level performance measures.
This function disaggregates chain-level performance metrics (queue lengths, utilizations, response times, throughputs) to class-level metrics using the aggregation factors (alpha).
- Parameters:
sn (NetworkStruct) – NetworkStruct object for the queueing network model
Lchain (numpy.ndarray) – (M, C) Service demands per chain
ST (numpy.ndarray | None) – (M, K) Mean service times per class (optional, computed from rates if None)
STchain (numpy.ndarray) – (M, C) Mean service times per chain
Vchain (numpy.ndarray) – (M, C) Mean visits per chain
alpha (numpy.ndarray) – (M, K) Class aggregation coefficients
Qchain (numpy.ndarray | None) – (M, C) Mean queue-lengths per chain (optional)
Uchain (numpy.ndarray | None) – (M, C) Mean utilization per chain (optional)
Rchain (numpy.ndarray) – (M, C) Mean response time per chain
Tchain (numpy.ndarray) – (M, C) Mean throughput per chain
Cchain (numpy.ndarray | None) – (1, C) Mean system response time per chain. MATLAB (sn_deaggregate_chain_results.m) rejects a non-empty Cchain and always derives C from Little’s law; callers therefore pass None/empty and C is computed as njobs/X, matching MATLAB. A non-empty Cchain is accepted here as an optional extension (disaggregated via alpha at the reference station) but is never supplied on the standard solver paths.
Xchain (numpy.ndarray) – (1, C) Mean system throughput per chain
- Returns:
Q: (M, K) queue lengths
U: (M, K) utilizations
R: (M, K) response times
T: (M, K) throughputs
C: (1, K) system response times (Little’s law: njobs/X)
X: (1, K) system throughputs
- Return type:
SnDeaggregateResult containing class-level performance metrics
- class SnDeaggregateResult(Q, U, R, T, C, X)[source]
Bases:
objectResult of sn_deaggregate_chain_results calculation.
- Q
(M, K) Class-level queue lengths
- Type:
- U
(M, K) Class-level utilizations
- Type:
- R
(M, K) Class-level response times
- Type:
- T
(M, K) Class-level throughputs
- Type:
- C
(1, K) Class-level system response times
- Type:
- X
(1, K) Class-level system throughputs
- Type:
- class ProductFormParams(lam, D, N, Z, mu, S, V)[source]
Bases:
NamedTupleResult of sn_get_product_form_params calculation.
Create new instance of ProductFormParams(lam, D, N, Z, mu, S, V)
- D: numpy.ndarray
Alias for field number 1
- N: numpy.ndarray
Alias for field number 2
- S: numpy.ndarray
Alias for field number 5
- V: numpy.ndarray
Alias for field number 6
- Z: numpy.ndarray
Alias for field number 3
- lam: numpy.ndarray
Alias for field number 0
- mu: numpy.ndarray
Alias for field number 4
- sn_get_product_form_params(sn)[source]
Extract standard product-form parameters from the network structure.
This function extracts class-level parameters from a network structure for use in product-form queueing network analysis.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
lam: Arrival rates for open classes
D: Service demands at queueing stations
N: Population vector
Z: Think times (service demands at delay stations)
mu: Load-dependent service capacity scaling factors
S: Number of servers at queueing stations
V: Visit ratios
- Return type:
ProductFormParams containing
References
MATLAB: matlab/src/api/sn/sn_get_product_form_params.m
- sn_get_residt_from_respt(sn, RN, WH=None)[source]
Compute residence times from response times.
This function converts response times to residence times by accounting for visit ratios at each station.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
RN (numpy.ndarray) – Average response times (M, K)
WH (Dict | None) – Residence time handles (optional)
- Returns:
Average residence times (M, K)
- Return type:
WN
References
MATLAB: matlab/src/api/sn/sn_get_residt_from_respt.m
- sn_get_state_aggr(sn)[source]
Get aggregated state representation.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
Dictionary mapping stateful node index to aggregated state
- Return type:
References
MATLAB: matlab/src/api/sn/sn_get_state_aggr.m
- sn_set_arrival(sn, station_idx, class_idx, rate)[source]
Set arrival rate for a class at a station.
- Parameters:
sn (NetworkStruct) – NetworkStruct object (modified in place)
station_idx (int) – Station index (0-based)
class_idx (int) – Class index (0-based)
rate (float) – Arrival rate
References
MATLAB: matlab/src/api/sn/sn_set_arrival.m
- sn_set_service(sn, station_idx, class_idx, rate, scv=1.0)[source]
Set service rate for a class at a station.
- Parameters:
sn (NetworkStruct) – NetworkStruct object (modified in place)
station_idx (int) – Station index (0-based)
class_idx (int) – Class index (0-based)
rate (float) – Service rate
scv (float) – Squared coefficient of variation (default 1.0 for exponential)
References
MATLAB: matlab/src/api/sn/sn_set_service.m
- sn_set_servers(sn, station_idx, nservers)[source]
Set number of servers at a station.
- Parameters:
sn (NetworkStruct) – NetworkStruct object (modified in place)
station_idx (int) – Station index (0-based)
nservers (int) – Number of servers
References
MATLAB: matlab/src/api/sn/sn_set_servers.m
- sn_set_population(sn, class_idx, njobs)[source]
Set population for a class.
- Parameters:
sn (NetworkStruct) – NetworkStruct object (modified in place)
class_idx (int) – Class index (0-based)
njobs (float) – Number of jobs (inf for open class)
References
MATLAB: matlab/src/api/sn/sn_set_population.m
- sn_set_priority(sn, class_idx, priority)[source]
Set priority for a class.
- Parameters:
sn (NetworkStruct) – NetworkStruct object (modified in place)
class_idx (int) – Class index (0-based)
priority (int) – Priority level (lower = more priority; 0 is highest)
References
MATLAB: matlab/src/api/sn/sn_set_priority.m
- sn_set_routing(sn, source_node, dest_node, source_class, dest_class, prob)[source]
Set routing probability between nodes and classes.
- Parameters:
References
MATLAB: matlab/src/api/sn/sn_set_routing.m
- sn_refresh_visits(sn)[source]
Refresh visit ratios from routing matrix.
This function solves traffic equations to compute visit ratios at each station from the routing probability matrix.
- Parameters:
sn (NetworkStruct) – NetworkStruct object (modified in place)
References
MATLAB: matlab/src/api/sn/sn_refresh_visits.m
- sn_set_fork_fanout(sn, fork_node_idx, fan_out)[source]
Set fork fanout (tasksPerLink) for a Fork node.
Updates the fanOut field in nodeparam for a Fork node.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
fork_node_idx (int) – Node index of the Fork node (0-based)
fan_out (int) – Number of tasks per output link (>= 1)
- Returns:
Modified NetworkStruct
- Raises:
ValueError – If the specified node is not a Fork node
- Return type:
References
MATLAB: matlab/src/api/sn/sn_set_fork_fanout.m
- sn_set_service_batch(sn, rates, scvs=None, auto_refresh=False)[source]
Set service rates for multiple station-class pairs.
Batch update of service rates. NaN values are skipped (not updated). More efficient than calling sn_set_service multiple times.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
rates (numpy.ndarray) – Matrix of new rates (nstations x nclasses), NaN = skip
scvs (numpy.ndarray | None) – Matrix of new SCVs (optional)
auto_refresh (bool) – If True, refresh process fields (default False)
- Returns:
Modified NetworkStruct
- Return type:
References
MATLAB: matlab/src/api/sn/sn_set_service_batch.m
- sn_nonmarkov_toph(sn, options=None)[source]
Convert non-Markovian distributions to Phase-Type using approximation.
This function scans all service and arrival processes in the network structure and converts non-Markovian distributions to Markovian Arrival Processes (MAPs) using the specified approximation method.
Supported non-Markovian distributions: - GAMMA: Gamma distribution - WEIBULL: Weibull distribution - LOGNORMAL: Lognormal distribution - PARETO: Pareto distribution - UNIFORM: Uniform distribution - DET: Deterministic (converted to Erlang)
- Parameters:
sn (NetworkStruct) – NetworkStruct object (from getStruct())
options (Dict[str, Any] | None) – Solver options dict with fields: - config.nonmkv: Method for conversion (‘none’, ‘bernstein’) - config.nonmkvorder: Number of phases for approximation (default 20) - config.preserveDet: Keep deterministic distributions (for MAP/D/c)
- Returns:
Modified NetworkStruct with converted processes
- Return type:
References
MATLAB: matlab/src/api/sn/sn_nonmarkov_toph.m
- class ChainParams(lambda_vec, D, N, Z, mu, S, V)[source]
Bases:
objectChain-aggregated product-form parameters.
- lambda_vec: numpy.ndarray
- mu: numpy.ndarray
- sn_get_arvr_from_tput(sn, TN, TH=None)[source]
Compute average arrival rates at stations from throughputs.
Calculates the average arrival rate at each station in steady-state from the station throughputs and routing matrix.
- Parameters:
sn (NetworkStruct) – Network structure
TN (numpy.ndarray) – Average throughputs at stations (M x R)
TH (numpy.ndarray | None) – Throughput handles (optional)
- Returns:
Average arrival rates at stations (M x R)
- Return type:
AN
References
Original MATLAB: matlab/src/api/sn/sn_get_arvr_from_tput.m
- sn_get_node_arvr_from_tput(sn, TN, TH=None, AN=None)[source]
Compute node arrival rates from station throughputs.
This function handles: - Station nodes: Uses station arrival rates directly - Cache nodes: Only requesting classes arrive (not hit/miss classes) - Non-station nodes (ClassSwitch, Sink): Uses nodevisits-based computation
- Parameters:
sn (NetworkStruct) – Network structure
TN (numpy.ndarray) – Station throughputs (M x R)
TH (numpy.ndarray | None) – Throughput handles (optional)
AN (numpy.ndarray | None) – Station arrival rates (optional, computed if not provided)
- Returns:
Node arrival rates (I x R)
- Return type:
ANn
References
Original MATLAB: matlab/src/api/sn/sn_get_node_arvr_from_tput.m
- sn_get_node_tput_from_tput(sn, TN, TH=None, ANn=None)[source]
Compute node throughputs from station throughputs.
This function handles: - Station nodes: Uses station throughputs directly - Cache nodes: Uses actual hit/miss probabilities if available - Non-station nodes: Uses routing matrix (rtnodes) for computation
- Parameters:
sn (NetworkStruct) – Network structure
TN (numpy.ndarray) – Station throughputs (M x R)
TH (numpy.ndarray | None) – Throughput handles (optional)
ANn (numpy.ndarray | None) – Node arrival rates (optional, computed if not provided)
- Returns:
Node throughputs (I x R)
- Return type:
TNn
References
Original MATLAB: matlab/src/api/sn/sn_get_node_tput_from_tput.m
- sn_get_product_form_chain_params(sn)[source]
Extract product-form parameters aggregated by chain.
Extracts parameters from a network structure and aggregates them by chain for use in product-form analysis methods.
- Parameters:
sn (NetworkStruct) – Network structure
- Returns:
ChainParams with lambda_vec, D, N, Z, mu, S, V
- Return type:
References
Original MATLAB: matlab/src/api/sn/sn_get_product_form_chain_params.m
- sn_set_routing_prob(sn, from_stateful, from_class, to_stateful, to_class, prob, auto_refresh=False)[source]
Set a routing probability between two stateful node-class pairs.
Updates a single entry in the rt matrix.
- Parameters:
sn (NetworkStruct) – Network structure
from_stateful (int) – Source stateful node index (0-based)
from_class (int) – Source class index (0-based)
to_stateful (int) – Destination stateful node index (0-based)
to_class (int) – Destination class index (0-based)
prob (float) – Routing probability [0, 1]
auto_refresh (bool) – If True, refresh visit ratios (default False)
- Returns:
Modified network structure
- Return type:
References
Original MATLAB: matlab/src/api/sn/sn_set_routing_prob.m
- sn_is_closed_model(sn)[source]
Check if the network model is closed (all finite populations).
A closed model has all finite job populations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if the network is a closed model
- Return type:
- sn_is_open_model(sn)[source]
Check if the network model is open (all infinite populations).
An open model has only infinite (open) job classes.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if the network is an open model
- Return type:
- sn_is_mixed_model(sn)[source]
Check if the network model is mixed (both open and closed classes).
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if the network has both open and closed classes
- Return type:
- sn_is_population_model(sn)[source]
Check if the network model is a population model.
A population model uses only delay-like scheduling strategies (INF, PS, PSPRIO, DPS, GPS, GPSPRIO, DPSPRIO, EXT), has no priorities, and no fork-join topology.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if model is population-based
- Return type:
- sn_has_closed_classes(sn)[source]
Check if the network has closed (finite population) classes.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one closed class
- Return type:
- sn_has_open_classes(sn)[source]
Check if the network has open (infinite population) classes.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one open class
- Return type:
- sn_has_mixed_classes(sn)[source]
Check if the network has both open and closed classes.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has both open and closed classes
- Return type:
- sn_has_single_class(sn)[source]
Check if the network has exactly one class.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has exactly one class
- Return type:
- sn_has_multi_class(sn)[source]
Check if the network has multiple classes.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has more than one class
- Return type:
- sn_has_multiple_closed_classes(sn)[source]
Check if the network has multiple closed classes.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has more than one closed class
- Return type:
- sn_has_single_chain(sn)[source]
Check if the network has exactly one chain.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has exactly one chain
- Return type:
- sn_has_multi_chain(sn)[source]
Check if the network has multiple chains.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has more than one chain
- Return type:
- sn_has_fcfs(sn)[source]
Check if the network has any FCFS (First-Come First-Served) stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one FCFS station
- Return type:
- sn_has_ps(sn)[source]
Check if the network has any PS (Processor Sharing) stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one PS station
- Return type:
- sn_has_inf(sn)[source]
Check if the network has any INF (Infinite Server/Delay) stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one INF station
- Return type:
- sn_has_lcfs(sn)[source]
Check if the network has any LCFS (Last-Come First-Served) stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one LCFS station
- Return type:
- sn_has_lcfspr(sn)[source]
Check if the network has any LCFS-PR (LCFS Preemptive Resume) stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one LCFS-PR station
- Return type:
- sn_has_lcfs_pr(sn)[source]
Check if the network has any LCFS-PR (LCFS Preemptive Resume) stations.
This is an alias for sn_has_lcfspr, matching the MATLAB function name.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one LCFS-PR station
- Return type:
- sn_has_lcfs_pi(sn)[source]
Check if the network has any LCFS-PI (LCFS Preemptive Identical) stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one LCFS-PI station
- Return type:
- sn_has_siro(sn)[source]
Check if the network has any SIRO (Service In Random Order) stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one SIRO station
- Return type:
- sn_has_dps(sn)[source]
Check if the network has any DPS (Discriminatory Processor Sharing) stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one DPS station
- Return type:
- sn_has_dps_prio(sn)[source]
Check if the network has any DPS with priority stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one DPS-PRIO station
- Return type:
- sn_has_gps(sn)[source]
Check if the network has any GPS (Generalized Processor Sharing) stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one GPS station
- Return type:
- sn_has_gps_prio(sn)[source]
Check if the network has any GPS with priority stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one GPS-PRIO station
- Return type:
- sn_has_ps_prio(sn)[source]
Check if the network has any PS with priority stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one PS-PRIO station
- Return type:
- sn_has_hol(sn)[source]
Check if the network has any HOL (Head of Line) priority stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one HOL station
- Return type:
- sn_has_lps(sn)[source]
Check if the network has any LPS (Least Progress Scheduling) stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one LPS station
- Return type:
- sn_has_setf(sn)[source]
Check if the network has any SETF (Shortest Elapsed Time First) stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one SETF station
- Return type:
- sn_has_sept(sn)[source]
Check if the network has any SEPT (Shortest Expected Processing Time) stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one SEPT station
- Return type:
- sn_has_lept(sn)[source]
Check if the network has any LEPT (Longest Expected Processing Time) stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one LEPT station
- Return type:
- sn_has_sjf(sn)[source]
Check if the network has any SJF (Shortest Job First) stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one SJF station
- Return type:
- sn_has_ljf(sn)[source]
Check if the network has any LJF (Longest Job First) stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one LJF station
- Return type:
- sn_has_polling(sn)[source]
Check if the network has any polling stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has at least one polling station
- Return type:
- sn_has_homogeneous_scheduling(sn, strategy)[source]
Check if the network uses an identical scheduling strategy at every station.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
strategy (int) – SchedStrategy value to check for
- Returns:
True if all stations use the specified strategy
- Return type:
- sn_has_multi_class_fcfs(sn)[source]
Check if the network has an FCFS station that serves multiple classes.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if any FCFS station serves more than one class
- Return type:
- sn_has_multi_class_heter_fcfs(sn)[source]
Check if network has multiclass heterogeneous FCFS stations.
A heterogeneous FCFS station has different service rates for different classes. Uses MATLAB’s range() check: max(rates) - min(rates) > 0 across all classes at each FCFS station.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has FCFS stations with heterogeneous class rates
- Return type:
- sn_has_multi_class_heter_exp_fcfs(sn)[source]
Check if network has multiclass heterogeneous exponential FCFS stations.
Returns true if any FCFS station has heterogeneous rates AND all service time SCVs at that station are approximately 1.0 (exponential).
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has FCFS stations with heterogeneous exponential service
- Return type:
- sn_has_multi_server(sn)[source]
Check if the network has any multi-server stations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if any station has more than one server
- Return type:
- sn_has_load_dependence(sn)[source]
Check if the network has load-dependent service.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has load-dependent scaling
- Return type:
- sn_has_fork_join(sn)[source]
Check if the network uses fork and/or join nodes.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has fork-join topology
- Return type:
- sn_has_priorities(sn)[source]
Check if the network uses class priorities.
In LINE, priority 0 is default (no priority). Values > 0 indicate priority classes are in use.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if any class has priority > 0
- Return type:
- sn_has_class_switching(sn)[source]
Check if the network has class switching.
Class switching is indicated by the number of classes differing from the number of chains.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if number of classes differs from number of chains
- Return type:
- sn_has_fractional_populations(sn)[source]
Check if the network has fractional (non-integer) populations.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if any class has fractional population
- Return type:
- sn_has_sd_routing(sn)[source]
Check if the network has state-dependent routing strategies.
State-dependent routing strategies violate the product-form assumption. These include Round-Robin, Weighted Round-Robin, Join Shortest Queue, Power of K Choices, and Reinforcement Learning.
Product-form requires state-independent (Markovian) routing. PROB and RAND are product-form compatible.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has state-dependent routing
- Return type:
- sn_has_product_form(sn)[source]
Check if the network has a known product-form solution.
A network has product form if: - All stations use INF, PS, FCFS, LCFS-PR, or EXT scheduling - No multiclass heterogeneous FCFS - No priorities - No fork-join
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network has product-form solution
- Return type:
- sn_has_bursty_arrival(sn)[source]
Check whether any external arrival process is bursty (non-renewal).
Returns True if any Source station has an arrival process with autocorrelated inter-arrival times (a non-renewal Markovian arrival process such as an MMPP/MAP), as opposed to a renewal process (Poisson, or any i.i.d. renewal process such as Erlang/HyperExp/Coxian/APH). Detection is exact: a MAP with matrices (D0,D1) is renewal iff D1 equals its rank-one renewal form t0*pie, where t0 = -D0*e and pie is the embedded stationary vector; any departure signals correlation between inter-arrival times.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if some external arrival process is non-renewal (bursty).
- Return type:
- sn_has_product_form_not_het_fcfs(sn)[source]
Check if network has product form except for heterogeneous FCFS.
This checks: - All stations use INF, PS, FCFS, LCFSPR, or EXT scheduling - No priorities, no fork-join, no state-dependent routing - At FCFS stations, all active class SCVs are approximately 1 (exponential)
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network would have product form without heterogeneous FCFS
- Return type:
- sn_has_product_form_except_multi_class_heter_exp_fcfs(sn)[source]
Check if network has product form except for multiclass heterogeneous exponential FCFS.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if network would have product form without multiclass heter exp FCFS
- Return type:
- sn_is_state_valid(sn)[source]
Check if the network state is valid.
- Parameters:
sn (NetworkStruct) – NetworkStruct object
- Returns:
True if state is valid
- Return type:
- sn_fj_visits_spn(sn)[source]
Compute fork-join node visit ratios via auxiliary SPN models.
For each class that passes through a fork-join pair, builds an auxiliary closed SPN with population B (max leaf count across outermost forks). The SPN is solved with SolverCTMC and the throughput ratios give the per-node visit ratios.
- Parameters:
sn (NetworkStruct) – NetworkStruct describing the queueing network.
- Returns:
List of numpy arrays (one per chain), each of shape (nnodes, nclasses) with visit ratios normalized so the reference station has value 1.
- Return type:
- sn_print(sn, file=None)[source]
Print comprehensive information about a NetworkStruct object.
This function displays all fields, matrices, lists, and maps in a formatted manner useful for debugging and inspection of network structures.
- Parameters:
sn (NetworkStruct) – Network structure to inspect
file – Output file (default: sys.stdout)
References
MATLAB: matlab/src/api/sn/sn_print.m
- sn_print_routing_matrix(sn, onlyclass=None, file=None)[source]
Print the routing matrix of the network.
This function displays the routing probabilities between nodes and classes in a human-readable format.
- Parameters:
sn (NetworkStruct) – Network structure
onlyclass (Any | None) – Optional filter for a specific class (object with ‘name’ attribute)
file – Output file (default: sys.stdout)
References
MATLAB: matlab/src/api/sn/sn_print_routing_matrix.m
- sn_refresh_process_fields(sn, station_idx, class_idx)[source]
Refresh process fields based on rate and SCV values.
Updates mu, phi, proc, pie, phases based on current rate and SCV values. - SCV = 1.0: Exponential (1 phase) - SCV < 1.0: Erlang approximation - SCV > 1.0: Hyperexponential(2) approximation
- Parameters:
sn (NetworkStruct) – Network structure (modified in place)
station_idx (int) – Station index (0-based)
class_idx (int) – Class index (0-based)
- Returns:
Modified network structure
- Return type:
References
MATLAB: matlab/src/api/sn/sn_refresh_process_fields.m
- sn_rtnodes_to_rtorig(sn)[source]
Convert node routing matrix to the original routing matrix format.
This function converts the node-level routing matrix to the original routing matrix format, excluding class-switching nodes.
- Parameters:
sn (NetworkStruct) – Network structure
- Returns:
rtorigcell: Dictionary representation {(r,s): ndarray} rtorig: Sparse/dense matrix representation
- Return type:
Tuple of (rtorigcell, rtorig) where
References
MATLAB: matlab/src/api/sn/sn_rtnodes_to_rtorig.m
Non-Product-Form Networks (line_solver.api.npfqn)
Non-Product-Form Queueing Network (NPFQN) algorithms.
Native Python implementations for approximating performance of non-product-form queueing networks.
- Key algorithms:
npfqn_nonexp_approx: Non-exponential distribution approximation npfqn_traffic_merge: Merge multiple MMAP traffic flows npfqn_traffic_merge_cs: Merge traffic flows with class switching npfqn_traffic_split_cs: Split traffic flows with class switching
- npfqn_nonexp_approx(method, sn, ST, V, SCV, Tin, Uin, gamma, nservers)[source]
Approximates non-product-form queueing networks using the specified method.
This function adjusts service times and other parameters to account for non-exponential service time distributions in product-form analysis.
- Parameters:
method (str) – Approximation method (“default”, “none”, “hmva”, “interp”)
sn (NetworkStruct) – Network structure
ST (numpy.ndarray) – Service time matrix (M x K)
V (numpy.ndarray | None) – Visit ratios matrix (M x K), optional
SCV (numpy.ndarray) – Squared coefficient of variation matrix (M x K)
Tin (numpy.ndarray) – Initial throughput matrix (M x K)
Uin (numpy.ndarray) – Initial utilization matrix (M x K)
gamma (numpy.ndarray) – Gamma correction matrix (M x 1)
nservers (numpy.ndarray) – Number of servers matrix (M x 1)
- Returns:
NpfqnNonexpApproxResult with updated matrices
- Raises:
ValueError – If unknown approximation method is specified
- Return type:
- class NpfqnNonexpApproxResult(ST, gamma, nservers, rho, scva, scvs, eta)[source]
Bases:
objectResult of non-exponential approximation.
- ST: numpy.ndarray
- gamma: numpy.ndarray
- nservers: numpy.ndarray
- rho: numpy.ndarray
- scva: numpy.ndarray
- scvs: numpy.ndarray
- eta: numpy.ndarray
- npfqn_traffic_merge(MMAPa, config_merge='default', config_compress=None)[source]
Merge multiple MMAP traffic flows.
Combines multiple MMAPs using specified aggregation strategies. Supports various merge configurations for different network topologies.
- Parameters:
MMAPa (Dict[int, List[numpy.ndarray] | None]) – Dictionary of MMAP traffic flows to be merged. Keys are integer indices, values are MMAP lists [D0, D1, …].
config_merge (str) – Merge configuration. Options: - “default”, “super”: Use MMAP superposition - “mixture”: Apply mixture fitting after superposition - “interpos”: Interposition method (falls back to super)
config_compress (str | None) – Compression configuration. Options: - None, “none”: No compression - “default”: Apply default compression
- Returns:
Merged and normalized MMAP, or None if input is empty.
- Raises:
RuntimeError – If unsupported merge configuration is provided.
- Return type:
List[numpy.ndarray] | None
Example
>>> mmap1 = [np.array([[-1.0]]), np.array([[1.0]])] >>> mmap2 = [np.array([[-2.0]]), np.array([[2.0]])] >>> result = npfqn_traffic_merge({0: mmap1, 1: mmap2})
- npfqn_traffic_merge_cs(MMAPs, prob, config='default')[source]
Merge MMAP traffic flows with class switching.
Combines multiple MMAPs while applying class switching transformations based on the probability matrix.
- Parameters:
MMAPs (Dict[int, List[numpy.ndarray]]) – Dictionary of MMAP traffic flows indexed by source.
prob (numpy.ndarray) –
Class switching probability matrix ((n*R) x R) where: - n is the number of sources - R is the number of classes - prob[(i-1)*R + r, s] = probability that class r from source i
becomes class s in the merged stream
config (str) – Merge configuration (“default” or “super”).
- Returns:
Merged MMAP with class switching applied, or None if empty.
- Return type:
List[numpy.ndarray] | None
- Algorithm:
Apply mmap_mark to each source MMAP to encode class switching
Superpose all marked MMAPs
Return result
Example
>>> mmap1 = [np.array([[-1.0]]), np.array([[0.5]]), np.array([[0.5]])] >>> mmap2 = [np.array([[-2.0]]), np.array([[1.0]]), np.array([[1.0]])] >>> prob = np.array([[0.8, 0.2], [0.3, 0.7], [0.6, 0.4], [0.5, 0.5]]) >>> result = npfqn_traffic_merge_cs({0: mmap1, 1: mmap2}, prob)
- npfqn_traffic_split_cs(MMAP_input, P)[source]
Split MMAP traffic flows with class switching.
Decomposes a single MMAP into multiple MMAPs based on routing probabilities and class switching matrix.
- Parameters:
MMAP_input (List[numpy.ndarray]) – Input MMAP as list [D0, D1, D2, …].
P (numpy.ndarray) –
Class switching probability matrix (R x J) where: - R is the number of arrival classes - J = M * R where M is the number of destinations - P[r, (jst-1)*R + s] = probability that class r arrival
becomes class s at destination jst
- Returns:
Dictionary mapping destination index to split MMAP. Keys are 0-indexed destination indices.
- Return type:
Dict[int, List[numpy.ndarray] | None]
- Algorithm:
Parse dimensions from P matrix
For each destination, create MMAP with weighted marking matrices
Normalize each result
Example
>>> mmap = [np.array([[-3.0]]), np.array([[1.0]]), np.array([[2.0]])] >>> P = np.array([[0.8, 0.2, 0.5, 0.5], [0.3, 0.7, 0.6, 0.4]]) >>> result = npfqn_traffic_split_cs(mmap, P)
- npfqn_sqd(sn, N=None, calibration_mode=0, server_blocking_time=True, neighbor_mode='downstream', v1_policy='compound', initial_v1=None)[source]
Solve a BAS closed network from its NetworkStruct.
- Parameters:
sn (NetworkStruct) – chain-aggregated network structure
N (int | None) – total closed-class population (defaults to sn.nclosedjobs)
calibration_mode (int) – 0=base, 1=fixed heuristic, 2=blocking-aware
server_blocking_time (bool) – add a manufacturing-blocking term to server time
neighbor_mode (str) – ‘downstream’ (routed) or ‘ownserver’ blocking aggregation
v1_policy (str) – ‘compound’ or ‘fresh’ load-dependent rate-scale update
initial_v1 (numpy.ndarray | None) – optional per-station initial V1 (None = _INITIAL_V1)
- Returns:
NpfqnSqdResult with per-station X, Q, U, R.
- Return type:
- class NpfqnSqdResult(X, Q, U, R)[source]
Bases:
objectPer-station results of the BAS approximation (single chain).
- X
(M,) per-station throughput
- Type:
- Q
(M,) per-station queue length
- Type:
- U
(M,) per-station utilization
- Type:
- R
(M,) per-station residence time
- Type:
- npfqn_rqna_weight(t)[source]
Canonical RBM correlation weight function w*(t) used by the RQNA.
w*(t) = 1 - (1 - c*(t))/(2 t), where c*(t) is the correlation function of the stationary version of canonical reflected Brownian motion (drift -1, diffusion coefficient 1),
c*(t) = 2(1 - 2t - t^2) Phi^c(sqrt(t)) + 2 sqrt(t) phi(sqrt(t)) (1 + t),
with Phi^c the standard-normal complementary cdf and phi its density. The weight is monotonically increasing with w*(0)=0 and w*(Inf)=1.
Reference: Whitt and You (2018), eqs. (24)-(25).
- Parameters:
t – scalar or array of nonnegative time arguments
- Returns:
Weight(s) w*(t) in [0,1], same shape as t (scalar in -> float out).
- npfqn_traffic_idc(lambda0, P, c2a0, a0IdcFun, mu, cs2, sIdcFun, corrections=None)[source]
- Traffic variability equations for the RQNA. Assembles and solves:
the limiting variability equations (eq. 42/44) for the asymptotic total-arrival variability parameters c2_{a,i} = I_{a,i}(Inf);
a solver (ctx.IaFun) for the time-dependent IDC equations (eq. 40/43), returning I_{a,i}(t) for all internal arrival flows, using the default correction terms alpha_{i,j} (eq. 34) and beta_i (eqs. 38-39) and tuning function h(rho)=rho^2.
Models a single-class open network of K single-server FCFS queues with Markovian routing P (P[i,j]=p_{i,j}).
- Parameters:
lambda0 – (K,) external arrival rate into each queue
P – (K,K) routing matrix among queues
c2a0 – (K,) asymptotic IDC (SCV) of each external arrival process
a0IdcFun – callable a0IdcFun(t) -> (K,) external arrival IDC I_{a,0,i}(t)
mu – (K,) service rate at each queue
cs2 – (K,) service SCV c2_{s,i}
sIdcFun – callable sIdcFun(t) -> (K,) service IDC I_{s,i}(t)
corrections – optional dict with ‘alpha’/’beta’ bool toggles
- Returns:
_TrafficIdcContext with lambda, rho, Xi, c2a, c2d, c2aij, c2x fields and method IaFun(t).
Polling Systems (line_solver.api.polling)
Polling System Analysis Algorithms.
Native Python implementations for analyzing polling/vacation queue systems with various disciplines.
- Key algorithms:
polling_qsys_exhaustive: Exhaustive polling discipline polling_qsys_gated: Gated polling discipline polling_qsys_1limited: 1-Limited polling discipline
- polling_qsys_exhaustive(arvMAPs, svcMAPs, switchMAPs)[source]
Compute exact mean waiting times for exhaustive polling system.
In exhaustive polling, the server continues to serve a queue until it becomes empty before moving to the next queue.
Based on Takagi, ACM Computing Surveys, Vol. 20, No. 1, 1988, eq (15).
- Parameters:
arvMAPs (List[Tuple[numpy.ndarray, numpy.ndarray]]) – List of arrival process MAPs, each as (D0, D1) tuple.
svcMAPs (List[Tuple[numpy.ndarray, numpy.ndarray]]) – List of service process MAPs, each as (D0, D1) tuple.
switchMAPs (List[Tuple[numpy.ndarray, numpy.ndarray]]) – List of switching time MAPs, each as (D0, D1) tuple.
- Returns:
Array of mean waiting times for each queue.
- Return type:
- polling_qsys_gated(arvMAPs, svcMAPs, switchMAPs)[source]
Compute exact mean waiting times for gated polling system.
In gated polling, the server serves all customers present at the beginning of a visit period.
Based on Takagi, ACM Computing Surveys, Vol. 20, No. 1, 1988, eq (20).
- Parameters:
arvMAPs (List[Tuple[numpy.ndarray, numpy.ndarray]]) – List of arrival process MAPs, each as (D0, D1) tuple.
svcMAPs (List[Tuple[numpy.ndarray, numpy.ndarray]]) – List of service process MAPs, each as (D0, D1) tuple.
switchMAPs (List[Tuple[numpy.ndarray, numpy.ndarray]]) – List of switching time MAPs, each as (D0, D1) tuple.
- Returns:
Array of mean waiting times for each queue.
- Return type:
- polling_qsys_1limited(arvMAPs, svcMAPs, switchMAPs)[source]
Compute exact mean waiting times for 1-limited polling system.
In 1-limited polling, the server serves at most one customer from each queue before moving to the next queue.
Based on Takagi, ACM Computing Surveys, Vol. 20, No. 1, 1988, eq (20).
- Parameters:
arvMAPs (List[Tuple[numpy.ndarray, numpy.ndarray]]) – List of arrival process MAPs, each as (D0, D1) tuple.
svcMAPs (List[Tuple[numpy.ndarray, numpy.ndarray]]) – List of service process MAPs, each as (D0, D1) tuple.
switchMAPs (List[Tuple[numpy.ndarray, numpy.ndarray]]) – List of switching time MAPs, each as (D0, D1) tuple.
- Returns:
Array of mean waiting times for each queue.
- Return type:
- polling_qsys_decrementing(arvMAPs, svcMAPs, switchMAPs)[source]
Compute exact mean waiting times for a symmetric decrementing (semiexhaustive) polling system with open (Poisson) arrivals.
In decrementing service, the server serves a queue until the number of jobs present drops to one less than the number found at the polling instant. The symmetric system admits the exact closed form of Pittel (1973) and Takagi (1984); see Takagi, ACM Computing Surveys, Vol. 20, No. 1, 1988, eq (28). No exact closed form for the individual E[W_i] is known for asymmetric decrementing systems, so this analysis is restricted to the symmetric case.
- Parameters:
arvMAPs (List[Tuple[numpy.ndarray, numpy.ndarray]]) – List of arrival process MAPs, each as (D0, D1) tuple.
svcMAPs (List[Tuple[numpy.ndarray, numpy.ndarray]]) – List of service process MAPs, each as (D0, D1) tuple.
switchMAPs (List[Tuple[numpy.ndarray, numpy.ndarray]]) – List of switching time MAPs, each as (D0, D1) tuple.
- Returns:
Array of mean waiting times for each queue (all equal, symmetric case).
- Return type:
Loss Networks (line_solver.api.lossn)
Loss Network Analysis Algorithms.
Native Python implementations for analyzing loss networks using Erlang formulas and related methods.
- Key algorithms:
lossn_erlangfp: Erlang fixed-point algorithm for loss networks erlang_b: Erlang B blocking probability erlang_c: Erlang C delay probability
- lossn_erlangfp(nu, A, c, tol=1e-8, max_iter=1000)[source]
Erlang fixed point approximation for loss networks.
Calls (jobs) on route (class) r arrive according to Poisson rate nu_r. Call service times on route r have unit mean.
- The link capacity requirements are:
sum_r A[j,r] * n[j,r] < c[j]
for all links j, where n[j,r] counts calls on route r on link j.
- Parameters:
nu (numpy.ndarray) – Arrival rates vector (R,) for each route.
A (numpy.ndarray) – Capacity requirement matrix (J, R) - A[j,r] is capacity required on link j by route r.
c (numpy.ndarray) – Capacity vector (J,) - c[j] is capacity of link j.
tol (float) – Convergence tolerance.
max_iter (int) – Maximum iterations.
- Returns:
qlen: Mean queue-length for each route (R,)
loss: Loss probability for each route (R,)
eblock: Blocking probability for each link (J,)
niter: Number of iterations
- Return type:
Tuple of (qlen, loss, eblock, niter) where
Example
>>> nu = np.array([0.3, 0.1]) >>> A = np.array([[1, 1], [1, 4]]) # 2 links, 2 routes >>> c = np.array([1, 3]) >>> qlen, loss, eblock, niter = lossn_erlangfp(nu, A, c)
- erlang_b(offered_load, servers)[source]
Compute Erlang B blocking probability.
The Erlang B formula gives the probability that an arriving call is blocked in an M/M/c/c loss system.
- Parameters:
- Returns:
Blocking probability.
- Return type:
Example
>>> erlang_b(10.0, 12) # Offered load 10 Erlang, 12 channels 0.1054...
- erlang_c(offered_load, servers)[source]
Compute Erlang C delay probability.
The Erlang C formula gives the probability that an arriving call must wait in an M/M/c queue.
- Parameters:
- Returns:
Delay probability (probability of waiting).
- Return type:
Example
>>> erlang_c(10.0, 12) # Offered load 10 Erlang, 12 agents
- lossn_mci(nu, A, C, samples=100000, gamma=None, seed=None, alpha=0.05)[source]
Monte Carlo importance-sampling summation for loss networks.
A loss network has links j=1..J with capacity C[j] and classes r=1..R with offered load nu[r] and per-link circuit requirement A[j,r]. The state n is feasible iff A @ n <= C (set Omega). The product-form normalization constant is g(C) = sum_{n in Omega} prod_r nu[r]**n_r/n_r!. Class-r acceptance is g(C-A[:,r])/g(C) = 1 - beta_r.
- States are drawn from the importance distribution (Eq. 6)
p(n) = (1/c) prod_r gamma_r**n_r / n_r!
over the box {0..N_1} x … x {0..N_R}, N_r = min_j floor(C_j/A_jr). Ratio estimators (Eq. 8) yield g and blocking with delta-method confidence intervals.
- Parameters:
nu (numpy.ndarray) – Offered load per class (R,).
A (numpy.ndarray) – Circuit requirement matrix (J, R).
C (numpy.ndarray) – Link capacity vector (J,).
samples (int) – Number of Monte Carlo samples.
gamma (numpy.ndarray | None) – Importance-sampling parameters (R,); default is the Section 3.4 heuristic.
seed (int | None) – RNG seed for reproducibility.
alpha (float) – Confidence-interval significance level (default 0.05).
- Returns:
qlen: Mean carried load E[n_r] per class (R,).
loss: Blocking probability beta_r per class (R,).
lG: Log of the estimated normalization constant g(C).
ci: dict with ‘accept’ (R,2), ‘loss’ (R,2), ‘acceptPoint’ (R,), ‘lossPoint’ (R,), ‘level’.
nsamples: Number of samples used.
- Return type:
Tuple (qlen, loss, lG, ci, nsamples) where
Layered Stochastic Networks (line_solver.api.lsn)
Layered Stochastic Network (LSN) utilities.
Native Python implementations for layered queueing network analysis.
- Key functions:
lsn_max_multiplicity: Compute maximum multiplicity for tasks in a layered network.
- Key classes:
LayeredNetworkStruct: Structure representing a layered network. LayeredNetworkElement: Enumeration of layered network element types.
- class LayeredNetworkElement(*values)[source]
Bases:
IntEnumTypes of elements in a layered network.
- TASK = 1
- ENTRY = 2
- ACTIVITY = 3
- PROCESSOR = 4
- HOST = 5
- class LayeredNetworkStruct(dag, mult, type, isref)[source]
Bases:
objectStructure representing a layered network for LSN analysis.
- dag
Directed acyclic graph adjacency matrix (n x n). dag[i,j] > 0 indicates an edge from node i to node j.
- Type:
- mult
Multiplicity (max concurrent instances) for each node (n,).
- Type:
- type
Node type for each node (n,), using LayeredNetworkElement values.
- Type:
- isref
Reference task flags (n,). Non-zero indicates a reference task.
- Type:
- dag: numpy.ndarray
- mult: numpy.ndarray
- type: numpy.ndarray
- isref: numpy.ndarray
- kahn_topological_sort(adjacency)[source]
Perform Kahn’s algorithm for topological sorting.
- Parameters:
adjacency (numpy.ndarray) – Adjacency matrix where adjacency[i,j] > 0 means edge i -> j.
- Returns:
List of node indices in topological order.
- Raises:
ValueError – If the graph contains a cycle.
- Return type:
- lsn_max_multiplicity(lsn)[source]
Compute the maximum multiplicity for each task in a layered network.
This function uses flow analysis based on Kahn’s topological sorting algorithm to determine the maximum sustainable throughput for each task, considering both the incoming flow and the multiplicity constraints.
- Parameters:
lsn (LayeredNetworkStruct) – The layered network structure containing task dependencies and constraints.
- Returns:
Matrix of maximum multiplicities for each task in the network (n x 1).
- Return type:
- Algorithm:
Build binary adjacency graph from DAG
Apply Kahn’s topological sort to determine processing order
Initialize inflow from reference tasks
For each node in topological order: - outflow = min(inflow, multiplicity constraint) - Propagate outflow to downstream nodes
Handle unreachable tasks (infinite multiplicity)
Example
>>> lsn = LayeredNetworkStruct( ... dag=np.array([[0, 1, 0], [0, 0, 1], [0, 0, 0]]), ... mult=np.array([2, 3, 5]), ... type=np.array([1, 1, 1]), ... isref=np.array([1, 0, 0]) ... ) >>> max_mult = lsn_max_multiplicity(lsn)
Trace Analysis (line_solver.api.trace)
Trace Analysis Functions.
Native Python implementations for statistical analysis of empirical trace data including means, variances, correlations, and index of dispersion.
- Key functions:
trace_mean: Mean of trace data trace_var: Variance of trace data trace_scv: Squared coefficient of variation trace_acf: Autocorrelation function trace_summary: Comprehensive summary statistics
- trace_mean(trace)[source]
Compute the arithmetic mean of trace data.
- Parameters:
trace (numpy.ndarray | list) – Array of trace values.
- Returns:
Mean value of the trace.
- Return type:
Example
>>> trace_mean([1.0, 2.0, 3.0, 4.0, 5.0]) 3.0
- trace_var(trace)[source]
Compute the variance of trace data.
Uses population variance (ddof=0) for consistency with Kotlin.
- Parameters:
trace (numpy.ndarray | list) – Array of trace values.
- Returns:
Variance of the trace.
- Return type:
Example
>>> trace_var([1.0, 2.0, 3.0, 4.0, 5.0]) 2.0
- trace_scv(trace)[source]
Compute the squared coefficient of variation (SCV).
SCV = Var(X) / E[X]^2
- Parameters:
trace (numpy.ndarray | list) – Array of trace values.
- Returns:
Squared coefficient of variation.
- Return type:
Example
>>> trace_scv([1.0, 2.0, 3.0]) # Var=0.667, Mean=2, SCV=0.167
- trace_acf(trace, lags=None)[source]
Compute the autocorrelation function at specified lags.
- Parameters:
trace (numpy.ndarray | list) – Array of trace values.
lags (numpy.ndarray | list) – Array of lag values (default: [1]).
- Returns:
Array of autocorrelation values at each lag.
- Return type:
Example
>>> trace = np.random.randn(100) >>> acf = trace_acf(trace, [1, 2, 3])
- trace_gamma(trace, limit=1000)[source]
Estimate the autocorrelation decay rate of a trace.
- Parameters:
trace (numpy.ndarray | list) – Array of trace values.
limit (int) – Maximum lag considered.
- Returns:
Array containing [GAMMA, RHO0, RESIDUALS].
- Return type:
Example
>>> gamma, rho0, residuals = trace_gamma(trace_data)
- trace_iat2counts(trace, scale)[source]
Compute the counting process from inter-arrival times.
- Parameters:
trace (numpy.ndarray | list) – Array of inter-arrival times.
scale (float) – Time scale for counting.
- Returns:
Array of counts after scale units of time from each arrival.
- Return type:
Example
>>> iat = [0.5, 0.3, 0.8, 0.2, 0.4] >>> counts = trace_iat2counts(iat, 1.0)
- trace_idi(trace, kset, option=None, n=1)[source]
Compute the Index of Dispersion for Intervals.
- Parameters:
trace (numpy.ndarray | list) – Array of trace values.
kset (numpy.ndarray | list) – Set of k values to compute IDI for.
option (str) – Aggregation option (None, ‘aggregate’, ‘aggregate-mix’).
n (int) – Aggregation parameter.
- Returns:
Tuple of (IDI values, support values).
- Return type:
Example
>>> idi, support = trace_idi(trace_data, [10, 20, 50])
- trace_idc(trace)[source]
Compute the Index of Dispersion for Counts.
Asymptotically equal to IDI.
- Parameters:
trace (numpy.ndarray | list) – Array of trace values.
- Returns:
IDC value.
- Return type:
Example
>>> idc = trace_idc(inter_arrival_times)
- trace_pmf(X)[source]
Compute the probability mass function of discrete data.
- Parameters:
X (numpy.ndarray | list) – Array of discrete values.
- Returns:
Tuple of (PMF values, unique values).
- Return type:
Example
>>> pmf, values = trace_pmf([1, 2, 2, 3, 3, 3])
- trace_shuffle(trace)[source]
Shuffle trace data randomly.
- Parameters:
trace (numpy.ndarray | list) – Array of trace values.
- Returns:
Shuffled trace array.
- Return type:
Example
>>> shuffled = trace_shuffle([1, 2, 3, 4, 5])
- trace_joint(trace, lag, order)[source]
Compute joint moments E[X^{k_1}_{i} * X^{k_2}_{i+j} * …].
- Parameters:
trace (numpy.ndarray | list) – Array of trace values.
lag (numpy.ndarray | list) – Cumulative lag values.
order (numpy.ndarray | list) – Moment orders.
- Returns:
Joint moment value.
- Return type:
Example
>>> jm = trace_joint(trace, [0, 1], [1, 1]) # E[X_i * X_{i+1}]
- trace_iat2bins(trace, scale)[source]
Compute counts in bins with specified timescale.
- Parameters:
trace (numpy.ndarray | list) – Array of inter-arrival times.
scale (float) – Bin timescale.
- Returns:
Tuple of (counts per bin, bin membership for each element).
- Return type:
Example
>>> counts, bins = trace_iat2bins(iat_data, 1.0)
- trace_summary(trace)[source]
Compute comprehensive summary statistics for a trace.
- Parameters:
trace (numpy.ndarray | list) – Array of trace values.
- Returns:
Array containing [MEAN, SCV, MAD, SKEW, KURT, Q25, Q50, Q75, P95, MIN, MAX, IQR, ACF1, ACF2, ACF3, ACF4, IDC_SCV_RATIO].
- Return type:
Example
>>> summary = trace_summary(trace_data) >>> print(f"Mean: {summary[0]}, SCV: {summary[1]}")
- trace_bicov(trace, grid)[source]
Compute bicovariance of a trace.
Bicovariance measures third-order correlation structure at multiple lag combinations.
- Parameters:
trace (numpy.ndarray | list) – Array of trace values.
grid (numpy.ndarray | list) – Array of lags to form the grid (e.g., [1, 2, 3, 4, 5]).
- Returns:
bicov: Array of bicovariance values
bicov_lags: 2D array of lag combinations (each row is [1, i, j])
- Return type:
Tuple of (bicov, bicov_lags) where
Example
>>> trace = np.random.randn(1000) >>> bicov, lags = trace_bicov(trace, [1, 2, 3, 4, 5])
- mtrace_mean(trace, ntypes, types)[source]
Compute the mean of a trace, divided by types.
- Parameters:
trace (numpy.ndarray | list) – Array of trace values.
ntypes (int) – Number of different types.
types (numpy.ndarray | list) – Array indicating the type of each element.
- Returns:
Array containing the mean values for each type.
- Return type:
Example
>>> trace = [1.0, 2.0, 3.0, 4.0] >>> types = [0, 1, 0, 1] >>> means = mtrace_mean(trace, 2, types)
- mtrace_var(trace, ntypes, types)[source]
Compute the variance of a trace, divided by types.
- Parameters:
trace (numpy.ndarray | list) – Array of trace values.
ntypes (int) – Number of different types.
types (numpy.ndarray | list) – Array indicating the type of each element.
- Returns:
Array containing the variance values for each type.
- Return type:
Example
>>> var_by_type = mtrace_var(trace, 2, types)
- mtrace_count(trace, ntypes, types)[source]
Count elements per type in a trace.
- Parameters:
trace (numpy.ndarray | list) – Array of trace values.
ntypes (int) – Number of different types.
types (numpy.ndarray | list) – Array indicating the type of each element.
- Returns:
Array containing counts for each type.
- Return type:
Example
>>> counts = mtrace_count(trace, 2, types)
- mtrace_sigma(T, L)[source]
Compute one-step class transition probabilities from a marked trace.
Computes P(C_k = j | C_{k-1} = i) empirically from the trace.
- Parameters:
T (numpy.ndarray | list) – Array of inter-arrival times (unused, for API consistency)
L (numpy.ndarray | list) – Array of class labels
- Returns:
C x C matrix where element (i,j) is the probability of observing class j after class i.
- Return type:
- mtrace_sigma2(T, L)[source]
Compute two-step class transition probabilities from a marked trace.
Computes P(C_k = h | C_{k-1} = j, C_{k-2} = i) empirically.
- Parameters:
T (numpy.ndarray | list) – Array of inter-arrival times (unused, for API consistency)
L (numpy.ndarray | list) – Array of class labels
- Returns:
C x C x C 3D array of transition probabilities.
- Return type:
- mtrace_cross_moment(T, L, k)[source]
Compute the k-th order moment of inter-arrival times between class pairs.
- Parameters:
T (numpy.ndarray | list) – Array of inter-arrival times
L (numpy.ndarray | list) – Array of class labels
k (int) – Order of the moment
- Returns:
C x C matrix where element (i,j) is E[T^k | C_{t-1} = i, C_t = j]
- Return type:
- mtrace_forward_moment(T, A, orders, norm=True)[source]
Compute forward moments of a marked trace.
Forward moment for class c is E[T_{k+1}^order | C_k = c].
- Parameters:
T (numpy.ndarray | list) – Array of inter-arrival times
A (numpy.ndarray | list) – Array of class labels
orders (numpy.ndarray | list) – Array of moment orders to compute
norm (bool) – If True, normalize by class probability
- Returns:
Matrix of shape (C, len(orders)) containing forward moments.
- Return type:
- mtrace_backward_moment(T, A, orders, norm=True)[source]
Compute backward moments of a marked trace.
Backward moment for class c is E[T_k^order | C_k = c].
- Parameters:
T (numpy.ndarray | list) – Array of inter-arrival times
A (numpy.ndarray | list) – Array of class labels
orders (numpy.ndarray | list) – Array of moment orders to compute
norm (bool) – If True, normalize by class probability
- Returns:
Matrix of shape (C, len(orders)) containing backward moments.
- Return type:
- mtrace_cov(T, A)[source]
Compute lag-1 covariance between classes in a marked trace.
- Parameters:
T (numpy.ndarray | list) – Array of inter-arrival times
A (numpy.ndarray | list) – Array of class labels
- Returns:
C x C matrix of 2x2 covariance matrices.
- Return type:
- mtrace_pc(T, L)[source]
Compute the probability of arrival for each class.
- Parameters:
T (numpy.ndarray | list) – Array of inter-arrival times (unused, for API consistency)
L (numpy.ndarray | list) – Array of class labels
- Returns:
Array of class probabilities.
- Return type:
- mtrace_summary(T, L)[source]
Compute comprehensive summary statistics for a marked trace.
- Parameters:
T (numpy.ndarray | list) – Array of inter-arrival times
L (numpy.ndarray | list) – Array of class labels
- Returns:
M: First 5 aggregate moments
ACF: Autocorrelation for lags 1-100
F1, F2: Forward moments of order 1 and 2
B1, B2: Backward moments of order 1 and 2
C1, C2: Cross moments of order 1 and 2
Pc: Class probabilities
Pab: One-step transition probabilities
- Return type:
Dictionary containing
- mtrace_split(T, L)[source]
Split a multi-class trace into per-class traces.
For each class, computes inter-arrival times between consecutive events of that class.
- Parameters:
T (numpy.ndarray | list) – Array of inter-arrival times
L (numpy.ndarray | list) – Array of class labels
- Returns:
List of arrays, one per class, containing inter-arrival times.
- Return type:
- mtrace_merge(t1, t2)[source]
Merge two traces into a single marked (multi-class) trace.
- Parameters:
t1 (numpy.ndarray | list) – Inter-arrival times of the first trace
t2 (numpy.ndarray | list) – Inter-arrival times of the second trace
- Returns:
T: Merged inter-arrival times
L: Class labels (1 for t1, 2 for t2)
- Return type:
Tuple of (T, L) where
- mtrace_joint(T, A, i)[source]
Compute class-dependent joint moments.
Computes E[(X^(a)_j)^i[0] * (X^(a)_{j+1})^i[1]] for all classes a.
- Parameters:
T (numpy.ndarray | list) – Array of inter-arrival times
A (numpy.ndarray | list) – Array of class labels
i (numpy.ndarray | list) – Array of exponents [i0, i1]
- Returns:
Array of joint moments, one per class.
- Return type:
- mtrace_moment(T, A, orders, after=False, norm=False)[source]
Compute class-dependent moments of a multi-class trace.
- Parameters:
T (numpy.ndarray | list) – Array of inter-arrival times
A (numpy.ndarray | list) – Array of class labels
orders (numpy.ndarray | list) – Array of moment orders to compute
after (bool) – If True, compute moments of Bucholz variables (forward) If False, compute moments of Horvath variables (backward)
norm (bool) – If True, normalize by class probability
- Returns:
Matrix of shape (C, len(orders)) containing moments per class.
- Return type:
- mtrace_moment_simple(T, A, k)[source]
Simple interface to compute k-th order moments per class.
- Parameters:
T (numpy.ndarray | list) – Array of inter-arrival times
A (numpy.ndarray | list) – Array of class labels
k (int) – Order of the moment
- Returns:
Array of k-th order moments, one per class.
- Return type:
- mtrace_bootstrap(T, A, n_samples=100, seed=None)[source]
Generate bootstrap samples from a marked trace.
- Parameters:
T (numpy.ndarray | list) – Array of inter-arrival times
A (numpy.ndarray | list) – Array of class labels
n_samples (int) – Number of bootstrap samples to generate
seed (int) – Random seed
- Returns:
Tuple of (T_boot, A_boot) containing bootstrap samples.
- Return type:
- mtrace_iat2counts(T, L, scale)[source]
Compute counting process from marked inter-arrival times.
For each class, counts arrivals in windows of specified scale.
- Parameters:
T (numpy.ndarray | list) – Array of inter-arrival times
L (numpy.ndarray | list) – Array of class labels
scale (float) – Time scale for counting
- Returns:
Array of counts per class per window.
- Return type:
Reinforcement Learning (line_solver.api.rl)
Reinforcement Learning (RL) agents for queueing control.
Native Python implementations of RL agents for queueing network control and optimization.
- Key classes:
RLTDAgent: Temporal Difference learning agent RLEnvironment: Queueing network environment
- Port from:
matlab/src/api/rl/rl_td_agent.m matlab/src/api/rl/rl_env.m
- class RLEnvironment(model, queue_indices, source_indices, state_size, gamma=0.99)[source]
Bases:
objectReinforcement Learning environment for queueing networks.
This class wraps a queueing network model and provides an interface for RL agents to interact with it through sampling and state updates.
- model
The queueing network model
- gamma
Discount factor for future rewards
- queue_indices
Indices of queue nodes in model.nodes
- source_indices
Indices of source nodes in model.nodes
- state_size
Maximum state size to consider
- action_size
Number of possible actions (number of queues)
Initialize the RL environment.
- Parameters:
- __init__(model, queue_indices, source_indices, state_size, gamma=0.99)[source]
Initialize the RL environment.
- sample()[source]
Sample the next event from the environment.
Uses the SSA solver to sample a single system event.
- class RLTDAgent(learning_rate=0.05, epsilon=1.0, epsilon_decay=0.99)[source]
Bases:
objectTemporal Difference (TD) learning agent for queueing control.
Implements average-reward TD learning for optimal routing decisions in queueing networks. The agent learns a value function V(s) that estimates the long-run average cost from each state.
- learning_rate
Step size for value function updates
- epsilon
Exploration rate for epsilon-greedy policy
- epsilon_decay
Decay factor for exploration rate
- V
Value function array
- Q
Q-function array (state-action values)
Initialize the TD agent.
- Parameters:
- reset(env)[source]
Reset agent and environment.
- Parameters:
env (RLEnvironment) – The RL environment
- solve(env, num_episodes=10000, verbose=True)[source]
Train the agent using TD learning.
Runs TD(0) learning for the specified number of episodes, learning an optimal routing policy for the queueing network.
- Parameters:
env (RLEnvironment) – The RL environment
num_episodes (int) – Number of training episodes
verbose (bool) – Whether to print progress
- Returns:
‘V’: Learned value function
’Q’: Learned Q-function
’mean_cost_rate’: Final estimated average cost rate
- Return type:
Dictionary with training results
- class RLEnvironmentGeneral(model, queue_indices, action_node_indices, state_size, gamma=0.99)[source]
Bases:
objectGeneral RL environment for queueing networks with flexible action spaces.
Unlike RLEnvironment which assumes sources dispatch to queues, this class supports arbitrary action nodes with configurable routing destinations. Actions are dispatching decisions at specific nodes that route jobs to connected downstream nodes.
- model
The queueing network model
- gamma
Discount factor for future rewards
- queue_indices
Indices of queue nodes in model.nodes
- nqueues
Number of queues
- action_node_indices
Indices of nodes where routing actions are needed
- state_size
Maximum state size to consider
- action_space
Dict mapping action_node -> list of possible destination nodes
MATLAB: matlab/src/api/rl/rl_env_general.m
Initialize the general RL environment.
- Parameters:
- __init__(model, queue_indices, action_node_indices, state_size, gamma=0.99)[source]
Initialize the general RL environment.
- Parameters:
- sample()[source]
Sample the next event from the environment.
Uses the SSA solver to sample a single system event.
- class RLTDAgentGeneral(learning_rate=0.1, epsilon=1.0, epsilon_decay=0.9999)[source]
Bases:
objectGeneral TD learning agent for queueing control with flexible policies.
Supports multiple solve methods: - solve(): TD control with tabular value function - solve_for_fixed_policy(): TD learning (evaluation) with fixed heuristic - solve_by_hashmap(): TD control with hash-map value function - solve_by_linear(): TD control with linear function approximation - solve_by_quad(): TD control with quadratic function approximation
Works with RLEnvironmentGeneral for arbitrary action spaces.
MATLAB: matlab/src/api/rl/rl_td_agent_general.m
Initialize the general TD agent.
- Parameters:
- __init__(learning_rate=0.1, epsilon=1.0, epsilon_decay=0.9999)[source]
Initialize the general TD agent.
- reset(env)[source]
Reset agent and environment.
- Parameters:
env (RLEnvironmentGeneral) – The RL environment
- solve_for_fixed_policy(env, num_episodes=10000, verbose=True)[source]
TD learning for value function evaluation with heuristic routing.
Evaluates the value function under the existing (model-defined) routing policy without modifying routing decisions.
- Parameters:
env (RLEnvironmentGeneral) – The general RL environment
num_episodes (int) – Number of training episodes
verbose (bool) – Whether to print progress
- Returns:
Learned value function array
- Return type:
MATLAB: rl_td_agent_general.solve_for_fixed_policy
- solve(env, num_episodes=10000, verbose=True)[source]
TD control with tabular value function.
Learns an optimal routing policy using epsilon-greedy exploration. At each action node departure, the agent selects the best downstream destination based on the current value function.
- Parameters:
env (RLEnvironmentGeneral) – The general RL environment
num_episodes (int) – Number of training episodes
verbose (bool) – Whether to print progress
- Returns:
Learned value function array
- Return type:
MATLAB: rl_td_agent_general.solve
- solve_by_hashmap(env, num_episodes=10000, verbose=True)[source]
TD control using hash-map value function.
Uses a dictionary to store value estimates only for visited states, with an ‘external’ default for unvisited states.
- Parameters:
env (RLEnvironmentGeneral) – The general RL environment
num_episodes (int) – Number of training episodes
verbose (bool) – Whether to print progress
- Returns:
X: State features matrix (n_states x (1 + nqueues)) Y: Value estimates (n_states x 1)
- Return type:
Tuple of (X, Y) where
MATLAB: rl_td_agent_general.solve_by_hashmap
- solve_by_linear(env, num_episodes=10000, verbose=True)[source]
TD control with linear function approximation.
Learns a linear value function: v(q1,…,qn) = w0 + w1*q1 + … + wn*qn
- Parameters:
env (RLEnvironmentGeneral) – The general RL environment
num_episodes (int) – Number of training episodes
verbose (bool) – Whether to print progress
- Returns:
X: State features matrix Y: Value estimates coefficients: Linear regression coefficients
- Return type:
Tuple of (X, Y, coefficients) where
MATLAB: rl_td_agent_general.solve_by_linear
- solve_by_quad(env, num_episodes=10000, verbose=True)[source]
TD control with quadratic function approximation.
Learns a quadratic value function: v(q1,…,qn) = sum_{i,j} w_{ij} * q_i * q_j
- Parameters:
env (RLEnvironmentGeneral) – The general RL environment
num_episodes (int) – Number of training episodes
verbose (bool) – Whether to print progress
- Returns:
X_quad: Augmented features (linear + quadratic terms) Y: Value estimates coefficients: Quadratic regression coefficients
- Return type:
Tuple of (X_quad, Y, coefficients) where
MATLAB: rl_td_agent_general.solve_by_quad
Utilities Module (line_solver.utils)
Mock module that can handle any attribute access
Constants Module (line_solver.constants)
Constants and enumerations for LINE queueing network models.
This module defines the various constants, enumerations, and strategies used throughout LINE for specifying model behavior, including:
Scheduling strategies (FCFS, LCFS, PS, etc.)
Routing strategies (PROB, RAND, etc.)
Node types (SOURCE, QUEUE, SINK, etc.)
Job class types (OPEN, CLOSED)
Solver types and options
Activity precedence types for layered networks
Call types and drop strategies
These constants ensure type safety and consistency across the API.
- class ActivityPrecedenceType(*values)[source]
Bases:
EnumTypes of activity precedence relationships in layered networks.
These specify how activities are ordered and synchronized: - PRE_SEQ: Sequential prerequisite (must complete before) - PRE_AND: AND prerequisite (all must complete before) - PRE_OR: OR prerequisite (any must complete before) - POST_SEQ: Sequential post-condition - POST_AND: AND post-condition - POST_OR: OR post-condition - POST_LOOP: Loop post-condition - POST_CACHE: Cache post-condition
- class CallType(*values)[source]
Bases:
EnumTypes of calls between tasks in layered networks.
SYNC: Synchronous call (caller waits for response)
ASYNC: Asynchronous call (caller continues immediately)
FWD: Forward call (caller terminates, response goes to caller’s caller)
- class DropStrategy(*values)[source]
Bases:
EnumStrategies for handling queue overflow and capacity limits.
WaitingQueue: Jobs wait in a waiting queue when capacity is exceeded
Queue: Alias for WaitingQueue
Drop: Jobs are dropped (lost) when capacity is exceeded
BlockingAfterService: Jobs are blocked after service completion
BlockingBeforeService: Jobs are blocked before service starts
ReServiceOnRejection: Rejected jobs are re-served at the upstream station
Values match the MATLAB DropStrategy constants and the JAR jline.lang.constant.DropStrategy ids, which are the interchange encoding of sn.droprule and sn.regionrule. Keep the three Python definitions of this enum (here, lang/base.py, api/sn/network_struct.py) numerically identical: they are written and read by different modules over the same sn fields.
- BlockingBeforeService = 3
- ReServiceOnRejection = 4
- class DepartureDiscipline(*values)[source]
Bases:
EnumDeparture disciplines for the depository of a queueing place (QPN semantics).
A queueing place serves tokens in its embedded queue and, on service completion, moves them to a depository from which they become available to the output transitions. The departure discipline governs the order in which depository tokens become available.
NORMAL: tokens available immediately upon service completion (standard QPN)
FIFO: tokens available in their order of arrival to the depository
- NORMAL = 0
- class SignalType(*values)[source]
Bases:
EnumTypes of signals for signal classes in G-networks and related models.
This is the single canonical definition: lang/classes.py re-exports it rather than defining a second enum. Two coexisting definitions used to be disambiguated only by the import order in line_solver/__init__.py, and the losing definition carried auto() ordinals (1-based) that would have mis-decoded against the 0-based MATLAB/Java enums on the JSON wire.
The member values are the lowercase names used on the JSON wire.
- NEGATIVE
Removes a job from the destination queue (G-network negative customer)
- REPLY
Triggers a reply action
- CATASTROPHE
Removes ALL jobs from the destination queue
- NEGATIVE = 'negative'
- REPLY = 'reply'
- CATASTROPHE = 'catastrophe'
- class RemovalPolicy(*values)[source]
Bases:
EnumRemoval policies for negative signals in G-networks.
Single canonical definition; see the note on SignalType above. The member values are the lowercase names used on the JSON wire.
- RANDOM
Select job uniformly at random from all jobs at the station
- FCFS
Remove the oldest job (first arrived)
- LCFS
Remove the newest job (last arrived)
- RANDOM = 'random'
- class EventType(*values)[source]
Bases:
EnumTypes of events in discrete-event simulation.
INIT: Initialization event
LOCAL: Local processing event
ARV: Job arrival event
DEP: Job departure event
PHASE: Phase transition event in multi-phase processes
READ: Cache read event
STAGE: Staging area event
- READ = 6
- ENABLE = 8
- FIRE = 9
- PRE = 10
- POST = 11
- RENEGE = 12
- RETRY = 13
- SWITCH = 14
- class JobClassType(*values)[source]
Bases:
EnumTypes of job classes in queueing networks.
OPEN: Open class (jobs arrive from outside the system)
CLOSED: Closed class (fixed population circulating in the system)
DISABLED: Disabled class (not currently active)
- class JoinStrategy(*values)[source]
Bases:
EnumStrategies for join node synchronization in fork-join networks.
STD: Standard join (wait for all parallel branches)
PARTIAL: Partial join (proceed when some branches complete)
Quorum: Quorum-based join (wait for minimum number of branches)
Guard: Guard condition join (custom completion criteria)
- class MetricType(*values)[source]
Bases:
EnumTypes of performance metrics that can be computed.
- SysDropR = 11
- SysPower = 13
- Tard = 24
- SysTard = 25
- class Metric(metric_type, job_class, station=None)[source]
Bases:
objectAn output metric of a Solver, such as a performance index.
- class TranResult(t, metric)[source]
Bases:
objectContainer for transient result time series with attribute access.
- class ProcessType(*values)[source]
Bases:
EnumTypes of stochastic processes for arrivals and service times.
- BMAP = 22
- MMAP = 23
- DUNIFORM = 24
- BERNOULLI = 25
- PRIOR = 26
- GEOMETRIC = 27
- ME = 28
- RAP = 29
- DISCRETESAMPLER = 30
- ZIPF = 31
- DMAP = 32
- EMPIRICALCDF = 33
- NHPP = 34
- class RoutingStrategy(*values)[source]
Bases:
EnumStrategies for routing jobs between network nodes. Values must match MATLAB’s RoutingStrategy constants for JMT compatibility.
- RL = 7
- class SchedStrategy(*values)[source]
Bases:
EnumScheduling strategies for service stations.
Values match lang/base.py SchedStrategy for consistency.
- LCFSPI = 3
- HOL = 9
- LPS = 17
- SETF = 18
- FCFSPR = 22
- EDF = 23
- JOIN = 25
- EDD = 27
- SRPT = 28
- SRPTPRIO = 29
- LCFSPRIO = 30
- LCFSPRPRIO = 31
- LCFSPIPRIO = 32
- FCFSPRPRIO = 33
- FCFSPIPRIO = 34
- PSJF = 36
- FB = 37
- LAS = 38
- LRPT = 39
- FSP = 40
- PAS = 41
- OI = 42
- class SchedStrategyType(*values)[source]
Bases:
EnumCategories of scheduling strategies by preemption behavior.
- class ServiceStrategy(*values)[source]
Bases:
EnumService strategies defining service time dependence.
- class SolverType(*values)[source]
Bases:
EnumTypes of solvers available in LINE.
- BA = 2
- LDES = 4
- class PollingType(*values)[source]
Bases:
EnumPolling strategies for polling systems.
- DECREMENTING = 4
- class HeteroSchedPolicy(*values)[source]
Bases:
EnumScheduling policies for heterogeneous multiserver queues.
- ORDER = 1
- ALIS = 2
- ALFS = 3
- FAIRNESS = 4
- FSF = 5
- RAIS = 6
- class GlobalConstants[source]
Bases:
objectGlobal constants and configuration for the LINE solver.
- Immediate = 100000000.0
- classmethod get_instance()
Get the singleton instance of GlobalConstants.
- classmethod get_verbose()
Get the current verbosity level.
- classmethod set_verbose(verbosity)
Set the verbosity level for solver output.
- classmethod get_constants()
Get a dictionary of all global constants.