LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
runAnalyzer.m
1function [runtime, tranSysState, tranSync] = runAnalyzer(self, options)
2% [RUNTIME, TRANSYSSTATE] = RUNANALYZER()
3%
4% Run the DES solver on the queueing network model.
5% For LayeredNetwork models, use SolverLDES from line-apps.
6
7T0 = tic;
8if nargin < 2
9 options = self.getOptions;
10end
11self.runAnalyzerChecks(options);
12Solver.resetRandomGeneratorSeed(options.seed);
13
14line_debug('DES solver starting: lang=%s, samples=%d, seed=%d', options.lang, options.samples, options.seed);
15
16tranSysState = [];
17tranSync = [];
18
19% Check if confidence intervals are requested
20[confintEnabled, confintLevel] = Solver.parseConfInt(options.confint);
21
22switch options.lang
23 case 'java'
24 line_debug('Default method: using Java DES discrete-event simulation\n');
25 line_debug('Using Java DES backend');
26 % Convert model to Java
27 jmodel = LINE2JLINE(self.model);
28
29 % Create Java solver with DES-specific options via JLINE wrapper
30 jsolver = JLINE.SolverDES(jmodel, options);
31
32 % Regular Network analysis
33 [runtime] = runNetworkAnalyzer(self, jmodel, jsolver, confintEnabled, options);
34 otherwise
35 line_error(mfilename, 'SolverDES currently only supports Java backend. Use options.lang = ''java''.');
36end
37
38runtime = toc(T0);
39end
40
41function [runtime] = runNetworkAnalyzer(self, jmodel, jsolver, confintEnabled, options)
42% RUNNETWORKANALYZER Run DES analysis for regular Network models
43
44M = jmodel.getNumberOfStations;
45R = jmodel.getNumberOfClasses;
46
47% Check if this is transient analysis
48isTransient = isfield(options, 'timespan') && length(options.timespan) >= 2 && ...
49 isfinite(options.timespan(2));
50
51if isTransient
52 % Run transient analysis directly
53 runTransientAnalyzer(self, jsolver, M, R, options);
54 runtime = 0; % Runtime tracked inside transient analyzer
55 return;
56end
57
58% Steady-state analysis
59[QN, UN, RN, WN, AN, TN] = JLINE.arrayListToResults(jsolver.getAvgTable(true));
60
61CN = JLINE.from_jline_matrix(jsolver.getAvgSysRespT());
62XN = JLINE.from_jline_matrix(jsolver.getAvgSysTput());
63runtime = jsolver.result.runtime;
64QN = reshape(QN', R, M)';
65UN = reshape(UN', R, M)';
66RN = reshape(RN', R, M)';
67TN = reshape(TN', R, M)';
68WN = reshape(WN', R, M)';
69AN = reshape(AN', R, M)';
70
71% Extract FCR metrics and append to result matrices
72sn = self.model.getStruct;
73F = sn.nregions;
74if F > 0
75 result = jsolver.result;
76 isValidMatrix = @(x) ~isempty(x) && isa(x, 'jline.util.matrix.Matrix');
77 if isValidMatrix(result.QNfcr)
78 QNfcr = JLINE.from_jline_matrix(result.QNfcr);
79 UNfcr = JLINE.from_jline_matrix(result.UNfcr);
80 RNfcr = JLINE.from_jline_matrix(result.RNfcr);
81 TNfcr = JLINE.from_jline_matrix(result.TNfcr);
82 WNfcr = JLINE.from_jline_matrix(result.WNfcr);
83 % ANfcr is NaN for FCR (not applicable)
84 ANfcr = NaN(F, R);
85 % Append FCR rows to station metrics
86 QN = [QN; QNfcr];
87 UN = [UN; UNfcr];
88 RN = [RN; RNfcr];
89 TN = [TN; TNfcr];
90 WN = [WN; WNfcr];
91 AN = [AN; ANfcr];
92 end
93end
94
95% Print samples like SSA does
96if options.verbose
97 line_printf('DES samples: %8d\n', options.samples);
98end
99
100self.setAvgResults(QN, UN, RN, TN, AN, WN, CN, XN, runtime, options.method, options.samples);
101
102% Extract confidence intervals from Java solver results
103if confintEnabled
104 result = jsolver.result;
105 % Helper to check for non-null Java objects
106 isValidMatrix = @(x) ~isempty(x) && isa(x, 'jline.util.matrix.Matrix');
107 if isValidMatrix(result.QNCI)
108 QNCI = JLINE.from_jline_matrix(result.QNCI);
109 QNCI = reshape(QNCI', R, M)';
110 else
111 QNCI = [];
112 end
113 if isValidMatrix(result.UNCI)
114 UNCI = JLINE.from_jline_matrix(result.UNCI);
115 UNCI = reshape(UNCI', R, M)';
116 else
117 UNCI = [];
118 end
119 if isValidMatrix(result.RNCI)
120 RNCI = JLINE.from_jline_matrix(result.RNCI);
121 RNCI = reshape(RNCI', R, M)';
122 else
123 RNCI = [];
124 end
125 if isValidMatrix(result.TNCI)
126 TNCI = JLINE.from_jline_matrix(result.TNCI);
127 TNCI = reshape(TNCI', R, M)';
128 else
129 TNCI = [];
130 end
131 if isValidMatrix(result.ANCI)
132 ANCI = JLINE.from_jline_matrix(result.ANCI);
133 ANCI = reshape(ANCI', R, M)';
134 else
135 ANCI = [];
136 end
137 if isValidMatrix(result.WNCI)
138 WNCI = JLINE.from_jline_matrix(result.WNCI);
139 WNCI = reshape(WNCI', R, M)';
140 else
141 WNCI = [];
142 end
143 % Store CI results
144 self.setAvgResultsCI(QNCI, UNCI, RNCI, TNCI, ANCI, WNCI, [], []);
145end
146
147end
148
149function runTransientAnalyzer(self, jsolver, Mjava, R, options)
150% RUNTRANSIENTANALYZER Run transient analysis for DES
151
152T0 = tic;
153
154% Get MATLAB model structure for correct station count
155sn = self.model.getStruct;
156M = sn.nstations; % Use MATLAB station count for cell arrays
157
158% Run transient analysis on Java side
159jsolver.getTranAvg();
160result = jsolver.result;
161runtime = toc(T0);
162
163% Check if transient results are available (result.QNt is a Java 2D array)
164if ~isempty(result.QNt) && ~isempty(result.t)
165 % Get number of time points
166 Tmax = result.t.length();
167 if Tmax > 0
168 % Convert Java transient results to MATLAB format
169 % result.QNt(ist,r) is a Matrix(numTimePoints, 2) with columns [value, time]
170 % Use MATLAB station count for cell arrays so getTranAvg can index correctly
171 QNt = cell(M, R);
172 UNt = cell(M, R);
173 RNt = cell(M, R); % Not computed by DES, will be empty
174 TNt = cell(M, R);
175 CNt = cell(1, R);
176 XNt = cell(1, R);
177
178 % Initialize all cells to NaN
179 for ist = 1:M
180 for r = 1:R
181 QNt{ist, r} = NaN;
182 UNt{ist, r} = NaN;
183 RNt{ist, r} = NaN;
184 TNt{ist, r} = NaN;
185 end
186 end
187
188 % Extract data from Java results (indexed by Java station count)
189 for ist = 1:Mjava
190 for r = 1:R
191 % Queue length transient
192 try
193 jmatrix = result.QNt(ist, r);
194 if ~isempty(jmatrix) && jmatrix.getNumRows() > 0
195 nRows = jmatrix.getNumRows();
196 matData = NaN(nRows, 2);
197 for p = 1:nRows
198 matData(p, 1) = jmatrix.get(p-1, 0); % value
199 matData(p, 2) = jmatrix.get(p-1, 1); % time
200 end
201 QNt{ist, r} = matData;
202 else
203 QNt{ist, r} = NaN;
204 end
205 catch
206 QNt{ist, r} = NaN;
207 end
208
209 % Utilization transient
210 try
211 jmatrix = result.UNt(ist, r);
212 if ~isempty(jmatrix) && jmatrix.getNumRows() > 0
213 nRows = jmatrix.getNumRows();
214 matData = NaN(nRows, 2);
215 for p = 1:nRows
216 matData(p, 1) = jmatrix.get(p-1, 0); % value
217 matData(p, 2) = jmatrix.get(p-1, 1); % time
218 end
219 UNt{ist, r} = matData;
220 else
221 UNt{ist, r} = NaN;
222 end
223 catch
224 UNt{ist, r} = NaN;
225 end
226
227 % Throughput transient
228 try
229 jmatrix = result.TNt(ist, r);
230 if ~isempty(jmatrix) && jmatrix.getNumRows() > 0
231 nRows = jmatrix.getNumRows();
232 matData = NaN(nRows, 2);
233 for p = 1:nRows
234 matData(p, 1) = jmatrix.get(p-1, 0); % value
235 matData(p, 2) = jmatrix.get(p-1, 1); % time
236 end
237 TNt{ist, r} = matData;
238 else
239 TNt{ist, r} = NaN;
240 end
241 catch
242 TNt{ist, r} = NaN;
243 end
244
245 % Response time transient not computed by DES
246 RNt{ist, r} = NaN;
247 end
248 end
249
250 % CNt and XNt not computed for transient
251 for r = 1:R
252 CNt{1, r} = NaN;
253 XNt{1, r} = NaN;
254 end
255
256 % Store transient results
257 self.setTranAvgResults(QNt, UNt, RNt, TNt, CNt, XNt, runtime);
258
259 % Also compute and store steady-state estimates from final transient values
260 QN = NaN(M, R);
261 UN = NaN(M, R);
262 RN = NaN(M, R);
263 TN = NaN(M, R);
264 WN = NaN(M, R);
265 AN = NaN(M, R);
266 CN = NaN(1, R);
267 XN = NaN(1, R);
268
269 for ist = 1:M
270 for r = 1:R
271 if ~isscalar(QNt{ist, r}) && ~isnan(QNt{ist, r}(end, 1))
272 QN(ist, r) = QNt{ist, r}(end, 1);
273 end
274 if ~isscalar(UNt{ist, r}) && ~isnan(UNt{ist, r}(end, 1))
275 UN(ist, r) = UNt{ist, r}(end, 1);
276 end
277 if ~isscalar(TNt{ist, r}) && ~isnan(TNt{ist, r}(end, 1))
278 TN(ist, r) = TNt{ist, r}(end, 1);
279 end
280 end
281 end
282
283 self.setAvgResults(QN, UN, RN, TN, AN, WN, CN, XN, runtime, options.method, 0);
284 end
285end
286
287% Print verbose output if requested
288if options.verbose
289 line_printf('DES transient analysis complete, timespan = [%g, %g]\n', ...
290 options.timespan(1), options.timespan(2));
291end
292end