Stochastic Network Utilities

Network analysis and transformation utilities.

The sn module contains utility functions for stochastic networks, including routing probability calculations, visit ratios, and network transformations.

Key function categories:

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

sn_gd_balance(phi, cutoffs)[source]

Worst relative violation of the Whittle balance property by phi.

For every state n of the lattice 0..cutoffs and every pair of stations (s,t) populated in n, the property requires

phi_s(n) phi_t(n - e_s) = phi_t(n) phi_s(n - e_t).

When it holds, the chain is reversible with pi(n) ~ Phi(n) prod rho**n for the balance function Phi implied by phi, and the stationary law is insensitive to the service-time distribution beyond its mean. When it fails, the model is still solvable by SolverCTMC but has no product form and is sensitive.

phi is evaluated on an (nstations,) population vector, i.e. the single-class reading of the (nstations, nclasses) contract of set_global_dependence, and must return a scalar or an (nstations,) vector.

Parameters:
  • phi – the scaling callable

  • cutoffs – scalar (same bound at every station) or (nstations,) vector

Returns:

(worst relative violation, the state attaining it)

Reference: P. Whittle, “Partial balance and insensitivity”, J. Appl. Prob. 22(1), 1985; T. Bonald, A. Proutiere, “Insensitivity in processor-sharing networks”, Perf. Eval. 49, 2002.

class MatrixArray(input_array)[source]

Bases: ndarray

Numpy 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.

static __new__(cls, input_array)[source]

Create MatrixArray from existing array.

__array_finalize__(obj)[source]

Handle view casting and new-from-template.

__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).

__setitem__(key, value)[source]

Override item setting to handle 2D indexing on 1D arrays.

get(i, j=None)[source]

Get element at index (i, j) or just i if 1D.

Parameters:
  • i – Row index (or element index for 1D)

  • j – Column index (optional, for 2D arrays)

Returns:

Element value at the specified index

set(i, j, value=None)[source]

Set element at index (i, j) or just i if 1D.

Parameters:
  • i – Row index (or element index for 1D)

  • j – Column index or value (for 1D arrays)

  • value – Value to set (optional, for 2D arrays)

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, sdr=None, hassetup=<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, jdscaling=None, jdscalingpeak=None, gdscaling=None, gdscalingpeak=None, gdscalingcutoff=None, classprio=None, classdeadline=None, isslc=None, issignal=None, signaltarget=None, signaltype=None, syncreply=None, replyblock=None, immfeed=None, signalremdist=None, signalrempolicy=None, iscatastrophe=None, connmatrix=None, nodenames=<factory>, classnames=<factory>, mu=None, phi=None, proc=None, isph=None, pie=None, procid=None, lst=None, fj=None, fjsync=None, fjclassmap=None, isfjaugmented=False, fjauxclass=None, 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, isbasdestination=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, retrialPolicy=None, orbitMaxJobs=None, orbitImpatience=None, hasbreakdown=None, breakdownMu=None, repairMu=None, breakdownProc=None, repairProc=None, downServiceRates=None, varsparam=None, markidx=None)[source]

Bases: object

Data 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.

