solvers.SSA
- ssa_nrm_refusal(sn)
[OK, REASON] = SSA_NRM_REFUSAL(SN) Whether an EXPLICIT options.method=’nrm’ can answer this model.
NOT SSA_NRM_ELIGIBLE, and the difference is the whole point of having two predicates. SSA_NRM_ELIGIBLE asks whether the NRM should be PREFERRED, and it is deliberately wide: SOLVER_SSA_ANALYZER consults it on the ‘default’ and ‘parallel’ paths to pick an engine. This one asks what a GATE must ask, which is whether the name the caller typed will produce an answer.
The two differ because the explicit ‘nrm’ arm of SOLVER_SSA_ANALYZER FALLS BACK to the serial engine, with a warning, for reneging patience, balking, phase-type service, global dependence and cache retrieval. A model carrying any of those still gets a correct answer under ‘nrm’, so refusing it here would withdraw a row the solver honours – the report would be wrong in the opposite direction.
What is left is the ONE condition that reaches SOLVER_SSA_ANALYZER_NRM and raises there rather than falling back: a scheduling discipline the reaction network has no form for (solver_ssa_analyzer_nrm.m:24, ‘solver_ssa_analyzer_nrm:UnsupportedPolicy’). That is the rule this gate states, and only that one.
The C++ port gates on the wider set ON PURPOSE and is not diverging: its NRM has no fallback arm at all, so every one of the six conditions raises there. Each gate states its own engine’s reach.
- solver_ssa_nrm_OMR(sn, options)
SOLVER_SSA_NRM Steady‑state analysis via the Next‑Reaction Method (SSA)
[PI, SSQ, ARVRATES, DEPRATES, SN] = SOLVER_SSA_NRM(SN, OPTIONS) runs a stochastic simulation of the queueing network described in SN for OPTIONS.samples reaction firings using Gibson & Bruck’s Next‑Reaction Method. During the run it:
observes every distinct global state visited and the time spent in it;
accumulates the per‑state propensities of all enabled reactions, including self‑loops (service completions routed back to the same queue).
- Outputs
- PI – 1×S vector of empirical steady‑state probabilities
(sojourn‑time fractions) for the S unique states;
- SSQ – S×(M·R) matrix listing those states row‑by‑row in the
flattened (station, class) order;
- DEPRATES – S×(M·R) matrix of total departure rates from each queue
in the corresponding state;
SN – (Possibly updated) network structure.
See also
NEXT_REACTION_METHOD.
- solver_ssa(sn, init_state, options, eventCache)
[PI,SSQ,ARVRATES,DEPRATES,TRANSYSSTATE,QN,DLYRATES,STARTRATES,PREEMPTRATES,TRANSTARTTAG,TRANPREEMPTTAG]=SOLVER_SSA(QN,OPTIONS)
STARTRATES and PREEMPTRATES are the derived START/PREEMPT rates per unique state, laid out like ARVRATES/DEPRATES: how fast the transitions enabled in that state start a class-r service at a stateful node, or push a class-r job in service there back into the buffer.
TRANSTARTTAG{e} and TRANPREEMPTTAG{e} are the tags of the transition that actually FIRED at step e, as rows [statefulIndex class]. The trace needs them explicitly: @SolverSSA/sample.m rebuilds events from sn.sync{tranSync(e)}, which by construction carries no derived tag.
- solver_ssa_analyzer_parallel(sn, init_state, laboptions)
[XN,UN,QN,RN,TN,CN]=SOLVER_SSA_ANALYZER_PARALLEL(SN, INIT_STATE, LABOPTIONS)
Worker-count-invariant parallel SSA.
The simulation budget is split into a FIXED number of independent replications R (laboptions.config.nreplicas). Replication r simulates ceil(samples/R) events and is seeded deterministically with (seed+r-1): inside a parfor body spmdIndex resolves to 1 in solver_ssa, so the effective seed is exactly laboptions.seed+r-1, independent of which worker executes the iteration. The R replications are distributed over whatever workers the parallel pool provides (and run on the client if no pool exists), and the per-replication estimates are averaged.
Because replication r always uses the same seed and sample budget no matter how many workers are available, the returned averages depend only on (seed, samples, R) and are invariant to the worker count. This is the key difference from the previous spmd implementation, whose result varied with the pool size (it both divided the budget by, and seeded labs from, the runtime number of labs).
- solver_ssa_findenabled(sn, node_a, enabled_next_states, cur_state, outprob_a, event_a, class_a, isSimulation, node_p, local, outprob_p, event_p, class_p, sync, gsync, depRatesSamples, samples_collected, arvRatesSamples, last_node_a, last_node_p, eventCache, startRatesSamples, preemptRatesSamples)
The START/PREEMPT accumulators and per-transition tags mirror the inlined enumeration in solver_ssa.m: this is the SAME enumeration, kept as a function, so tagging only one of the two would make the counters depend on the use_inline performance flag.
- solver_ssa_analyzer_serial(sn, init_state, options, isHashed)
[XN,UN,QN,RN,TN,CN,TRANSYSSTATE,TRANSYNC,SN,STARTN,PREEMPTN,TRANSTARTTAG,TRANPREEMPTTAG]=SOLVER_SSA_ANALYZER_SERIAL(SN, OPTIONS)
STARTN and PREEMPTN are the (station x class) service-start and preemption rates, estimated exactly as TN is: the time average of the rate the enabled transitions carry. TRANSTARTTAG/TRANPREEMPTTAG are the per-step tags of the sampled path, used by @SolverSSA/sample.m to emit START and PREEMPT events.
- solver_ssa_analyzer_nrm(sn, options)
SOLVER_SSA_ANALYZER_NRM Performance indices from SSA/NRM simulation This variant runs the next‑reaction–method SSA on the network SN and returns mean throughput (XN), utilisation (UN), queue length (QN), response time (RN), throughput per station (TN) and class residence time (CN). Results are based on the empirical state probabilities obtained from SOLVER_SSA_NRM. * Only the scheduling policies listed in ALLOWEDSCHED below are supported. Any other policy triggers an error. Cache nodes are not supported in this simplified variant. *
- class EventCache
EventCache Event caching utilities for SSA solver optimization
EventCache provides static methods to create and manage event caching for the Stochastic State-space Analysis (SSA) solver. Event caching improves performance by storing computed events to avoid redundant calculations during simulation.
@brief Event caching system for SSA solver performance optimization
The cache stores mappings of state transitions and their associated events, enabling faster simulation execution by reusing previously computed results.
- Method Summary
- static create(enabled, sn)
CREATE Create an event cache container
@brief Creates a dictionary for event caching if enabled @param enabled Boolean flag to enable/disable caching @param sn Network structure containing model information @return eventCache dictionary instance or empty array
- solver_ssa_reachability(sn, options)
[SSQ,SSH,QN] = SOLVER_SSA_REACHABILITY(QN,OPTIONS)
- ssa_firingdep_refusal(sn)
[OK, REASON] = SSA_FIRINGDEP_REFUSAL(SN) Whether SolverSSA can answer a Petri net whose firing rates depend on the marking (Transition.setFiringRateDependence).
IT CANNOT, UNDER ANY METHOD, AND SAYS SO BY NAME. The NRM builds one constant-propensity reaction per timed mode, so the g(marking) multiplier has no place in it, and the contract the solver is held to (line-test test_spn_firing_dependence, test_ssa_rejects_dependence) is a refusal rather than a nominal-rate answer. The registry has no name for the construct (‘Transition’ and ‘Firing’ are declared and the rule is about the handle behind them), so it is structural.
ONE PREDICATE, THREE CALLERS: SolverSSA.supportsModelMethod answers with it so model.help does not offer any ssa.* row on such a net, solver_ssa_analyzer raises with it before an engine is chosen, and the NRM reaction builder raises with it on the enableChecks=false path.
- ssa_nrm_guards(sn)
G = SSA_NRM_GUARDS(SN) The per-feature tests the NRM engine’s dispatch and gate both read.
ONE BODY, THREE CALLERS. SOLVER_SSA_ANALYZER reads the fields INDIVIDUALLY, because its explicit ‘nrm’ arm falls back to the serial engine with a warning that names the offending construct, so it has to know WHICH test failed. SSA_NRM_ELIGIBLE reads them together to answer “should the NRM be preferred”. SSA_NRM_REFUSAL reads only sched, because that is the one condition the explicit arm does not fall back on.
These were local functions of SOLVER_SSA_ANALYZER until 2026-09-05, which is why the eligibility test could not be asked from a gate. Moving them here is what lets all three callers share one definition instead of three copies.
- Fields (all true = the NRM can take it):
sched every station’s discipline has a reaction form phase non-exponential service only where every job present is in service renege no station renegs with non-exponential patience balk no balking strategy outside QUEUE_LENGTH gd no global (Whittle) dependence cache every cache configuration (always true; see below) fcr every finite capacity region rule (always true; see below) spn a Petri net the NRM’s reaction builder can read (see below)
- solver_ssa_nrm_space(sn, options)
SOLVER_SSA_NRM_SPACE Steady‑state analysis via the Next‑Reaction Method (SSA)
[PI, SSQ, ARVRATES, DEPRATES, SN] = SOLVER_SSA_NRM_SPACE(SN, OPTIONS) runs a stochastic simulation of the queueing network described in SN for OPTIONS.samples reaction firings using Gibson & Bruck’s Next‑Reaction Method. During the run it:
observes every distinct global state visited and the time spent in it;
accumulates the per‑state propensities of all enabled reactions, including self‑loops (service completions routed back to the same queue).
- Outputs
- PI – 1×S vector of empirical steady‑state probabilities
(sojourn‑time fractions) for the S unique states;
- SSQ – S×(M·R) matrix listing those states row‑by‑row in the
flattened (station, class) order;
- DEPRATES – S×(M·R) matrix of total departure rates from each queue
in the corresponding state;
SN – (Possibly updated) network structure.
See also
NEXT_REACTION_METHOD.
- solver_ssa_nrm_space_analyzer(sn, options)
SOLVER_SSA_ANALYZER_NRM Performance indices from SSA/NRM simulation This variant runs the next‑reaction–method SSA on the network SN and returns mean throughput (XN), utilisation (UN), queue length (QN), response time (RN), throughput per station (TN) and class residence time (CN). Results are based on the empirical state probabilities obtained from SOLVER_SSA_NRM. * Only stations whose scheduling policy is INF, EXT or PS are supported. Any other policy triggers an error. Cache nodes are not supported in this simplified variant. *
- ssa_nrm_eligible(sn)
[OK, REASON] = SSA_NRM_ELIGIBLE(SN) Whether the next-reaction-method engine can run this model AT ALL.
THIS IS THE PREFERENCE QUESTION, not the gate question. SOLVER_SSA_ANALYZER asks it to decide whether the ‘default’ and ‘parallel’ paths should run the NRM instead of the serial engine. A caller asking whether an EXPLICIT options.method=’nrm’ will produce an answer must ask SSA_NRM_REFUSAL instead, which is narrower: the explicit arm FALLS BACK to the serial engine, with a warning, for every one of these conditions except the scheduling one.
The tests themselves live in SSA_NRM_GUARDS, which SOLVER_SSA_ANALYZER also reads field by field so its fallback warnings can name the construct. One body, three callers.
The NRM simulates open and closed models alike – it only lacks Fork/Join node handling – so the model-class exclusion is Fork/Join, not the INF/PS-only sn_is_population_model.
- solver_ssa_nrm_OM2R2(sn, options)
SOLVER_SSA_NRM Steady‑state analysis via Gibson & Bruck’s Next‑Reaction Method (SSA) as modified in Anderson’s, THE JOURNAL OF CHEMICAL PHYSICS 127, 214107, 2007.
- solver_ssa_nrm(sn, options)
SOLVER_SSA_NRM Steady‑state analysis via the Next‑Reaction Method (SSA)
[QN, UN, RN, TN, CN, XN, LG, SN] = SOLVER_SSA_NRM(SN, OPTIONS) runs a stochastic simulation of the queueing network described in SN for OPTIONS.samples reaction firings using Gibson & Bruck’s Next‑Reaction Method. During the run it:
computes performance metrics directly during simulation;
returns standard queueing performance measures.
- Outputs
QN – M×K matrix of mean queue lengths UN – M×K matrix of utilizations RN – M×K matrix of response times TN – M×K matrix of throughputs CN – 1×K vector of cycle times XN – 1×K vector of system throughputs LG – Logarithm of normalizing constant (not computed) SN – (Possibly updated) network structure. STARTN – M×K rate at which a class-r service starts at station i PREEMPTN – M×K rate at which a class-r job in service is displaced
See also
SOLVER_SSA_NRM_SPACE,NEXT_REACTION_METHOD_DIRECT.
- solver_ssa_analyzer(sn, options)
[QN,UN,RN,TN,CN,XN,RUNTIME,…,STARTN,PREEMPTN,TRANSTARTTAG,TRANPREEMPTTAG] = SOLVER_SSA_ANALYZER(SN, OPTIONS)
STARTN/PREEMPTN are the derived (station x class) service-start and preemption rates, and TRANSTARTTAG/TRANPREEMPTTAG the per-step tags of the sampled path. Both back-ends fill them, so the counters do not depend on which one the dispatch picks. Wrapper that selects the most suitable SSA performance-analysis back-end.
If every station uses scheduling policy INF, EXT, or PS (and the network has no cache nodes), the faster Next-Reaction-Method analyser
-> solver_ssa_analyzer_nrm
is invoked. Otherwise the original serial / parallel analysers are used.
Copyright (c) 2012-2026, Imperial College London All rights reserved.
- solver_ssa_gdfactor(sn, cur_state)
GDNOW = SOLVER_SSA_GDFACTOR(SN, CUR_STATE)
Evaluates the globally state-dependent rate scaling phi(n) declared through setGlobalDependence on the CURRENT sample-path state, returning the (nstations x nclasses) matrix of scalings.
SolverCTMC tabulates phi once per state of the enumerated space; a simulator instead has one state at a time, so the same factorization applies with the table collapsed to a single row. Within a state phi is a constant, so it multiplies the rate of every station service event at that state.