1function [runtime, analyzer] = runAnalyzer(self, options)
7 options = self.getOptions;
15% The shared gate subsumes
the coarse supports(self.model) test (through
16% supportsModelMethod) and additionally reports which features are unsupported;
17% a separate coarse check here would fire first and name nothing. It also
18% validates options.method, as in
the other
solvers.
19self.runAnalyzerChecks(options);
21Solver.resetRandomGeneratorSeed(options.seed);
23sn = getStruct(self); % doesn't need initial state
24line_debug(options, 'QNS: starting (method=%s, multiserver=%s)', options.method, options.config.multiserver);
26if (strcmp(options.method,'exact')||strcmp(options.method,'mva')) && ~self.model.hasProductFormSolution
27 line_error(mfilename,'The exact method requires
the model to have a product-form solution. This model does not have one. You can use Network.hasProductFormSolution() to check before running
the solver.');
30method = options.method;
34 options.config.multiserver = 'conway';
36 options.config.multiserver = 'rolia';
38 options.config.multiserver = 'zhou';
40 options.config.multiserver = 'suri';
42 options.config.multiserver = 'reiser';
44 options.config.multiserver = 'schmidt';
46 options.config.multiserver = 'rolia';
49if self.model.hasProductFormSolution() || self.model.hasOpenClasses()
50 % Use qnsolver directly for product-form networks or open networks
51 % (QN2LQN does not support Source/Sink
nodes for open networks)
52 line_debug(options, 'QNS: product-form or open model, routing to qns_analyzer');
53 [QN,UN,RN,TN,CN,XN,runtime,actualMethod] = solver_qns_analyzer(sn, options);
55 line_debug(options, 'QNS: non-product-form closed model, converting to LQN and using SolverLQNS');
56 lqnmodel=QN2LQN(self.model);
57 lqn = lqnmodel.getStruct;
59 lqnsoptions = SolverLQNS.defaultOptions;
60 lqnsoptions.verbose = false;
61 actualMethod = options.method; % Track
the actual method for LQNS path
64 lqnsoptions.config.multiserver = 'conway';
65 actualMethod = 'conway';
67 lqnsoptions.config.multiserver = 'rolia';
68 actualMethod = 'rolia';
70 lqnsoptions.config.multiserver = 'zhou';
71 actualMethod = 'zhou';
73 lqnsoptions.config.multiserver = 'suri';
74 actualMethod = 'suri';
76 lqnsoptions.config.multiserver = 'reiser';
77 actualMethod = 'reiser';
79 lqnsoptions.config.multiserver = 'schmidt';
80 actualMethod = 'schmidt';
82 actualMethod = 'rolia'; % Default
is rolia for LQNS
84 AvgTable = SolverLQNS(lqnmodel,lqnsoptions).getAvgTable;
88 t = lqn.ashift + r + (i-1)*sn.nclasses;
89 QN(i,r) = AvgTable.QLen(t);
90 % lqns already reports
the activity utilization per server, which
91 %
is the convention LINE uses at a finite-capacity station, so it
92 %
is carried over unscaled. Dividing by nservers here would report
93 % a utilization nservers times too low.
94 UN(i,r) = AvgTable.Util(t);
95 RN(i,r) = AvgTable.RespT(t);
96 WN(i,r) = AvgTable.ResidT(t);
97 TN(i,r) = AvgTable.Tput(t);
105 analyzer = @(sn) solver_qns_analyzer(sn, options);
109T = getAvgTputHandles(self);
110AN = sn_get_arvr_from_tput(sn, TN, T);
112% Apply default(...) convention based on actual method used
113if strcmp(method, 'default')
114 method = ['default/' actualMethod];
116 method = actualMethod;
119self.setAvgResults(QN,UN,RN,TN,AN,[],CN,XN,runtime,method);