Variables:
  • nstations (int) – Number of stations (queues, delays, sources, joins, places)

  • nstateful (int) – Number of stateful nodes

  • nnodes (int) – Total number of nodes

  • nclasses (int) – Number of job classes

  • nchains (int) – Number of chains (routing chains)

  • nclosedjobs (int) – Total number of jobs in closed classes

  • njobs (numpy.ndarray) – (1, K) Population per class (inf for open classes)

  • nservers (numpy.ndarray) – (M, 1) Number of servers per station

  • rates (numpy.ndarray) – (M, K) Service rates

  • scv (numpy.ndarray) – (M, K) Squared coefficient of variation

  • visits (Dict[int, numpy.ndarray]) – Dict[int, ndarray] - Chain ID -> (M, K) visit ratios

  • inchain (Dict[int, numpy.ndarray]) – Dict[int, ndarray] - Chain ID -> class indices in chain

  • chains (numpy.ndarray) – (K, 1) Chain membership per class

  • refstat (numpy.ndarray) – (K, 1) Reference station per class

  • refclass (numpy.ndarray) – (1, C) Reference class per chain

  • sched (Dict[int, int]) – Dict[int, SchedStrategy] - Station ID -> scheduling strategy

  • routing (numpy.ndarray) – (N, K) Routing strategy matrix

  • rt (numpy.ndarray | None) – Routing probability matrix

  • nodetype (List[int]) – List[NodeType] - Node types

  • isstation (numpy.ndarray) – (N, 1) Boolean mask for stations

  • isstateful (numpy.ndarray) – (N, 1) Boolean mask for stateful nodes

  • hassetup (numpy.ndarray) – (M, 1) Boolean mask, STATION-indexed: queue stations that carry setup/delay-off times (function stations)

  • nodeToStation (numpy.ndarray) – (N, 1) Node index -> station index mapping

  • nodeToStateful (numpy.ndarray) – (N, 1) Node index -> stateful index mapping

  • stationToNode (numpy.ndarray) – (M, 1) Station index -> node index mapping

  • stationToStateful (numpy.ndarray) – (M, 1) Station index -> stateful index mapping

  • statefulToNode (numpy.ndarray) – (S, 1) Stateful index -> node index mapping

  • statefulToStation (numpy.ndarray) – (S, 1) Stateful index -> station index mapping

  • state (Dict[int, numpy.ndarray]) – Dict State per stateful node

  • lldscaling (numpy.ndarray | None) – (M, Nmax) Load-dependent scaling matrix

  • cdscaling (Dict | None) – Class-dependent (product-form) scaling functions beta_{i,r}

  • jdscaling (Dict | None) – Joint-dependent (non-product-form) scaling functions eta_i

  • cap (numpy.ndarray | None) – (M, 1) Station capacities

  • classcap (numpy.ndarray | None) – (M, K) Per-class capacities

  • connmatrix (numpy.ndarray | None) – (N, N) Connection matrix

  • nodenames (List[str]) – List[str] - Node names

  • classnames (List[str]) – List[str] - Class names

nstations: int = 0
nstateful: int = 0
nnodes: int = 0
nclasses: int = 0
nchains: int = 0
nclosedjobs: int = 0
njobs: ndarray
nservers: ndarray
cap: ndarray | None = None
classcap: ndarray | None = None
rates: ndarray
scv: ndarray
phases: ndarray | None = None
phasessz: ndarray | None = None
phaseshift: ndarray | None = None
visits: Dict[int, ndarray]
nodevisits: Dict[int, ndarray]
inchain: Dict[int, ndarray]
chains: ndarray
refstat: ndarray
refclass: ndarray
sched: Dict[int, int]
schedparam: ndarray | None = None
routing: ndarray
rt: ndarray | None = None
rtnodes: ndarray | None = None
nodetype: List[int]
isstation: ndarray
isstateful: ndarray
isstatedep: ndarray | None = None
sdr: dict | None = None
hassetup: ndarray
nodeToStation: ndarray
nodeToStateful: ndarray
stationToNode: ndarray
stationToStateful: ndarray
statefulToNode: ndarray
statefulToStation: ndarray
state: Dict[int, ndarray]
stateprior: Dict[int, ndarray]
space: Dict[int, ndarray]
lldscaling: ndarray | None = None
cdscaling: Dict | None = None
cdscalingpeak: ndarray | None = None
jdscaling: Dict | None = None
jdscalingpeak: ndarray | None = None
gdscaling: Any | None = None
gdscalingpeak: ndarray | None = None
gdscalingcutoff: int | None = None
classprio: ndarray | None = None
classdeadline: ndarray | None = None
isslc: ndarray | None = None
issignal: ndarray | None = None
signaltarget: ndarray | None = None
signaltype: List | None = None
syncreply: ndarray | None = None
replyblock: ndarray | None = None
immfeed: ndarray | None = None
signalremdist: List | None = None
signalrempolicy: List | None = None
iscatastrophe: ndarray | None = None
connmatrix: ndarray | None = None
nodenames: List[str]
classnames: List[str]
mu: Dict | None = None
phi: Dict | None = None
proc: Dict | None = None
isph: ndarray | None = None
pie: Dict | None = None
procid: Dict | None = None
lst: Dict | None = None
fj: ndarray | None = None
fjsync: List | None = None
fjclassmap: ndarray | None = None
isfjaugmented: bool = False
fjauxclass: ndarray | None = None
droprule: Dict | None = None
nregions: int = 0
region: List | None = None
regionrule: ndarray | None = None
regionweight: ndarray | None = None
regionsz: ndarray | None = None
regionmaxmem: List | None = None
regionmembers: List | None = None
sync: Dict | None = None
gsync: Dict | None = None
nodeparam: Dict | None = None
routingweights: Dict | None = None
reward: Dict | None = None
rtorig: Dict | None = None
csmask: ndarray | None = None
nvars: ndarray | None = None
isbasblocking: ndarray | None = None
isbasdestination: ndarray | None = None
impatienceType: ndarray | None = None
impatienceMu: ndarray | None = None
impatienceClass: ndarray | None = None
impatiencePhi: ndarray | None = None
impatiencePhases: ndarray | None = None
impatienceProc: List[List[Any]] | None = None
impatiencePie: List[List[Any]] | None = None
impatienceDist: List[List[Any]] | None = None
balkingStrategy: ndarray | None = None
balkingThresholds: List[List[Any]] | None = None
retrialType: ndarray | None = None
retrialMu: ndarray | None = None
retrialPhi: ndarray | None = None
retrialProc: List[List[Any]] | None = None
retrialMaxAttempts: ndarray | None = None
retrialPolicy: ndarray | None = None
orbitMaxJobs: ndarray | None = None
orbitImpatience: List[List[Any]] | None = None
hasbreakdown: ndarray | None = None
breakdownMu: ndarray | None = None
repairMu: ndarray | None = None
breakdownProc: List[Any] | None = None
repairProc: List[Any] | None = None
downServiceRates: ndarray | None = None
varsparam: ndarray | None = None
markidx: ndarray | None = None
__setattr__(name, value)[source]

