LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
solver_ssa_analyzer_nrm.m
1function [XN,UN,QN,RN,TN,CN,tranSysState,tranSync,sn] = solver_ssa_analyzer_nrm(sn, options)
2% SOLVER_SSA_ANALYZER_NRM Performance indices from SSA/NRM simulation
3% This variant runs the next‑reaction–method SSA on the network SN and
4% returns mean throughput (XN), utilisation (UN), queue length (QN),
5% response time (RN), throughput per station (TN) and class residence
6% time (CN). Results are based on the empirical state probabilities
7% obtained from SOLVER_SSA_NRM.
8% *** Only the scheduling policies listed in ALLOWEDSCHED below are
9% supported. Any other policy triggers an error. Cache nodes are not
10% supported in this simplified variant. ***
11
12% Validate scheduling policies ---------------------------------------------------
13% Keep this list in sync with the propensity switch of SOLVER_SSA_NRM and with
14% the NRM eligibility gate of SOLVER_SSA_ANALYZER.
15allowedSched = [SchedStrategy.INF, SchedStrategy.EXT, SchedStrategy.PS, ...
16 SchedStrategy.LPS, SchedStrategy.DPS, SchedStrategy.GPS, ...
17 SchedStrategy.PSPRIO, SchedStrategy.DPSPRIO, SchedStrategy.GPSPRIO, ...
18 SchedStrategy.FCFS, SchedStrategy.LCFS, SchedStrategy.SIRO, ...
19 SchedStrategy.HOL, SchedStrategy.SEPT, SchedStrategy.LEPT, ...
20 SchedStrategy.LCFSPR, SchedStrategy.PAS, SchedStrategy.POLLING];
21if any(~arrayfun(@(s) any(s == allowedSched), sn.sched))
22 unsupported = unique(sn.sched(~arrayfun(@(s) any(s == allowedSched), sn.sched)));
23 names = strjoin(arrayfun(@(s) SchedStrategy.toText(s), unsupported, 'UniformOutput', false), ', ');
24 error('solver_ssa_analyzer_nrm:UnsupportedPolicy', ...
25 'The NRM method does not support the scheduling policy: %s.', names);
26end
27
28% see _kb/06-solver-catalog.md for rationale (SSA immfeed self-loop)
29if isfield(sn,'immfeed') && ~isempty(sn.immfeed) && any(sn.immfeed(:))
30 line_warning(mfilename,'SolverSSA(method=nrm) does not model immediate feedback (immfeed); self-loops are treated as class-switching with re-queueing. Use method=''serial'' for immediate feedback.\n');
31end
32
33% Shorthands --------------------------------------------------------------------
34M = sn.nstations; % number of stations
35K = sn.nclasses; % number of classes
36S = sn.nservers; % server multiplicities per station
37NK = sn.njobs'; % population vector (closed chains)
38PH = sn.proc; % service‑process MAPs/PHs
39sched = sn.sched; % scheduling policies
40
41% Pre‑allocate performance vectors/matrices --------------------------------------
42XN = NaN(1,K); % class throughput
43UN = NaN(M,K); % utilisation
44QN = NaN(M,K); % mean jobs at station
45RN = NaN(M,K); % response time
46TN = NaN(M,K); % class throughput at station (departures)
47CN = NaN(1,K); % cycle time per class
48% -------------------------------------------------------------------------------
49% 1) Run the SSA/NRM simulator ---------------------------------------------------
50% -------------------------------------------------------------------------------
51% see _kb/06-solver-catalog.md for rationale (SSA NRM engine dispatch)
52useBufferedNrm = true;
53if isfield(options, 'config') && isfield(options.config, 'state_space_gen')
54 ssg = options.config.state_space_gen;
55 if ~(strcmp(ssg, 'none') || strcmp(ssg, 'default'))
56 useBufferedNrm = false;
57 end
58end
59if useBufferedNrm
60 % Compute only stead-state mean performance indices while running nrm
61 [QN, UN, RN, TN, CN, XN, ~, sn] = solver_ssa_nrm(sn, options);
62else
63 % Use explicit state space generation version
64
65 % -------------------------------------------------------------------------------
66 % 1) Run the SSA/NRM simulator ---------------------------------------------------
67 % -------------------------------------------------------------------------------
68 [pi,space,depRates,sn] = solver_ssa_nrm_space(sn, options);
69 pi=pi(:)';
70
71 % -------------------------------------------------------------------------------
72 % 2) Aggregate performance indices ----------------------------------------------
73 % -------------------------------------------------------------------------------
74 % Global class throughput ---------------------------------------------------------
75 for i=1:M
76 for k = 1:K
77 refnd = sn.stationToNode(sn.refstat(k)); % reference (sink) stateful index
78 XN(k) = pi * depRates(:, (refnd-1)*K+k);
79 end
80 end
81
82 % Station‑level metrics -----------------------------------------------------------
83 rates = sn.rates;
84 for ist = 1:M
85 ind = sn.stationToNode(ist); % reference (sink) stateful index
86 for k = 1:K
87 TN(ist,k) = pi * depRates(:, (ind-1)*K+k);
88 QN(ist,k) = pi * space(:, (ind-1)*K + k);
89 end
90
91 switch sched(ist)
92 case {SchedStrategy.INF, SchedStrategy.EXT}
93 % Infinite‑server or external delay: utilisation equals mean jobs
94 UN(ist,:) = QN(ist,:);
95
96 case {SchedStrategy.PS, SchedStrategy.FCFS, SchedStrategy.LCFS}
97 % see _kb/06-solver-catalog.md for rationale (SSA utilization estimator)
98 isCd = ~isempty(sn.cdscaling) && ist <= numel(sn.cdscaling) && ~isempty(sn.cdscaling{ist});
99 isJd = ~isempty(sn.jdscaling) && ist <= numel(sn.jdscaling) && ~isempty(sn.jdscaling{ist});
100 for k = 1:K
101 if ~isempty(PH{ist}{k})
102 if isCd || isJd
103 % Util = T*S/peak, effective peak = product of the
104 % declared class- and joint-dependence peaks.
105 sdiv = 1;
106 if isCd, sdiv = sdiv * sn.cdscalingpeak(ist,k); end
107 if isJd, sdiv = sdiv * sn.jdscalingpeak(ist,k); end
108 else
109 sdiv = S(ist);
110 end
111 if sdiv > 0
112 UN(ist,k) = pi * depRates(:, (ind-1)*K+k) / rates(ist,k) / sdiv;
113 else
114 UN(ist,k) = 0;
115 end
116 end
117 end
118 end
119 end
120
121 % Response time (Little's law) & cycle time --------------------------------------
122 for k = 1:K
123 for ist = 1:M
124 if TN(ist,k) > 0
125 RN(ist,k) = QN(ist,k) / TN(ist,k);
126 else
127 RN(ist,k) = 0;
128 end
129 end
130 CN(k) = NK(k) / XN(k);
131 end
132end
133
134% -------------------------------------------------------------------------------
135% 3) Post‑process and clean‑up ----------------------------------------------------
136% -------------------------------------------------------------------------------
137QN(isnan(QN)) = 0; UN(isnan(UN)) = 0; RN(isnan(RN)) = 0;
138XN(isnan(XN)) = 0; TN(isnan(TN)) = 0; CN(isnan(CN)) = 0;
139
140tranSysState = []; % transient traces removed in this streamlined version
141tranSync = [];
142end
Definition fjtag.m:161