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_ncoi) 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% IS specialized to OI/P&S stations -> pfqn_pas_is (reduces to pfqn_oi_is for an
21% empty swap graph); see _kb/06-solver-catalog.md (NC section, analyzer routing)
22if nc_is_pas_model(sn) && any(strcmpi(options.method, {'default','is','sampling'}))
23 line_debug('NC analyzer routing to solver_nc_pas_is_analyzer (pass-and-swap IS)');
24 [Q,U,R,T,C,X,lG,runtime,iter,method] = solver_nc_pas_is_analyzer(sn, options);
25 return
26end
27
28% plain 'is' is the sample-an-ordering family for closed product-form networks;
29% no open-class form. see _kb/06-solver-catalog.md (NC section, analyzer routing)
30if strcmpi(options.method, 'is') && any(isinf(sn.njobs))
31 line_error(mfilename, 'The ''is'' importance-sampling method requires a closed queueing network. Use ''sampling'' (pfqn_mci/pfqn_ls) for open or mixed models.');
32end
33
34% Maximum Entropy Method (Kouvatsos 1994): explicit request only. The
35% method='default' path routes to the native normalizing-constant analyzer
36% (solver_nc), as it did before MEM was introduced.
37if strcmpi(options.method, 'mem')
38 line_debug('NC analyzer routing to solver_nc_mem (Maximum Entropy)');
39 [Q,U,R,T,C,X,iter,method] = solver_nc_mem(sn, options);
40 lG = NaN;
41 runtime = toc(Tstart);
42 return
43end
44
45nservers = sn.nservers;
46if max(nservers(nservers<Inf))>1 & any(isinf(sn.njobs)) & strcmpi(options.method,'exact') %#ok<AND2>
47 line_error(mfilename,'NC solver cannot provide exact solutions for open or mixed queueing networks. Remove the ''exact'' option.');
48end
49
50% interpolate for non-integer closed populations
51eta = abs(sn.njobs - floor(sn.njobs));
52if any(eta>GlobalConstants.FineTol)
53 line_debug('Fractional populations detected, using interpolation');
54 sn_floor = sn; sn_floor.njobs = floor(sn.njobs);
55 [Qf,Uf,Rf,Tf,Cf,Xf,lGf,~,iterf] = solver_nc(sn_floor, options);
56 sn_ceil = sn; sn_ceil.njobs = ceil(sn.njobs);
57 [Qc,Uc,Rc,Tc,Cc,Xc,lGc,~,iterc,method] = solver_nc(sn_ceil, options);
58 Q = Qf + eta .* (Qc-Qf);
59 U = Uf + eta .* (Uc-Uf);
60 R = Rf + eta .* (Rc-Rf);
61 T = Tf + eta .* (Tc-Tf);
62 C = Cf + eta .* (Cc-Cf);
63 X = Xf + eta .* (Xc-Xf);
64 lG = lGf + eta .* (lGf-lGc);
65 iter = iterc + iterf;
66 line_debug('NC interpolation complete: used %d + %d iterations', iterf, iterc);
67else % if integers or open model
68 if any(isinf(sn.njobs))
69 line_debug('Open/mixed model detected, calling solver_nc');
70 else
71 line_debug('Using exact integer populations, calling solver_nc');
72 end
73 [Q,U,R,T,C,X,lG,~,iter,method] = solver_nc(sn, options);
74end
75runtime = toc(Tstart);
76end