Override to convert numpy arrays to MatrixArray for API compatibility.

__post_init__()[source]

Ensure arrays are MatrixArray (numpy arrays with .get()/.set() methods).

validate()[source]

Validate structural consistency.

Raises:

ValueError – If structural consistency is violated

is_valid()[source]

Check if structure is valid.

Returns:

True if structure passes validation, False otherwise

Return type:

bool

get_chain_population(chain_id)[source]

Get total population in a chain.

Parameters:

chain_id (int) – Chain index (0-based)

Returns:

Total number of jobs in the chain

Return type:

float

is_closed_chain(chain_id)[source]

Check if a chain is closed (finite population).

Parameters:

chain_id (int) – Chain index (0-based)

Returns:

True if chain is closed, False if open

Return type:

bool

is_open_chain(chain_id)[source]

Check if a chain is open (infinite population).

Parameters:

chain_id (int) – Chain index (0-based)

Returns:

True if chain is open, False if closed

Return type:

bool

get_station_indices()[source]

Get indices of station nodes.

Returns:

Array of node indices that are stations

Return type:

ndarray

get_stateful_indices()[source]

Get indices of stateful nodes.

Returns:

Array of node indices that are stateful

Return type:

ndarray

get_scheduling_at_station(station_id)[source]

Get scheduling strategy at a station.

Parameters:

station_id (int) – Station index (0-based)

Returns:

SchedStrategy value

Return type:

int

has_multi_server()[source]

Check if any station has multiple servers.

Infinite servers are delays, not multiserver queues: counting them made every model with a Delay read as multiserver (MATLAB sn_has_multi_server filters them out).

has_load_dependence()[source]

Check if model has load-dependent service rates.

has_class_dependence()[source]

Check if model has class-dependent scaling.

has_joint_dependence()[source]

Check if model has joint-dependent (non-product-form) scaling.

has_open_classes()[source]

Check if model has open (infinite population) classes.

has_closed_classes()[source]

Check if model has closed (finite population) classes.

get_total_population()[source]

Get total population across all closed classes.

get_open_class_indices()[source]

Get indices of open classes.

get_closed_class_indices()[source]

Get indices of closed classes.

copy()[source]

Create a deep copy of this NetworkStruct.

__repr__()[source]

String representation.

property obj

Return self for compatibility with wrapper code that accesses .obj

class NodeType(*values)[source]

Bases: IntEnum

Node 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
static toText(node_type)[source]

Convert node type to text representation.

class SchedStrategy(*values)[source]

Bases: IntEnum

