1function [Q,U,R,T,C,X,lG,runtime,iter,method] = solver_nc_lossn_analyzer(sn, options)
2% SOLVER_NC_LOSSN_ANALYZER Analyzes open loss networks with FCR
4% This analyzer handles open queueing networks with a single multiclass
5% Delay node inside a Finite Capacity Region (FCR) with DROP policy.
7% Method selection (options.method):
8%
'erlangfp' (default) - Erlang fixed-point (reduced-load) approximation.
9%
'mci' - Monte Carlo importance-sampling summation
10% (Ross-Wang 1992): estimates
the normalization
11% constant g(C) and class blocking with confidence
12% intervals. Set options.samples and options.seed.
15K = sn.nclasses; % number of classes
18line_debug(
'NC loss network analyzer starting: method=%s, nstations=%d, nclasses=%d', options.method, M, K);
20% 1. Extract arrival rates from Source
23 sourceIdx = sn.refstat(r);
24 nu(r) = sn.rates(sourceIdx, r); % arrival rate
27% 2. Find delay station in FCR and extract constraints
28regionMatrix = sn.region{1};
29stationsInFCR = find(any(regionMatrix(:,1:end-1) >= 0, 2) | regionMatrix(:,end) >= 0);
30delayIdx = stationsInFCR(1);
32globalMax = regionMatrix(delayIdx, K+1);
33classMax = regionMatrix(delayIdx, 1:K);
35% Handle unbounded constraints (replace -1 with large value
for Erlang)
39classMax(classMax < 0) = 1e6;
41% 3. Build A matrix (J x K) where J = K+1 links
42% Link 1: global constraint (all classes contribute)
43% Links 2..K+1: per-
class constraints (only class r contributes to link r+1)
46A(1, :) = 1; % global link: all classes contribute
48 A(r+1, r) = 1; % per-
class link: only class r contributes
51% 4. Build C vector (J x 1)
54C_vec(2:end) = classMax(:);
56% 5. Select method and solve
57tokens = strsplit(lower(options.method), '.');
58useMCI = any(strcmp(tokens, 'mci'));
60lG = NaN; % normalization constant (finite only for mci)
63 if isfield(options, 'samples') && ~isempty(options.samples) && ~isinf(options.samples)
64 mciopt.samples = options.samples;
66 if isfield(options, 'seed') && ~isempty(options.seed)
67 mciopt.seed = options.seed;
69 [QLen, Loss, lG, ~, niter] = lossn_mci(nu, A, C_vec, mciopt);
72 [QLen, Loss, E, niter] = lossn_erlangfp(nu, A, C_vec);
76% 6. Convert to standard outputs
82% At delay node: QLen
is effective throughput (after loss)
84 T(delayIdx, r) = QLen(r); % effective throughput = arrival rate * (1-loss)
85 % Source emits
the accepted (post-drop) rate into
the network so that
the
86 % routing-based arrival-rate computation (sn_get_arvr_from_tput) yields a
87 % non-zero ArvR at
the delay, consistent with
the flow-conserving departure
88 % throughput and with
the simulated rate reported by SolverJMT.
89 sourceIdx = sn.refstat(r);
90 T(sourceIdx, r) = QLen(r);
91 mu_r = sn.rates(delayIdx, r); % service rate at delay
92 Q(delayIdx, r) = QLen(r) / mu_r; % Little's law: Q = X * S
93 R(delayIdx, r) = 1 / mu_r; % response time = service time (infinite server)
94 U(delayIdx, r) = T(delayIdx, r) / mu_r; % "utilization" for delay
97X = QLen(:)'; % system throughput per class (row vector)
98C = zeros(1, K); % cycle time not applicable
100runtime = toc(Tstart);