LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
solver_nc_analyzer.m
1function [Q,U,R,T,C,X,lG,runtime,iter,method] = solver_nc_analyzer(sn, options)
2% [Q,U,R,T,C,X,LG,RUNTIME,METHOD] = SOLVER_NC_ANALYZER(QN, OPTIONS)
3
4% Copyright (c) 2012-2026, Imperial College London
5% All rights reserved.
6Tstart = tic;
7
8line_debug('NC analyzer starting: method=%s, nstations=%d, nclasses=%d, njobs=%s', options.method, sn.nstations, sn.nclasses, mat2str(sn.njobs));
9
10% Order-independent (OI) closed network: explicit request, or auto-detected
11% when the closed model consists solely of OI and delay stations. Solved
12% exactly by the balanced-fairness normalizing constant (pfqn_oi_nc) with the
13% OI functional-server (pfqn_oi_fnc) identity for the mean queue lengths.
14if nc_is_oi_model(sn) && any(strcmpi(options.method, {'default','exact'}))
15 line_debug('NC analyzer routing to solver_nc_oi_analyzer (order-independent)');
16 [Q,U,R,T,C,X,lG,runtime,iter,method] = solver_nc_oi_analyzer(sn, options);
17 return
18end
19
20% Importance sampling ('is') specialized to OI / pass-and-swap (P&S) stations:
21% the auto-normalized IS normalizing constant pfqn_pas_is (which reduces to
22% pfqn_oi_is when the swap graph is empty). Triggers on the explicit IS selector
23% 'is'; on 'sampling', which maps to 'is' in the presence of OI/PAS stations
24% (rather than the generic pfqn_mci/pfqn_ls estimators); and on 'default' for a
25% P&S tandem with a non-empty swap graph, which is reducible and has no exact
26% path (a pure-OI tandem on 'default'/'exact' is caught by the exact OI analyzer
27% above).
28if nc_is_pas_model(sn) && any(strcmpi(options.method, {'default','is','sampling'}))
29 line_debug('NC analyzer routing to solver_nc_pas_is_analyzer (pass-and-swap IS)');
30 [Q,U,R,T,C,X,lG,runtime,iter,method] = solver_nc_pas_is_analyzer(sn, options);
31 return
32end
33
34% 'is' is the sample-an-ordering importance-sampling family. OI / pass-and-swap
35% stations are handled above (pfqn_pas_is / pfqn_oi_is); every other CLOSED
36% product-form network falls through to the standard normalizing-constant path,
37% where pfqn_nc routes 'is' to pfqn_is (load-independent) and pfqn_ncld routes it
38% to pfqn_ld_is (load-dependent). The estimator has no open-class form.
39if strcmpi(options.method, 'is') && any(isinf(sn.njobs))
40 line_error(mfilename, 'The ''is'' importance-sampling method requires a closed queueing network. Use ''sampling'' (pfqn_mci/pfqn_ls) for open or mixed models.');
41end
42
43% Maximum Entropy Method (Kouvatsos 1994): explicit request only. The
44% method='default' path routes to the native normalizing-constant analyzer
45% (solver_nc), as it did before MEM was introduced.
46if strcmpi(options.method, 'mem')
47 line_debug('NC analyzer routing to solver_nc_mem (Maximum Entropy)');
48 [Q,U,R,T,C,X,iter] = solver_nc_mem(sn, options);
49 lG = NaN;
50 method = 'mem';
51 runtime = toc(Tstart);
52 return
53end
54
55nservers = sn.nservers;
56if max(nservers(nservers<Inf))>1 & any(isinf(sn.njobs)) & strcmpi(options.method,'exact') %#ok<AND2>
57 line_error(mfilename,'NC solver cannot provide exact solutions for open or mixed queueing networks. Remove the ''exact'' option.');
58end
59
60% interpolate for non-integer closed populations
61eta = abs(sn.njobs - floor(sn.njobs));
62if any(eta>GlobalConstants.FineTol)
63 line_debug('Fractional populations detected, using interpolation');
64 sn_floor = sn; sn_floor.njobs = floor(sn.njobs);
65 [Qf,Uf,Rf,Tf,Cf,Xf,lGf,~,iterf] = solver_nc(sn_floor, options);
66 sn_ceil = sn; sn_ceil.njobs = ceil(sn.njobs);
67 [Qc,Uc,Rc,Tc,Cc,Xc,lGc,~,iterc,method] = solver_nc(sn_ceil, options);
68 Q = Qf + eta .* (Qc-Qf);
69 U = Uf + eta .* (Uc-Uf);
70 R = Rf + eta .* (Rc-Rf);
71 T = Tf + eta .* (Tc-Tf);
72 C = Cf + eta .* (Cc-Cf);
73 X = Xf + eta .* (Xc-Xf);
74 lG = lGf + eta .* (lGf-lGc);
75 iter = iterc + iterf;
76 line_debug('NC interpolation complete: used %d + %d iterations', iterf, iterc);
77else % if integers or open model
78 if any(isinf(sn.njobs))
79 line_debug('Open/mixed model detected, calling solver_nc');
80 else
81 line_debug('Using exact integer populations, calling solver_nc');
82 end
83 [Q,U,R,T,C,X,lG,~,iter,method] = solver_nc(sn, options);
84end
85runtime = toc(Tstart);
86end
Definition Station.m:245