LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
solver_mva_analyzer.m
1function [Q,U,R,T,C,X,lG,runtime,iter,method] = solver_mva_analyzer(sn, options)
2% [Q,U,R,T,C,X,LG,RUNTIME] = SOLVER_MVA_ANALYZER(QN, OPTIONS)
3
4% Copyright (c) 2012-2026, Imperial College London
5% All rights reserved.
6
7iter = NaN;
8Tstart = tic;
9method = options.method;
10method = regexprep(method, '^amva\.', '');
11
12line_debug(options, 'MVA analyzer starting: method=%s, nclasses=%d, njobs=%s, nchains=%d', method, sn.nclasses, mat2str(sn.njobs), sn.nchains);
13
14switch method
15 case {'exact','mva'}
16 line_debug(options, 'Using exact MVA method, calling solver_mva');
17 [Q,U,R,T,C,X,lG] = solver_mva(sn, options);
18 case {'sqd'}
19 line_debug(options, 'Using BAS method, calling solver_sqd');
20 [Q,U,R,T,C,X,lG,iter] = solver_sqd(sn, options);
21 case {'qna'}
22 line_debug(options, 'Using QNA method, calling solver_qna');
23 [Q,U,R,T,C,X] = solver_qna(sn, options);
24 lG = NaN;
25 case {'sum','esum'}
26 line_debug(options, 'Using summation method, calling solver_mva_sum');
27 [Q,U,R,T,C,X,lG,iter] = solver_mva_sum(sn, options);
28 case {'rqna'}
29 line_debug(options, 'Using RQNA method, calling solver_rqna');
30 [Q,U,R,T,C,X] = solver_rqna(sn, options);
31 lG = NaN;
32 case {'default'}
33 % for non-exponential open queueing networks, use qna
34 % (commented as not ready yet, it fails on example_cacheModel_3.m)
35 %if all(isinf(sn.njobs)) && any(any(sn.scv ~= 1.0))
36 % line_warning(mfilename,'QNA implementation is still in beta version.')
37 % [Q,U,R,T,C,X] = solver_qna(sn, options);
38 % lG = NaN;
39 %else
40 % Bursty single-class open network: the arrival process is non-renewal
41 % (MMPP/MAP), whose autocorrelation a two-moment method cannot capture.
42 % Dispatch the robust queueing network analyzer (RQNA), which
43 % characterizes each flow by its index of dispersion for counts.
44 if sn.nclasses == 1 && all(isinf(sn.njobs)) && sn_has_bursty_arrival(sn)
45 line_debug('Default method: bursty single-class open network, using RQNA\n');
46 line_debug(options, 'Non-renewal arrivals detected, calling solver_rqna');
47 [Q,U,R,T,C,X] = solver_rqna(sn, options);
48 lG = NaN;
49 method = 'rqna';
50 % Closed single-chain Blocking-After-Service network (finite buffers)
51 elseif isBasModel(sn)
52 line_debug('Default method: using BAS for blocking-after-service model\n');
53 line_debug(options, 'Model has Blocking-After-Service finite buffers, calling solver_sqd');
54 [Q,U,R,T,C,X,lG,iter] = solver_sqd(sn, options);
55 method = 'sqd';
56 % Force AMVA for class-dependent models - exact MVA doesn't support them
57 elseif ~isempty(sn.cdscaling)
58 line_debug('Default method: using AMVA for class-dependent model\n');
59 line_debug(options, 'Model has class dependence, calling solver_amva');
60 [Q,U,R,T,C,X,lG,iter,method] = solver_amva(sn, options);
61 elseif any(isinf(sn.njobs)) && any(isfinite(sn.njobs) & sn.njobs > 0) && max(sn.nservers(isfinite(sn.nservers))) == 1 && sn_has_product_form(sn) && all(sn.njobs(isfinite(sn.njobs)) == floor(sn.njobs(isfinite(sn.njobs))))
62 % Mixed open+closed product-form single-server model: exact BCMP
63 % mixed MVA (pfqn_mvamx via solver_mva). The AMVA linearizer inflates
64 % the closed-class response time by double-counting the open-class
65 % interference. Only the finite (closed) populations need to be
66 % integral (isinf fails the fractional-population test spuriously).
67 line_debug('Default method: using exact mixed MVA\n');
68 [Q,U,R,T,C,X,lG] = solver_mva(sn, options);
69 method = 'exact';
70 elseif sn.nchains <= 4 && sum(sn.njobs) <= 20 && sn_has_product_form(sn) && ~sn_has_fractional_populations(sn)
71 line_debug('Default method: using exact MVA\n');
72 % The parameters above take in the worst case a handful of ms
73 line_debug(options, 'Model qualifies for exact MVA (nchains=%d, njobs=%d, product-form=%d), calling solver_mva', sn.nchains, sum(sn.njobs), sn_has_product_form(sn));
74 [Q,U,R,T,C,X,lG] = solver_mva(sn, options);
75 method = 'exact';
76 else
77 line_debug('Default method: using approximate MVA\n');
78 line_debug(options, 'Model requires approximation (nchains=%d, njobs=%d, product-form=%d), calling solver_amva', sn.nchains, sum(sn.njobs), sn_has_product_form(sn));
79 [Q,U,R,T,C,X,lG,iter,method] = solver_amva(sn, options);
80 end
81 %end
82 case {'amva','bs','qd','qli','fli','lin','qdlin','sqni','egflin','gflin','ab','schmidt','schmidt-ext'} %,'aql','qdaql'
83 line_debug(options, 'Using approximate MVA method: %s, calling solver_amva', method);
84 [Q,U,R,T,C,X,lG,iter] = solver_amva(sn, options);
85 otherwise
86 Q=[];
87 U=[];
88 R=[];
89 T=[];
90 C=[];
91 X=[];
92 lG=[];
93 iter=[];
94 if options.verbose
95 line_warning(mfilename,'Unsupported SolverMVA method.');
96 end
97end
98runtime = toc(Tstart);
99
100if options.verbose
101 %line_printf('\nMVA analysis completed. Runtime: %f seconds.\n',runtime);
102end
103
104end
105
106function tf = isBasModel(sn)
107% Detect a closed single-chain network with Blocking-After-Service (BAS) finite-buffer
108% blocking, which solver_sqd handles but exact/AMVA MVA does not.
109tf = false;
110if sn.nchains ~= 1 || sn.nclosedjobs <= 0 || isempty(sn.droprule)
111 return;
112end
113if any(isinf(sn.njobs))
114 return; % open class present
115end
116tf = any(sn.droprule(:) == DropStrategy.BAS);
117end
Definition Station.m:245