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)
4% Copyright (c) 2012-2026, Imperial College London
8line_debug(
'NC analyzer starting: method=%s, nstations=%d, nclasses=%d, njobs=%s', options.method, sn.nstations, sn.nclasses, mat2str(sn.njobs));
10nservers = sn.nservers;
11if max(nservers(nservers<Inf))>1 & any(isinf(sn.njobs)) & strcmpi(options.method,
'exact') %#ok<AND2>
12 line_error(mfilename,
'NC solver cannot provide exact solutions for open or mixed queueing networks. Remove the ''exact'' option.');
15% interpolate
for non-integer closed populations
16eta = abs(sn.njobs - floor(sn.njobs));
17if any(eta>GlobalConstants.FineTol)
18 line_debug('Fractional populations detected, using interpolation');
19 sn_floor = sn; sn_floor.njobs = floor(sn.njobs);
20 [Qf,Uf,Rf,Tf,Cf,Xf,lGf,~,iterf] = solver_nc(sn_floor, options);
21 sn_ceil = sn; sn_ceil.njobs = ceil(sn.njobs);
22 [Qc,Uc,Rc,Tc,Cc,Xc,lGc,~,iterc,method] = solver_nc(sn_ceil, options);
23 Q = Qf + eta .* (Qc-Qf);
24 U = Uf + eta .* (Uc-Uf);
25 R = Rf + eta .* (Rc-Rf);
26 T = Tf + eta .* (Tc-Tf);
27 C = Cf + eta .* (Cc-Cf);
28 X = Xf + eta .* (Xc-Xf);
29 lG = lGf + eta .* (lGf-lGc);
31 line_debug('NC interpolation complete: used %d + %d iterations', iterf, iterc);
32else % if integers or open model
33 if any(isinf(sn.njobs))
34 line_debug('Open/mixed model detected, calling solver_nc');
36 line_debug('Using exact integer populations, calling solver_nc');
38 [Q,U,R,T,C,X,lG,~,iter,method] = solver_nc(sn, options);