Scheduling 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
FCFSPI = 43
class RoutingStrategy(*values)[source]

Bases: IntEnum

Routing strategies.

Values must match MATLAB’s RoutingStrategy constants for JMT compatibility.

SQ = 6
SDR = 7
class DropStrategy(*values)[source]

Bases: IntEnum

Drop 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: object

Result of sn_get_demands_chain calculation.

Variables:
  • Lchain (numpy.ndarray) – (M, C) Chain-level demand matrix

  • STchain (numpy.ndarray) – (M, C) Chain-level service time matrix

  • Vchain (numpy.ndarray) – (M, C) Chain-level visit ratio matrix

  • alpha (numpy.ndarray) – (M, K) Class-to-chain weighting matrix

  • Nchain (numpy.ndarray) – (1, C) Population per chain

  • SCVchain (numpy.ndarray) – (M, C) Chain-level squared coefficient of variation

  • refstatchain (numpy.ndarray) – (C, 1) Reference station per chain

Lchain: ndarray
STchain: ndarray
Vchain: ndarray
alpha: ndarray
Nchain: ndarray
SCVchain: ndarray
refstatchain: 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 (ndarray) – (M, C) Service demands per chain

  • ST (ndarray | None) – (M, K) Mean service times per class (optional, computed from rates if None)

  • STchain (ndarray) – (M, C) Mean service times per chain

  • Vchain (ndarray) – (M, C) Mean visits per chain

  • alpha (ndarray) – (M, K) Class aggregation coefficients

  • Qchain (ndarray | None) – (M, C) Mean queue-lengths per chain (optional)

  • Uchain (ndarray | None) – (M, C) Mean utilization per chain (optional)

  • Rchain (ndarray) – (M, C) Mean response time per chain

  • Tchain (ndarray) – (M, C) Mean throughput per chain

  • Cchain (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 (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: object

Result of sn_deaggregate_chain_results calculation.

Variables:
Q: ndarray
U: ndarray
R: ndarray
T: ndarray
C: ndarray
X: ndarray
class ProductFormParams(lam, D, N, Z, mu, S, V)[source]

Bases: NamedTuple

Result of sn_get_product_form_params calculation.

Create new instance of ProductFormParams(lam, D, N, Z, mu, S, V)

lam: ndarray

Alias for field number 0

D: ndarray

Alias for field number 1

N: ndarray

Alias for field number 2

Z: ndarray

Alias for field number 3

mu: ndarray

Alias for field number 4

S: ndarray

Alias for field number 5

V: ndarray

Alias for field number 6

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 (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:

Dict[int, ndarray]

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:
  • sn (NetworkStruct) – NetworkStruct object (modified in place)

  • source_node (int) – Source node index (0-based)

  • dest_node (int) – Destination node index (0-based)

  • source_class (int) – Source class index (0-based)

  • dest_class (int) – Destination class index (0-based)

  • prob (float) – Routing probability

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_refresh_cacheqn_visits(sn)[source]

Relabel every Cache node’s self-switch with the split standing on the node, then refresh the visits derived from it.

RESTORING THE HIT/MISS SPLIT IS NOT ENOUGH, BECAUSE THE VISITS ARE DERIVED FROM IT. link() lays down a uniform hit/miss split before any cache has been analyzed; a solver that writes actualhitprob back onto the node without this step leaves rtnodes – and so nodevisits – carrying that guess, and the node-level ResidT is then RespT times the wrong visit. Every MATLAB solver that writes a hit probability follows it with refreshChains for this reason, and the native analyzers relabel and call sn_refresh_visits inline (solver_nc_cacheqn_analyzer).

Intended for the delegating bridges (lang=’java’, lang=’cpp’), which take the split from a foreign engine and must reproduce that refresh here. A cache whose node carries no split is left alone rather than zeroed: absent means the engine reported none, and the offered routing is then all there is.

Parameters:

sn (NetworkStruct) – NetworkStruct object (modified in place)

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:

NetworkStruct

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 (ndarray) – Matrix of new rates (nstations x nclasses), NaN = skip

  • scvs (ndarray | None) – Matrix of new SCVs (optional)

  • auto_refresh (bool) – If True, refresh process fields (default False)

Returns:

Modified NetworkStruct

Return type:

NetworkStruct

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:

NetworkStruct

References

MATLAB: matlab/src/api/sn/sn_nonmarkov_toph.m

sn_rt_stations(sn)[source]

Station-to-station routing probabilities and per-station visits.

sn.rt and sn.visits are indexed by STATEFUL node, so a solver that writes traffic equations over stations and indexes them by station index silently reads the wrong rows as soon as the model owns a stateful node that is not a station (Router, Cache, stateful class switch). The returned routing matrix absorbs those nodes,

Pst = P_AA + P_AB * (I - P_BB)^-1 * P_BA,

with A the station rows in station order and B the remaining stateful rows, which is exact because a non-station stateful node holds no jobs: it passes every arrival on instantaneously. When every stateful node is a station the result is sn.rt unchanged.

Parameters:

sn (NetworkStruct) – NetworkStruct

Returns:

Tuple (rt_stations, visits_stations) of shapes (M*K, M*K) and (M, K).

class ChainParams(lambda_vec, D, N, Z, mu, S, V)[source]

Bases: object

Chain-aggregated product-form parameters.

lambda_vec: ndarray
D: ndarray
N: ndarray
Z: ndarray
mu: ndarray
S: ndarray
V: ndarray
sn_pn_firing_rates(sn, TN, tput_is_tokens)[source]

Recover per-mode transition firing rates from the Place throughputs.

The firing rates of a Petri net are not carried by the network structure, but they are determined by the Place throughputs together with the net structure. Writing x for the vector of per-mode firing rates, two families of equations hold at steady state, for every Place p and class k:

departure the sum over the modes consuming (p,k) of x, weighted by the

input arc multiplicity when tput_is_tokens is True and unweighted when it is False, equals TN(p,k)

balance the sum over all modes of x times (produced minus consumed)

equals zero

The system is solved in least squares. That is deliberate: an exact solver supplies throughputs that satisfy it exactly and the fit is then the exact answer, whereas a simulator supplies estimates that satisfy it only up to sampling error and the least-squares fit is the right estimator there. A residual test would reject every simulated run.

Parameters:
  • sn (NetworkStruct) – Network structure

  • TN (ndarray) – Average throughputs at stations (M x R)

  • tput_is_tokens (bool) – True when TN counts tokens, False when it counts firing events

Returns:

(x, consumed, produced, place_nodes) where x is the firing rate per (transition, mode) pair and is None when undetermined, consumed and produced are indexed (mode, place, class), and place_nodes holds the node indices of the Places in the order used above.

References

Original MATLAB: matlab/src/api/sn/sn_pn_firing_rates.m

sn_pn_avg_rates(sn, QN, TN, AN=None, RN=None)[source]

Place throughput, arrival rate and response time in tokens.

A Place is a station and a token is the job it holds, so a firing that consumes two tokens is two departures, not one. The CTMC and SSA analyzers count firing events instead, which for unit arc multiplicities is the same number and for weighted arcs is not: the reported throughput is then not a token rate, and QLen over it is not a sojourn time.

This function rescales the Place rows to tokens:

TN(p,k) tokens consumed from the Place per unit time AN(p,k) tokens produced into the Place per unit time RN(p,k) QN(p,k) / TN(p,k), Little’s law over the Place

Rows that do not belong to a Place are returned untouched, so a mixed Queue/Place model keeps its queueing metrics. When the firing rates cannot be recovered from the throughputs the inputs are returned unchanged rather than replaced by a guess.

Parameters:
  • sn (NetworkStruct) – Network structure

  • QN (ndarray) – Average queue lengths, i.e. mean token counts at the Places

  • TN (ndarray) – Average throughputs at stations, counting firing events

  • AN (ndarray | None) – Average arrival rates at stations, as computed by the caller

  • RN (ndarray | None) – Average response times at stations, as computed by the caller

Returns:

(TN, AN, RN) with the Place rows expressed in tokens.

References

Original MATLAB: matlab/src/api/sn/sn_pn_avg_rates.m

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 (ndarray) – Average throughputs at stations (M x R)

  • TH (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_map_modulation(sn)[source]

Collect the (D0,D1) modulation records of every non-renewal process.

A MAP with matrices (D0,D1) is a Poisson-like point process modulated by the CTMC with generator Q = D0 + D1 (the phase process), whose conditional intensity in phase k is lambda(k) = sum_j D1(k,j). This returns one record per modulating process, so that a solver-agnostic transformation can replace each of them by a random-environment stage set (see api.io.map2renv).

Only processes declared as MAP, MMPP2 or MMAP are reported: every other distribution is stored in sn.proc in (D0,D1) form as well (Erlang, Coxian, APH, …), but those are renewal processes that carry no modulation and are supported natively by the phase-type solvers.

Marked processes (MMAP) at a Source are reported as a single record whose ‘classes’ entry lists every marked class, since all marks share one phase process; the per-class intensity comes from the mark-specific D1 matrices.

Mirrors matlab/src/api/sn/sn_map_modulation.m.

Parameters:

sn – NetworkStruct object

Returns:

List of dicts with keys ist, node, arrival, classes, D0, D1 (list, one per entry of classes), order, is_mmpp.

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 (ndarray) – Station throughputs (M x R)

  • TH (ndarray | None) – Throughput handles (optional)

  • AN (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 (ndarray) – Station throughputs (M x R)

  • TH (ndarray | None) – Throughput handles (optional)

  • ANn (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:

ChainParams

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:

NetworkStruct

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

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:

bool

sn_has_immfeed(sn)[source]

Whether immediate feedback is EFFECTIVE anywhere in the model.

A declaration alone is not enough. Queue.setImmediateFeedback marks a station and JobClass.setImmediateFeedback marks a class – and the class spelling marks EVERY station, since sn.immfeed is the OR of the two – so a model with no self-loop at all can carry a full sn.immfeed matrix while the feature changes nothing. Reading the raw matrix made every solver that consults it warn, or refuse, on a plain M/M/1 that merely mentioned the flag.

Immediate feedback is effective at (station i, class r) when sn.immfeed[i, r] holds AND the routing table has a self-loop INTO (i, r) from some class s at the same station, which is the only way a job can come back to the server it just left. A class switch on the way round is folded into sn.rt by refresh_routing, so the incoming class s need not be r.

Solvers that handle immediate feedback look at the SYNCHRONIZATION instead; see immfeed_self_loop(), which applies the same test per sync.

Parameters:

sn (NetworkStruct) – NetworkStruct object

Returns:

True if some station keeps its server across a self-loop

Return type:

bool

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:

bool

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:

bool

sn_has_quorum_join(sn)[source]

Check if the network has a quorum (k-of-n) join.

True if some Join node declares a non-standard strategy with a positive required count in some class, i.e. it fires before every sibling has arrived. The sibling count is not re-derived here, so a declaration with k >= n reads as a quorum; use sn_join_quorum where the branch count is known and the distinction matters, as the fork-join fixed point does.

Parameters:

sn (NetworkStruct) – NetworkStruct object

Returns:

True if some join declares a positive quorum

Return type:

bool

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:

bool

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:

bool

sn_has_blocking(sn)[source]

Check if the network holds jobs back at a finite buffer or region.

True when some station can refuse a job, either because its own buffer BINDS (Kendall’s K below the population that can reach it, whatever the drop rule: WAITQ, DROP, BAS, BBS, RSRD) or because a finite capacity region caps a set of stations jointly. Such a network is not product form: the truncation couples the station occupancies, so no BCMP factorization of the equilibrium distribution exists.

Only a buffer that can actually BIND counts, which is what sn_get_buffer_size decides: refreshCapacity derives a finite classcap (the chain population) at every station of every closed model, so a plain finiteness test would call every closed model blocking.

Two shapes are exempt. A Cache builds its own capped retrieval queues (classCap = 1), which the cache analyzers solve rather than treat as a buffer constraint. And the single-station M/M/1/K loss system keeps the truncated geometric distribution, a product form over its one station.

Parameters:

sn (NetworkStruct) – NetworkStruct object

Returns:

True if the network has binding finite buffers or capacity regions

Return type:

bool

sn_compat_rate(compat, counts, rates, n)[source]

Total service rate of a compatibility-structured station.

A pool t holds counts[t] identical servers, each running at rates[t], and may serve operand j when compat[t, j] is nonzero. The rate the station clears in state n is:

mu(n) = sum_t counts[t]*rates[t]*min(1, sum_{j: compat[t,j] != 0} n[j])

the ACTIVATED-SERVER law: a pool contributes its full rate as soon as it is compatible with at least one operand PRESENT. This is the order-independent reading of a compatibility structure – at an INTEGER state mu depends on n only through its SUPPORT, so it is invariant to the arrival order and to any permutation of the microstate, which is exactly the condition an OI station has to meet (Dorsman & Gardner, Queueing Systems 107:205-256, 2024, Fig. 1). It is also what pas_compatibility_5class.m encodes for a flat Network, so the layered and flat readings of one compatibility matrix agree.

WHY min(1, .) AND NOT AN INDICATOR. At every integer state the two agree exactly – a pool with at least one compatible job present is fully active, one with none is idle – so nothing about the OI law on the real state lattice changes. They part company only at a FRACTIONAL argument, which is what a mean-value solver hands this function: AMVA evaluates the rate at a MEAN population, and under a hard indicator any operand with a mean above zero, however small, activates every pool it touches. A compatibility structure would then be invisible to AMVA whenever every operand is a little bit busy – which is nearly always. Scaling linearly below one job keeps the structure visible at the evaluation point while leaving the integer-state law untouched; it is the ordinary continuous relaxation of a step function, and the CTMC and simulation paths, which only ever evaluate at integer states, cannot tell the difference.

IT IS NOT A MATCHING. A pool of two servers compatible with a class holding ONE job contributes both servers here, which over-counts against a non-redundant system where one server serves one job. That is deliberate: the matching size depends on the counts and not only on the support, so it is NOT order independent and would take the station outside the product form the OI closure is built on. A model that means the matching wants a different station, not a different reading of this one.

Parameters:
  • compat – (npools x noperands) array, nonzero where the pool may serve

  • counts – (npools) servers held by each pool

  • rates – (npools) per-server rate of each pool

  • n – (noperands) per-operand population, integer or fractional

Returns:

the total service rate mu(n)

sn_compat_peak(counts, rates)[source]

Rate a compatibility declaration clears with every pool active, sum_t counts[t]*rates[t].

Utilization at a rate-scaled station is reported as U = T*S/peak, and the peak is a property of the DECLARATION rather than of a state, so it is computed once and handed to the solver beside the rate handle rather than recovered from sn_compat_rate() at a guessed state.

sn_compat_scaling(compat, counts, rates, n)[source]

Rate scaling eta(n) a compatibility declaration imposes on its station.

This is what SolverLN carries onto the layer station, and it is NOT sn_compat_rate / sn_compat_peak. The denominator is the rate the SAME population would obtain under FULL compatibility:

eta(n) = mu(n) / (peak * min(1, sum_j n_j / S))

so eta isolates the effect of the compatibility GRAPH and nothing else. The denominator DAMPS BY OCCUPANCY RELATIVE TO THE SERVER COUNT, min(1, N/S), because that is precisely what the solver’s own multiserver term contributes: it applies min(N,S) servers at the average server rate peak/S, so:

min(N,S) * (peak/S) * eta(n) = mu(n)

and the station clears the activated-server rate exactly, at every state.

DAMPING BY min(1, N) INSTEAD – which this did until 2026-08-28 – leaves the effective law at min(N,S)/S * mu(n), which cancels the REDUNDANCY SPEED-UP the activated-server law exists to express: a pool of S servers facing one compatible job clears S, not 1, because every one of them works on it and the first to finish cancels the rest. Under the old normalization a fully compatible pool reduced to the plain multiserver, so the OI machinery did no work in the homogeneous case and LDES, which simulates mu(n) directly, disagreed with it by that factor.

eta is therefore ABOVE ONE at low occupancy, which is not a defect: it is the speed-up carried by servers that would otherwise be idle. A FULLY-COMPATIBLE POOL IS THEREFORE NOT THE NEUTRAL eta == 1 – it is min(1, N) / min(1, N/S), which is S below one job, S/N between one job and S, and 1 from S jobs up. tests/test_lqn_server_pools.py pins that law both directly and through the layer station.

sn_is_mm1k_loss(sn)[source]

Check if the model is a single-station M/M/1/K queue with tail drop.

True for a single-class open Source-Queue-Sink system whose queue is a single-server exponential M/M/1/K with tail drop (DropStrategy.Drop). This is the exact regime of the closed-form loss scripts qsys_mm1k_loss (probability-based, SolverNC) and qsys_mg1k_loss_mgs (moment-based, SolverMVA), and the one truncated shape that keeps a product form over its single station, hence the exemption in sn_has_blocking.

Parameters:

sn (NetworkStruct) – NetworkStruct object

Returns:

True if the model is a single-station M/M/1/K with tail drop

Return type:

bool

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 - At FCFS stations, all active class SCVs are approximately 1 (BCMP type 1)

Parameters:

sn (NetworkStruct) – NetworkStruct object

Returns:

True if network has product-form solution

Return type:

bool

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:

bool

sn_has_product_form_not_het_fcfs(sn, check_means=True)[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) and all active class service means agree (BCMP type 1 asks the FCFS service to be class-independent, not merely exponential)

Parameters:
  • sn (NetworkStruct) – NetworkStruct object

  • check_means (bool) – also demand class-independent FCFS service means. Pass False only for an algorithm that models class-dependent FCFS itself (ab, schmidt, schmidt-ext), for which the exclusion is the whole point.

Returns:

True if network would have product form without heterogeneous FCFS

Return type:

bool

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:

bool

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:

bool

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:

List[ndarray]

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:

NetworkStruct

References

MATLAB: matlab/src/api/sn/sn_refresh_process_fields.m

sn_is_phasetype(proc, pie=None)[source]

Test whether a process representation admits a phase-type reading.

A representation is Markovian when D0 has nonnegative off-diagonal entries, every D_k with k >= 1 is nonnegative, and the entry vector pie is nonnegative. Exactly under those conditions do sn.mu, sn.phi and sn.pie carry their probabilistic reading (mu_i = -D0(i,i) is a rate, phi_i a completion probability, pie a distribution over phases), which is what the CTMC state space, SSA and the fluid ODEs consume.

A matrix-exponential (ME) or rational (RAP) process fails the test: its moments, transforms and aggregated stationary measures remain exact, but the per-phase quantities are signed. See _kb/04-networkstruct.md.

An entry that is empty, holds scalar distribution parameters, or carries a NaN describes a disabled or not-yet-Markovian process; there is no phase decomposition to invalidate, so it passes.

Mirrors matlab/src/api/sn/sn_is_phasetype.m and jline.api.sn.SnIsPhaseType.

Parameters:
  • proc – Process representation, a sequence [D0, D1, …].

  • pie – Optional entry vector to test for nonnegativity.

Returns:

True when the representation is Markovian.

Return type:

bool

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

sn_interlock_chain(sn, ILclass)[source]

Aggregate a class-indexed interlock matrix to the chain basis of the MVA solvers.

ILclass[r,s] is the share of the class-s queue that a class-r arrival must not see, the interlocked flow of Franks (1999), Eq. (4.7). Two classes of the same chain belong to the same client, so the diagonal blocks carry no information and the chain diagonal stays zero: an arrival always sees its own chain in full.

Reference: G. Franks, “Performance Analysis of Distributed Server Systems”, PhD thesis, Carleton University, 1999, Ch. 4.

sn_patience_handles(sn, ist, r)[source]

Build ccdf, pdf and hazard handles for the patience law of station ist, class r.

Parameters:
  • sn – the NetworkStruct

  • ist (int) – station index

  • r (int) – class index

Returns:

Dict with ccdf, pdf, hazard (callables), mean, isExponential and rate; None when the station-class pair has no reneging patience configured.

Return type:

Dict[str, Any] | None

See also

matlab/src/api/sn/sn_patience_handles.m

sn_arrival_rate_fun(sn, ist, r)[source]

Build lambda(t) for station ist, class r.

LINE carries a time-varying arrival as a MAPt or an NHPP, whose sn.proc slot holds a piecewise-constant schedule, so lambda(t) is read off the segment in force at t. For any other process the rate is constant and the handle returns it, which is what lets a caller ask for the time-varying analysis of a stationary model and get the stationary answer rather than an error.

Parameters:
  • sn – the NetworkStruct

  • ist (int) – station index

  • r (int) – class index

Returns:

(lambdaFun, isTimeVarying, period); period is the cycle length when the schedule is cyclic and inf otherwise.

Return type:

Tuple[Callable[[Any], Any], bool, float]

See also

matlab/src/api/sn/sn_arrival_rate_fun.m