LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
JLINE.m
1classdef JLINE
2 % JLINE Conversion utilities for JLINE format models
3 %
4 % JLINE provides static methods to convert between LINE MATLAB models
5 % and JLINE Java/Kotlin models. This class serves as the primary interface
6 % for interoperability between the MATLAB and Java implementations of LINE.
7 %
8 % @brief JLINE format conversion and Java interoperability utilities
9 %
10 % Main functionality:
11 % - Convert LINE MATLAB models to JLINE Java models
12 % - Convert JLINE Java models back to LINE MATLAB format
13 % - Access JLINE solvers from MATLAB
14 % - Handle serialization between MATLAB and Java representations
15 %
16 % Example:
17 % @code
18 % % Convert a LINE model to JLINE format
19 % jnetwork = JLINE.from_model(network);
20 % % Get a JLINE solver
21 % jssa = JLINE.get_solver(jnetwork, 'ssa');
22 % @endcode
23
24 properties (Constant)
25 jar_loc = which('jline.jar');
26 end
27
28 methods(Static)
29
30 function model = from_line_layered_network(line_layered_network)
31 sn = line_layered_network.getStruct;
32
33 %% initialization
34 model = javaObject('jline.lang.layered.LayeredNetwork', line_layered_network.getName);
35
36 %% host processors
37 P = cell(1,sn.nhosts);
38 for h=1:sn.nhosts
39 if isinf(sn.mult(h))
40 sn_mult_h = java.lang.Integer.MAX_VALUE;
41 else
42 sn_mult_h = sn.mult(h);
43 end
44 switch sn.sched(h)
45 case SchedStrategy.REF
46 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.REF);
47 case SchedStrategy.INF
48 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.INF);
49 case SchedStrategy.FCFS
50 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.FCFS);
51 case SchedStrategy.LCFS
52 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LCFS);
53 case SchedStrategy.SIRO
54 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.SIRO);
55 case SchedStrategy.SJF
56 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.SJF);
57 case SchedStrategy.LJF
58 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LJF);
59 case SchedStrategy.PS
60 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.PS);
61 case SchedStrategy.DPS
62 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.DPS);
63 case SchedStrategy.GPS
64 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.GPS);
65 case SchedStrategy.SEPT
66 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.SEPT);
67 case SchedStrategy.LEPT
68 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LEPT);
69 case {SchedStrategy.HOL, SchedStrategy.FCFSPRIO}
70 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.FCFSPRIO);
71 case SchedStrategy.FORK
72 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.FORK);
73 case SchedStrategy.EXT
74 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.EXT);
75 case SchedStrategy.LCFSPR
76 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LCFSPR);
77 case SchedStrategy.LCFSPI
78 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LCFSPI);
79 case SchedStrategy.LCFSPRIO
80 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LCFSPRIO);
81 case SchedStrategy.LCFSPRPRIO
82 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LCFSPRPRIO);
83 case SchedStrategy.LCFSPIPRIO
84 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LCFSPIPRIO);
85 case SchedStrategy.PSPRIO % todo
86 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.PSPRIO);
87 case SchedStrategy.DPSPRIO % todo
88 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.DPSPRIO);
89 case SchedStrategy.GPSPRIO % todo
90 P{h} = javaObject('jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.GPSPRIO);
91 end
92 if sn.repl(h)~=1
93 P{h}.setReplication(sn.repl(h));
94 end
95 end
96
97 %% tasks
98 T = cell(1,sn.ntasks);
99 for t=1:sn.ntasks
100 tidx = sn.tshift+t;
101 if isinf(sn.mult(tidx))
102 sn_mult_tidx = java.lang.Integer.MAX_VALUE;
103 else
104 sn_mult_tidx = sn.mult(tidx);
105 end
106 % Check if this is a CacheTask
107 if sn.iscache(tidx)
108 % Get replacement strategy from ordinal
109 switch sn.replacestrat(tidx)
110 case ReplacementStrategy.RR
111 jReplacestrat = jline.lang.constant.ReplacementStrategy.RR;
112 case ReplacementStrategy.FIFO
113 jReplacestrat = jline.lang.constant.ReplacementStrategy.FIFO;
114 case ReplacementStrategy.SFIFO
115 jReplacestrat = jline.lang.constant.ReplacementStrategy.SFIFO;
116 case ReplacementStrategy.LRU
117 jReplacestrat = jline.lang.constant.ReplacementStrategy.LRU;
118 otherwise
119 jReplacestrat = jline.lang.constant.ReplacementStrategy.FIFO;
120 end
121 T{t} = javaObject('jline.lang.layered.CacheTask', model, sn.names{tidx}, sn.nitems(tidx), sn.itemcap{tidx}, jReplacestrat, sn_mult_tidx);
122 elseif sn.isfunction(tidx)
123 % FunctionTask (has setupTime/delayOffTime)
124 jSchedStrategy = JLINE.to_jline_sched_strategy(sn.sched(tidx));
125 T{t} = javaObject('jline.lang.layered.FunctionTask', model, sn.names{tidx}, sn_mult_tidx, jSchedStrategy);
126 else
127 jSchedStrategy = JLINE.to_jline_sched_strategy(sn.sched(tidx));
128 T{t} = javaObject('jline.lang.layered.Task', model, sn.names{tidx}, sn_mult_tidx, jSchedStrategy);
129 end
130 T{t}.on(P{sn.parent(tidx)});
131 if sn.repl(tidx)~=1
132 T{t}.setReplication(sn.repl(tidx));
133 end
134 if ~isempty(sn.think{tidx}) && sn.think_type(tidx) ~= ProcessType.DISABLED
135 switch sn.think_type(tidx)
136 case ProcessType.IMMEDIATE
137 T{t}.setThinkTime(jline.lang.processes.Immediate);
138 case ProcessType.EXP
139 T{t}.setThinkTime(jline.lang.processes.Exp(1/sn.think_mean(tidx)));
140 case ProcessType.ERLANG
141 T{t}.setThinkTime(jline.lang.processes.Erlang.fitMeanAndSCV(sn.think_mean(tidx), sn.think_scv(tidx)));
142 case ProcessType.HYPEREXP
143 if ~isempty(sn.think_params{tidx}) && length(sn.think_params{tidx}) >= 3
144 T{t}.setThinkTime(jline.lang.processes.HyperExp(sn.think_params{tidx}(1), sn.think_params{tidx}(2), sn.think_params{tidx}(3)));
145 else
146 T{t}.setThinkTime(jline.lang.processes.HyperExp.fitMeanAndSCV(sn.think_mean(tidx), sn.think_scv(tidx)));
147 end
148 case ProcessType.COXIAN
149 T{t}.setThinkTime(jline.lang.processes.Coxian.fitMeanAndSCV(sn.think_mean(tidx), sn.think_scv(tidx)));
150 case ProcessType.APH
151 T{t}.setThinkTime(jline.lang.processes.APH.fitMeanAndSCV(sn.think_mean(tidx), sn.think_scv(tidx)));
152 case ProcessType.PH
153 if ~isempty(sn.think_proc{tidx})
154 proc = sn.think_proc{tidx};
155 T{t}.setThinkTime(jline.lang.processes.PH(JLINE.from_line_matrix(proc{1}), JLINE.from_line_matrix(proc{2})));
156 else
157 T{t}.setThinkTime(jline.lang.processes.Exp(1/sn.think_mean(tidx)));
158 end
159 case ProcessType.MAP
160 if ~isempty(sn.think_proc{tidx})
161 proc = sn.think_proc{tidx};
162 T{t}.setThinkTime(jline.lang.processes.MAP(JLINE.from_line_matrix(proc{1}), JLINE.from_line_matrix(proc{2})));
163 else
164 T{t}.setThinkTime(jline.lang.processes.Exp(1/sn.think_mean(tidx)));
165 end
166 otherwise
167 line_error(mfilename,sprintf('JLINE conversion does not support the %s distribution for task think time yet.',char(sn.think_type(tidx))));
168 end
169 end
170 % Setup time
171 if sn.isfunction(tidx) && ~isnan(sn.setuptime_mean(tidx)) && sn.setuptime_mean(tidx) > 1e-8
172 T{t}.setSetupTime(sn.setuptime_mean(tidx));
173 end
174 % Delay-off time
175 if sn.isfunction(tidx) && ~isnan(sn.delayofftime_mean(tidx)) && sn.delayofftime_mean(tidx) > 1e-8
176 T{t}.setDelayOffTime(sn.delayofftime_mean(tidx));
177 end
178 end
179 %% entries
180 E = cell(1,sn.nentries);
181 for e=1:sn.nentries
182 eidx = sn.eshift+e;
183 % Check if this is an ItemEntry (has nitems > 0)
184 if sn.nitems(eidx) > 0
185 % ItemEntry requires cardinality and popularity distribution
186 if ~isempty(sn.itemproc) && ~isempty(sn.itemproc{eidx})
187 jPopularity = JLINE.from_line_distribution(sn.itemproc{eidx});
188 else
189 % Default to uniform distribution
190 jPopularity = javaObject('jline.lang.processes.DiscreteSampler', jline.util.matrix.Matrix.uniformDistribution(sn.nitems(eidx)));
191 end
192 E{e} = javaObject('jline.lang.layered.ItemEntry', model, sn.names{eidx}, sn.nitems(eidx), jPopularity);
193 else
194 E{e} = javaObject('jline.lang.layered.Entry', model, sn.names{eidx});
195 end
196 E{e}.on(T{sn.parent(eidx)-sn.tshift});
197 end
198
199 %% activities
200 A = cell(1,sn.nacts);
201 for a=1:sn.nacts
202 aidx = sn.ashift+a;
203 tidx = sn.parent(aidx);
204 onTask = tidx-sn.tshift;
205 % Convert host demand from primitives to Java distribution
206 switch sn.hostdem_type(aidx)
207 case ProcessType.IMMEDIATE
208 jHostDem = jline.lang.processes.Immediate;
209 case ProcessType.DISABLED
210 jHostDem = jline.lang.processes.Disabled;
211 case ProcessType.EXP
212 jHostDem = javaObject('jline.lang.processes.Exp', 1/sn.hostdem_mean(aidx));
213 case ProcessType.ERLANG
214 jHostDem = jline.lang.processes.Erlang.fitMeanAndSCV(sn.hostdem_mean(aidx), sn.hostdem_scv(aidx));
215 case ProcessType.HYPEREXP
216 if ~isempty(sn.hostdem_params{aidx}) && length(sn.hostdem_params{aidx}) >= 3
217 jHostDem = javaObject('jline.lang.processes.HyperExp', sn.hostdem_params{aidx}(1), sn.hostdem_params{aidx}(2), sn.hostdem_params{aidx}(3));
218 else
219 jHostDem = jline.lang.processes.HyperExp.fitMeanAndSCV(sn.hostdem_mean(aidx), sn.hostdem_scv(aidx));
220 end
221 case ProcessType.COXIAN
222 jHostDem = jline.lang.processes.Coxian.fitMeanAndSCV(sn.hostdem_mean(aidx), sn.hostdem_scv(aidx));
223 case ProcessType.APH
224 jHostDem = jline.lang.processes.APH.fitMeanAndSCV(sn.hostdem_mean(aidx), sn.hostdem_scv(aidx));
225 case ProcessType.PH
226 if ~isempty(sn.hostdem_proc{aidx})
227 proc = sn.hostdem_proc{aidx};
228 jHostDem = javaObject('jline.lang.processes.PH', JLINE.from_line_matrix(proc{1}), JLINE.from_line_matrix(proc{2}));
229 else
230 jHostDem = javaObject('jline.lang.processes.Exp', 1/sn.hostdem_mean(aidx));
231 end
232 case ProcessType.MAP
233 if ~isempty(sn.hostdem_proc{aidx})
234 proc = sn.hostdem_proc{aidx};
235 jHostDem = javaObject('jline.lang.processes.MAP', JLINE.from_line_matrix(proc{1}), JLINE.from_line_matrix(proc{2}));
236 else
237 jHostDem = javaObject('jline.lang.processes.Exp', 1/sn.hostdem_mean(aidx));
238 end
239 case ProcessType.DET
240 jHostDem = javaObject('jline.lang.processes.Det', sn.hostdem_mean(aidx));
241 otherwise
242 line_error(mfilename,sprintf('JLINE conversion does not support the %s distribution for host demand yet.',char(sn.hostdem_type(aidx))));
243 end
244 A{a} = javaObject('jline.lang.layered.Activity', model, sn.names{aidx}, jHostDem);
245 A{a}.on(T{onTask});
246
247 boundTo = find(sn.graph((sn.eshift+1):(sn.eshift+sn.nentries),aidx));
248
249 if ~isempty(boundTo)
250 A{a}.boundTo(E{boundTo});
251 end
252
253 if sn.sched(tidx) ~= SchedStrategy.REF % ref tasks don't reply
254 repliesTo = find(sn.replygraph(a,:)); % index of entry
255 if ~isempty(repliesTo)
256 if ~sn.isref(sn.parent(sn.eshift+repliesTo))
257 A{a}.repliesTo(E{repliesTo});
258 end
259 end
260 end
261
262 if ~isempty(sn.callpair)
263 cidxs = find(sn.callpair(:,1)==aidx);
264 calls = sn.callpair(:,2);
265 for c = cidxs(:)'
266 switch sn.calltype(c)
267 case CallType.SYNC
268 A{a}.synchCall(E{calls(c)-sn.eshift},sn.callproc_mean(c));
269 case CallType.ASYNC
270 A{a}.asynchCall(E{calls(c)-sn.eshift},sn.callproc_mean(c));
271 end
272 end
273 end
274
275 end
276
277 %% think times
278 for h=1:sn.nhosts
279 if ~isempty(sn.think{h}) && sn.think_type(h) ~= ProcessType.DISABLED
280 switch sn.think_type(h)
281 case ProcessType.IMMEDIATE
282 P{h}.setThinkTime(jline.lang.processes.Immediate);
283 case ProcessType.EXP
284 P{h}.setThinkTime(jline.lang.processes.Exp(1/sn.think_mean(h)));
285 case ProcessType.ERLANG
286 P{h}.setThinkTime(jline.lang.processes.Erlang.fitMeanAndSCV(sn.think_mean(h),sn.think_scv(h)));
287 case ProcessType.HYPEREXP
288 % For HyperExp, reconstruct from params if available, otherwise use fitMeanAndSCV
289 if ~isempty(sn.think_params{h}) && length(sn.think_params{h}) >= 3
290 P{h}.setThinkTime(jline.lang.processes.HyperExp(sn.think_params{h}(1), sn.think_params{h}(2), sn.think_params{h}(3)));
291 else
292 P{h}.setThinkTime(jline.lang.processes.HyperExp.fitMeanAndSCV(sn.think_mean(h), sn.think_scv(h)));
293 end
294 case ProcessType.COXIAN
295 % For Coxian, use fitMeanAndSCV
296 P{h}.setThinkTime(jline.lang.processes.Coxian.fitMeanAndSCV(sn.think_mean(h), sn.think_scv(h)));
297 case ProcessType.APH
298 % For APH, reconstruct from params if available
299 if ~isempty(sn.think_params{h})
300 P{h}.setThinkTime(jline.lang.processes.APH.fitMeanAndSCV(sn.think_mean(h), sn.think_scv(h)));
301 else
302 P{h}.setThinkTime(jline.lang.processes.Exp(1/sn.think_mean(h)));
303 end
304 otherwise
305 line_error(mfilename,sprintf('JLINE conversion does not support the %s distribution yet.',char(sn.think_type(h))));
306 end
307 end
308 end
309
310 %% Sequential precedences
311 for ai = 1:sn.nacts
312 aidx = sn.ashift + ai;
313 tidx = sn.parent(aidx);
314 % for all successors
315 for bidx=find(sn.graph(aidx,:))
316 if bidx > sn.ashift % ignore precedence between entries and activities
317 % Serial pattern (SEQ)
318 if full(sn.actpretype(aidx)) == ActivityPrecedenceType.PRE_SEQ && full(sn.actposttype(bidx)) == ActivityPrecedenceType.POST_SEQ
319 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.Serial(sn.names{aidx}, sn.names{bidx}));
320 end
321 end
322 end
323 end
324
325 %%%%%%%%%%%%%%%%%%%%%%%%%%% translated up to here
326
327 %% Loop precedences (POST_LOOP)
328 % Loop structure in sn.graph:
329 % - Entry activity (preAct) has edge to first loop body activity
330 % - Last loop body activity has back-edge to first loop body (weight = 1-1/counts)
331 % - Last loop body activity has edge to end activity (weight = 1/counts)
332 % - All loop body and end activities have POST_LOOP type
333 processedLoops = false(1, sn.nacts);
334 for ai = 1:sn.nacts
335 aidx = sn.ashift + ai;
336 tidx = sn.parent(aidx);
337 % Check if this activity starts a loop (has a successor with POST_LOOP type)
338 % and hasn't been processed as part of another loop
339 if processedLoops(ai)
340 continue;
341 end
342
343 successors = find(sn.graph(aidx,:));
344 for bidx = successors
345 if bidx > sn.ashift && full(sn.actposttype(bidx)) == ActivityPrecedenceType.POST_LOOP
346 % Skip if this loop body activity was already processed
347 if processedLoops(bidx - sn.ashift)
348 continue;
349 end
350 % Found start of a loop: aidx is the entry, bidx is first loop body activity
351 loopStart = bidx;
352 precActs = java.util.ArrayList();
353
354 % Follow the chain of POST_LOOP activities
355 curIdx = loopStart;
356 while true
357 precActs.add(sprintf("%s", sn.names{curIdx}));
358 processedLoops(curIdx - sn.ashift) = true;
359
360 % Find successors of current activity
361 curSuccessors = find(sn.graph(curIdx,:));
362 curSuccessors = curSuccessors(curSuccessors > sn.ashift);
363
364 % Check for loop termination: find the end activity
365 % End activity has weight = 1/counts (not the back-edge weight)
366 endIdx = 0;
367 nextIdx = 0;
368 for succIdx = curSuccessors
369 if full(sn.actposttype(succIdx)) == ActivityPrecedenceType.POST_LOOP
370 if succIdx == loopStart
371 % This is the back-edge, skip it
372 continue;
373 end
374 weight = full(sn.graph(curIdx, succIdx));
375 if weight > 0 && weight < 1
376 % This is the end activity (weight = 1/counts)
377 endIdx = succIdx;
378 else
379 % This is the next activity in the loop body (weight = 1.0)
380 nextIdx = succIdx;
381 end
382 end
383 end
384
385 if endIdx > 0
386 % Found end activity - calculate counts and output
387 weight = full(sn.graph(curIdx, endIdx));
388 if weight > 0
389 counts = 1/weight;
390 else
391 counts = 1; % Fallback to prevent division by zero
392 end
393 precActs.add(sprintf("%s", sn.names{endIdx}));
394 processedLoops(endIdx - sn.ashift) = true;
395
396 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.Loop(sn.names{aidx}, precActs, jline.util.matrix.Matrix(counts)));
397 break;
398 elseif nextIdx > 0
399 % Continue to next activity in loop body
400 curIdx = nextIdx;
401 else
402 % No more successors - shouldn't happen in valid loop
403 break;
404 end
405 end
406 break; % Only process one loop starting from this activity
407 end
408 end
409 end
410
411 %% OrFork precedences (POST_OR)
412 precMarker = 0;
413 for ai = 1:sn.nacts
414 probs = [];
415 aidx = sn.ashift + ai;
416 tidx = sn.parent(aidx);
417 prob_ctr = 0;
418 % for all successors
419 for bidx=find(sn.graph(aidx,:))
420 if bidx > sn.ashift % ignore precedence between entries and activities
421 % Or pattern (POST_OR)
422 if full(sn.actposttype(bidx)) == ActivityPrecedenceType.POST_OR
423 if precMarker == 0 % start a new orjoin
424 precActs = java.util.ArrayList();
425 precMarker = aidx-sn.ashift;
426 precActs.add(sprintf("%s", sn.names{bidx}));
427 probs=full(sn.graph(aidx,bidx));
428 else
429 precActs.add(sprintf("%s", sn.names{bidx}));
430 probs(end+1)=full(sn.graph(aidx,bidx));
431 end
432 end
433 end
434 end
435
436
437 if precMarker > 0
438 probsMatrix = jline.util.matrix.Matrix(1,length(probs));
439 for i=1:length(probs)
440 probsMatrix.set(0,i-1,probs(i));
441 end
442 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.OrFork(sn.names{precMarker+sn.ashift}, precActs, probsMatrix));
443 precMarker = 0;
444 end
445 end
446
447 %% AndFork precedences (POST_AND)
448 precMarker = 0;
449 postActs = '';
450 for ai = 1:sn.nacts
451 aidx = sn.ashift + ai;
452 tidx = sn.parent(aidx);
453 % for all successors
454 for bidx=find(sn.graph(aidx,:))
455 if bidx > sn.ashift % ignore precedence between entries and activities
456 % Or pattern (POST_AND)
457 if full(sn.actposttype(bidx)) == ActivityPrecedenceType.POST_AND
458 if isempty(postActs)
459 postActs = java.util.ArrayList();
460 postActs.add(sprintf("%s", sn.names{bidx}));
461 else
462 postActs.add(sprintf("%s", sn.names{bidx}));
463 end
464
465 if precMarker == 0 % start a new orjoin
466 precMarker = aidx-sn.ashift;
467 end
468 end
469 end
470 end
471 if precMarker > 0
472 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.AndFork(sn.names{precMarker+sn.ashift}, postActs));
473 precMarker = 0;
474 end
475 end
476
477 %% CacheAccess precedences (POST_CACHE)
478 precMarker = 0;
479 postActs = '';
480 for ai = 1:sn.nacts
481 aidx = sn.ashift + ai;
482 tidx = sn.parent(aidx);
483 % for all successors
484 for bidx=find(sn.graph(aidx,:))
485 if bidx > sn.ashift % ignore precedence between entries and activities
486 % CacheAccess pattern (POST_CACHE)
487 if full(sn.actposttype(bidx)) == ActivityPrecedenceType.POST_CACHE
488 if isempty(postActs)
489 postActs = java.util.ArrayList();
490 postActs.add(sprintf("%s", sn.names{bidx}));
491 else
492 postActs.add(sprintf("%s", sn.names{bidx}));
493 end
494
495 if precMarker == 0 % start a new cache access
496 precMarker = aidx-sn.ashift;
497 end
498 end
499 end
500 end
501 if precMarker > 0
502 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.CacheAccess(sn.names{precMarker+sn.ashift}, postActs));
503 precMarker = 0;
504 postActs = '';
505 end
506 end
507
508 %% OrJoin precedences (PRE_OR)
509 precMarker = 0;
510 for bi = sn.nacts:-1:1
511 bidx = sn.ashift + bi;
512 tidx = sn.parent(bidx);
513 % for all predecessors
514 for aidx=find(sn.graph(:,bidx))'
515 if aidx > sn.ashift % ignore precedence between entries and activities
516 % OrJoin pattern (PRE_OR)
517 if full(sn.actpretype(aidx)) == ActivityPrecedenceType.PRE_OR
518 if precMarker == 0 % start a new orjoin
519 precActs = java.util.ArrayList();
520 precMarker = bidx-sn.ashift;
521 precActs.add(sprintf("%s", sn.names{aidx}));
522 else
523 precActs.add(sprintf("%s", sn.names{aidx}));
524 end
525 end
526 end
527 end
528 if precMarker > 0
529 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.OrJoin(precActs, sn.names{precMarker+sn.ashift}));
530 precMarker = 0;
531 end
532 end
533
534 %% AndJoin precedences (PRE_AND)
535 precMarker = 0;
536 for bi = sn.nacts:-1:1
537 bidx = sn.ashift + bi;
538 tidx = sn.parent(bidx);
539 % for all predecessors
540 for aidx=find(sn.graph(:,bidx))'
541 if aidx > sn.ashift % ignore precedence between entries and activities
542 % OrJoin pattern (PRE_AND)
543 if full(sn.actpretype(aidx)) == ActivityPrecedenceType.PRE_AND
544 if precMarker == 0 % start a new orjoin
545 precActs = java.util.ArrayList();
546 precMarker = bidx-sn.ashift;
547 precActs.add(sprintf("%s", sn.names{aidx}));
548 else
549 precActs.add(sprintf("%s", sn.names{aidx}));
550 end
551 end
552 end
553 end
554 if precMarker > 0
555 % Find quorum parameter from original precedence structure
556 postActName = sn.names{precMarker+sn.ashift};
557 localTaskIdx = tidx - sn.tshift;
558 quorum = [];
559 for ap = 1:length(line_layered_network.tasks{localTaskIdx}.precedences)
560 precedence = line_layered_network.tasks{localTaskIdx}.precedences(ap);
561 if precedence.preType == ActivityPrecedenceType.PRE_AND
562 % Check if this precedence contains our post activity
563 if any(strcmp(precedence.postActs, postActName))
564 quorum = precedence.preParams;
565 break;
566 end
567 end
568 end
569
570 if isempty(quorum)
571 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.AndJoin(precActs, sn.names{precMarker+sn.ashift}));
572 else
573 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.AndJoin(precActs, sn.names{precMarker+sn.ashift}, quorum));
574 end
575 precMarker = 0;
576 end
577 end
578
579 end
580
581 function jdist = from_line_distribution(line_dist)
582 if isa(line_dist, 'Exp')
583 jdist = javaObject('jline.lang.processes.Exp', line_dist.getParam(1).paramValue);
584 elseif isa(line_dist, "APH")
585 alpha = line_dist.getParam(1).paramValue;
586 T = line_dist.getParam(2).paramValue;
587 jline_alpha = java.util.ArrayList();
588 for i = 1:length(alpha)
589 jline_alpha.add(alpha(i));
590 end
591 jline_T = JLINE.from_line_matrix(T);
592 jdist = javaObject('jline.lang.processes.APH', jline_alpha, jline_T);
593 elseif isa(line_dist, 'Coxian')
594 jline_mu = java.util.ArrayList();
595 jline_phi = java.util.ArrayList();
596 if length(line_dist.params) == 3
597 jline_mu.add(line_dist.getParam(1).paramValue);
598 jline_mu.add(line_dist.getParam(2).paramValue);
599 jline_phi.add(line_dist.getParam(3).paramValue);
600 else
601 mu = line_dist.getParam(1).paramValue;
602 phi = line_dist.getParam(2).paramValue;
603 for i = 1:length(mu)
604 jline_mu.add(mu(i));
605 end
606 for i = 1:length(phi)
607 jline_phi.add(phi(i));
608 end
609 end
610 jdist = javaObject('jline.lang.processes.Coxian', jline_mu, jline_phi);
611 elseif isa(line_dist, 'Det')
612 jdist = javaObject('jline.lang.processes.Det', line_dist.getParam(1).paramValue);
613 elseif isa(line_dist, 'DiscreteSampler')
614 popularity_p = JLINE.from_line_matrix(line_dist.getParam(1).paramValue);
615 popularity_val = JLINE.from_line_matrix(line_dist.getParam(2).paramValue);
616 jdist = javaObject('jline.lang.processes.DiscreteSampler', popularity_p, popularity_val);
617 elseif isa(line_dist, 'Erlang')
618 jdist = javaObject('jline.lang.processes.Erlang', line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue);
619 elseif isa(line_dist, 'Gamma')
620 jdist = javaObject('jline.lang.processes.Gamma', line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue);
621 elseif isa(line_dist, "HyperExp")
622 jdist = javaObject('jline.lang.processes.HyperExp', line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue, line_dist.getParam(3).paramValue);
623 elseif isa(line_dist, 'Lognormal')
624 jdist = javaObject('jline.lang.processes.Lognormal', line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue);
625 elseif isa(line_dist, 'Pareto')
626 jdist = javaObject('jline.lang.processes.Pareto', line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue);
627 elseif isa(line_dist, 'MAP')
628 D0 = line_dist.D(0);
629 D1 = line_dist.D(1);
630 jdist = javaObject('jline.lang.processes.MAP', JLINE.from_line_matrix(D0), JLINE.from_line_matrix(D1));
631 elseif isa(line_dist, 'MMPP2')
632 lambda0 = line_dist.getParam(1).paramValue;
633 lambda1 = line_dist.getParam(2).paramValue;
634 sigma0 = line_dist.getParam(3).paramValue;
635 sigma1 = line_dist.getParam(4).paramValue;
636 jdist = javaObject('jline.lang.processes.MMPP2', lambda0, lambda1, sigma0, sigma1);
637 elseif isa(line_dist, 'PH')
638 alpha = line_dist.getParam(1).paramValue;
639 T = line_dist.getParam(2).paramValue;
640 jdist = javaObject('jline.lang.processes.PH', JLINE.from_line_matrix(alpha), JLINE.from_line_matrix(T));
641 elseif isa(line_dist, 'Uniform')
642 jdist = javaObject('jline.lang.processes.Uniform', line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue);
643 elseif isa(line_dist, 'Weibull')
644 jdist = javaObject('jline.lang.processes.Weibull', line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue);
645 elseif isa(line_dist, 'Zipf')
646 jdist = javaObject('jline.lang.processes.Zipf', line_dist.getParam(3).paramValue, line_dist.getParam(4).paramValue);
647 elseif isa(line_dist, 'Immediate')
648 jdist = javaObject('jline.lang.processes.Immediate');
649 elseif isempty(line_dist) || isa(line_dist, 'Disabled')
650 jdist = javaObject('jline.lang.processes.Disabled');
651 return;
652 elseif isa(line_dist, 'Replayer')
653 jdist = javaObject('jline.lang.processes.Replayer', line_dist.params{1}.paramValue);
654 elseif isa(line_dist, 'Trace')
655 jdist = javaObject('jline.lang.processes.Trace', line_dist.params{1}.paramValue);
656 elseif isa(line_dist, 'Prior')
657 % Convert Prior: each alternative is a distribution
658 dists = line_dist.getParam(1).paramValue;
659 probs = line_dist.getParam(2).paramValue;
660 jdists = java.util.ArrayList();
661 for k = 1:length(dists)
662 jdists.add(JLINE.from_line_distribution(dists{k}));
663 end
664 jdist = javaObject('jline.lang.processes.Prior', jdists, probs);
665 else
666 line_error(mfilename,'Distribution not supported by JLINE.');
667 end
668 end
669
670 function matlab_dist = from_jline_distribution(jdist)
671 if isa(jdist, 'jline.lang.processes.Exp')
672 matlab_dist = Exp(jdist.getRate());
673 elseif isa(jdist, 'jline.lang.processes.Det')
674 matlab_dist = Det(jdist.getParam(1).getValue);
675 elseif isa(jdist, 'jline.lang.processes.Erlang')
676 matlab_dist = Erlang(jdist.getParam(1).getValue(),jdist.getNumberOfPhases());
677 elseif isa(jdist, 'jline.lang.processes.Gamma')
678 matlab_dist = Gamma(jdist.getParam(1).getValue,jdist.getParam(2).getValue);
679 elseif isa(jdist, 'jline.lang.processes.HyperExp')
680 matlab_dist = HyperExp(jdist.getParam(1).getValue, jdist.getParam(2).getValue, jdist.getParam(3).getValue);
681 elseif isa(jdist, 'jline.lang.processes.Lognormal')
682 matlab_dist = Lognormal(jdist.getParam(1).getValue,jdist.getParam(2).getValue);
683 elseif isa(jdist, 'jline.lang.processes.Pareto')
684 matlab_dist = Pareto(jdist.getParam(1).getValue,jdist.getParam(2).getValue);
685 elseif isa(jdist, 'jline.lang.processes.Uniform')
686 matlab_dist = Uniform(jdist.getParam(1).getValue,jdist.getParam(2).getValue);
687 elseif isa(jdist, 'jline.lang.processes.Weibull')
688 matlab_dist = Weibull(jdist.getParam(1).getValue,jdist.getParam(2).getValue);
689 elseif isa(jdist, 'jline.lang.processes.MAP')
690 D0 = JLINE.from_jline_matrix(jdist.D(0));
691 D1 = JLINE.from_jline_matrix(jdist.D(1));
692 matlab_dist = MAP({D0, D1});
693 elseif isa(jdist, 'jline.lang.processes.APH')
694 alpha = JLINE.from_jline_matrix(jdist.getInitProb());
695 T = JLINE.from_jline_matrix(jdist.getSubgenerator());
696 matlab_dist = APH(alpha(:)', T);
697 elseif isa(jdist, 'jline.lang.processes.PH')
698 alpha = JLINE.from_jline_matrix(jdist.getInitProb());
699 T = JLINE.from_jline_matrix(jdist.getSubgenerator());
700 matlab_dist = PH(alpha(:)', T);
701 elseif isa(jdist, 'jline.lang.processes.Coxian')
702 if jdist.getNumberOfPhases == 2
703 matlab_dist = Coxian([jdist.getParam(1).getValue.get(0), jdist.getParam(1).getValue.get(1)], [jdist.getParam(2).getValue.get(0),1]);
704 else
705 jmu = jdist.getParam(1).getValue;
706 jphi = jdist.getParam(2).getValue;
707 mu = zeros(1, jmu.size);
708 phi = zeros(1, jphi.size);
709 for i = 1:jmu.size
710 mu(i) = jmu.get(i-1);
711 end
712 for i = 1:jphi.size
713 phi(i) = jphi.get(i-1);
714 end
715 matlab_dist = Coxian(mu, phi);
716 end
717 elseif isa(jdist, 'jline.lang.processes.Zipf')
718 matlab_dist = Zipf(jdist.getParam(3).getValue, jdist.getParam(4).getValue);
719 elseif isa(jdist, 'jline.lang.processes.DiscreteSampler')
720 jpMat = jdist.getParam(1).getValue;
721 jxMat = jdist.getParam(2).getValue;
722 p = zeros(1, jpMat.length);
723 x = zeros(1, jxMat.length);
724 for i = 1:jpMat.length
725 p(i) = jpMat.get(i-1);
726 end
727 for i = 1:jxMat.length
728 x(i) = jxMat.get(i-1);
729 end
730 matlab_dist = DiscreteSampler(p, x);
731 elseif isa(jdist, 'jline.lang.processes.Immediate')
732 matlab_dist = Immediate();
733 elseif isa(jdist, 'jline.lang.processes.Disabled')
734 matlab_dist = Disabled();
735 elseif isa(jdist, 'jline.lang.processes.MMPP2')
736 matlab_dist = MMPP2(jdist.getParam(1).getValue, jdist.getParam(2).getValue, jdist.getParam(3).getValue, jdist.getParam(4).getValue);
737 elseif isa(jdist, 'jline.lang.processes.Prior')
738 % Convert Prior from JAR to MATLAB
739 jdists = jdist.getDistributions();
740 nalt = jdists.size();
741 dists = cell(1, nalt);
742 for k = 1:nalt
743 dists{k} = JLINE.from_jline_distribution(jdists.get(k-1));
744 end
745 probs = jdist.getProbabilities();
746 matlab_dist = Prior(dists, probs);
747 else
748 line_error(mfilename,'Distribution not supported by JLINE.');
749 end
750 end
751
752 function set_csMatrix(line_node, jnode, jclasses)
753 nClasses = length(line_node.model.classes);
754 csMatrix = jnode.initClassSwitchMatrix();
755 for i = 1:nClasses
756 for j = 1:nClasses
757 csMatrix.set(jclasses{i}, jclasses{j}, line_node.server.csFun(i,j,0,0));
758 end
759 end
760 jnode.setClassSwitchingMatrix(csMatrix);
761 end
762
763 function set_service(line_node, jnode, job_classes)
764 if (isa(line_node, 'Sink') || isa(line_node, 'Router') || isa(line_node, 'Cache') || isa(line_node, 'Logger') || isa(line_node, 'ClassSwitch') || isa(line_node, 'Fork') || isa(line_node, 'Join') || isa(line_node, 'Place') || isa(line_node, 'Transition'))
765 return;
766 end
767
768 for n = 1 : length(job_classes)
769 if (isa(line_node, 'Queue') || isa(line_node, 'Delay'))
770 matlab_dist = line_node.getService(job_classes{n});
771 elseif (isa(line_node, 'Source'))
772 matlab_dist = line_node.getArrivalProcess(job_classes{n});
773 else
774 line_error(mfilename,'Node not supported by JLINE.');
775 end
776 service_dist = JLINE.from_line_distribution(matlab_dist);
777
778 if (isa(line_node,'Queue') || isa(line_node, 'Delay'))
779 jnode.setService(jnode.getModel().getClasses().get(n-1), service_dist, line_node.schedStrategyPar(n));
780 elseif (isa(line_node, 'Source'))
781 jnode.setArrival(jnode.getModel().getClasses().get(n-1), service_dist);
782 end
783 end
784 end
785
786 function set_delayoff(line_node, jnode, job_classes)
787 % Transfer setup and delayoff times from MATLAB Queue to Java Queue
788 if ~isa(line_node, 'Queue')
789 return;
790 end
791
792 % Check if setupTime property exists and is not empty
793 if ~isprop(line_node, 'setupTime') || isempty(line_node.setupTime)
794 return;
795 end
796
797 for n = 1 : length(job_classes)
798 c = job_classes{n}.index;
799 % Check if both setupTime and delayoffTime are set for this class
800 if c <= length(line_node.setupTime) && ~isempty(line_node.setupTime{1, c}) && ...
801 c <= length(line_node.delayoffTime) && ~isempty(line_node.delayoffTime{1, c})
802 % Convert MATLAB distributions to Java distributions
803 setup_dist = JLINE.from_line_distribution(line_node.setupTime{1, c});
804 delayoff_dist = JLINE.from_line_distribution(line_node.delayoffTime{1, c});
805 % Set delayoff on the Java Queue
806 jnode.setDelayOff(jnode.getModel().getClasses().get(n-1), setup_dist, delayoff_dist);
807 end
808 end
809 end
810
811 function set_line_service(jline_node, line_node, job_classes, line_classes)
812 if (isa(line_node,'Sink')) || isa(line_node, 'ClassSwitch') || isa(line_node, 'Fork') || isa(line_node, 'Join') || isa(line_node, 'Place') || isa(line_node, 'Transition') || isa(line_node, 'Cache')
813 return;
814 end
815 for n = 1:job_classes.size()
816 if (isa(line_node, 'Queue') || isa(line_node, 'Delay'))
817 jdist = jline_node.getServiceProcess(job_classes.get(n-1));
818 matlab_dist = JLINE.from_jline_distribution(jdist);
819 weight = jline_node.getSchedStrategyPar(job_classes.get(n-1));
820 line_node.setService(line_classes{n}, matlab_dist, weight);
821 elseif (isa(line_node, 'Source'))
822 jdist = jline_node.getArrivalProcess(job_classes.get(n-1));
823 matlab_dist = JLINE.from_jline_distribution(jdist);
824 line_node.setArrival(line_classes{n}, matlab_dist);
825 elseif (isa(line_node, 'Router'))
826 % no-op
827 else
828 line_error(mfilename,'Node not supported by JLINE.');
829 end
830 end
831 end
832
833 function node_object = from_line_node(line_node, jnetwork, ~, forkNode, sn)
834 % Handle optional sn argument
835 if nargin < 5
836 sn = [];
837 end
838 if isa(line_node, 'Delay')
839 node_object = javaObject('jline.lang.nodes.Delay', jnetwork, line_node.getName);
840 elseif isa(line_node, 'Queue')
841 switch line_node.schedStrategy
842 case SchedStrategy.INF
843 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.INF);
844 case SchedStrategy.FCFS
845 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FCFS);
846 case SchedStrategy.LCFS
847 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LCFS);
848 case SchedStrategy.SIRO
849 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.SIRO);
850 case SchedStrategy.SJF
851 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.SJF);
852 case SchedStrategy.LJF
853 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LJF);
854 case SchedStrategy.PS
855 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.PS);
856 case SchedStrategy.DPS
857 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.DPS);
858 case SchedStrategy.GPS
859 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.GPS);
860 case SchedStrategy.SEPT
861 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.SEPT);
862 case SchedStrategy.LEPT
863 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LEPT);
864 case {SchedStrategy.HOL, SchedStrategy.FCFSPRIO}
865 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FCFSPRIO);
866 case SchedStrategy.FORK
867 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FORK);
868 case SchedStrategy.EXT
869 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.EXT);
870 case SchedStrategy.REF
871 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.REF);
872 case SchedStrategy.LCFSPR
873 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LCFSPR);
874 case SchedStrategy.LCFSPI
875 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LCFSPI);
876 case SchedStrategy.LCFSPRIO
877 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LCFSPRIO);
878 case SchedStrategy.LCFSPRPRIO
879 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LCFSPRPRIO);
880 case SchedStrategy.LCFSPIPRIO
881 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LCFSPIPRIO);
882 case SchedStrategy.FCFSPR
883 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FCFSPR);
884 case SchedStrategy.FCFSPI
885 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FCFSPI);
886 case SchedStrategy.FCFSPRPRIO
887 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FCFSPRPRIO);
888 case SchedStrategy.FCFSPIPRIO
889 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FCFSPIPRIO);
890 case SchedStrategy.PSPRIO
891 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.PSPRIO);
892 case SchedStrategy.DPSPRIO
893 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.DPSPRIO);
894 case SchedStrategy.GPSPRIO
895 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.GPSPRIO);
896 case SchedStrategy.POLLING
897 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.POLLING);
898 case SchedStrategy.SRPT
899 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.SRPT);
900 case SchedStrategy.SRPTPRIO
901 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.SRPTPRIO);
902 case SchedStrategy.PSJF
903 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.PSJF);
904 case SchedStrategy.FB
905 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FB);
906 case SchedStrategy.LRPT
907 node_object = javaObject('jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LRPT);
908 end
909 nservers = line_node.getNumberOfServers;
910 if isinf(nservers)
911 node_object.setNumberOfServers(java.lang.Integer.MAX_VALUE);
912 elseif nservers > 1
913 node_object.setNumberOfServers(line_node.getNumberOfServers);
914 end
915 if ~isempty(line_node.lldScaling)
916 node_object.setLoadDependence(JLINE.from_line_matrix(line_node.lldScaling));
917 end
918 if ~isempty(line_node.lcdScaling)
919 if isempty(sn)
920 line_error(mfilename, "Class-dependent models require sn struct for MATLAB-to-JAVA translation.");
921 end
922 node_object.setLimitedClassDependence(JLINE.handle_to_serializablefun(line_node.lcdScaling, sn));
923 end
924 % Transfer LJD (Limited Joint Dependence) scaling
925 if ~isempty(line_node.ljdScaling) && ~isempty(line_node.ljdCutoffs)
926 jScaling = JLINE.from_line_matrix(line_node.ljdScaling(:));
927 jCutoffs = JLINE.from_line_matrix(line_node.ljdCutoffs(:));
928 node_object.setLimitedJointDependence(jScaling, jCutoffs);
929 end
930 % NOTE: LJCD (Limited Joint Class Dependence) is transferred in
931 % from_line_network after classes are created
932 % Set queue capacity if finite
933 if ~isinf(line_node.cap)
934 node_object.setCapacity(line_node.cap);
935 end
936 elseif isa(line_node, 'Source')
937 node_object = javaObject('jline.lang.nodes.Source', jnetwork, line_node.getName);
938 elseif isa(line_node, 'Sink')
939 node_object = javaObject('jline.lang.nodes.Sink', jnetwork, line_node.getName);
940 elseif isa(line_node, 'Router')
941 node_object = javaObject('jline.lang.nodes.Router', jnetwork, line_node.getName);
942 elseif isa(line_node, 'ClassSwitch')
943 node_object = javaObject('jline.lang.nodes.ClassSwitch', jnetwork, line_node.getName);
944 elseif isa(line_node, 'Fork')
945 node_object = javaObject('jline.lang.nodes.Fork', jnetwork, line_node.name);
946 node_object.setTasksPerLink(line_node.output.tasksPerLink);
947 elseif isa(line_node, 'Join')
948 node_object = javaObject('jline.lang.nodes.Join', jnetwork, line_node.name, forkNode);
949 elseif isa(line_node, 'Logger')
950 node_object = javaObject('jline.lang.nodes.Logger', jnetwork, line_node.name, [line_node.filePath,line_node.fileName]);
951 elseif isa(line_node, 'Cache')
952 nitems = line_node.items.nitems;
953 switch line_node.replacestrategy
954 case ReplacementStrategy.RR
955 repStrategy = jline.lang.constant.ReplacementStrategy.RR;
956 case ReplacementStrategy.FIFO
957 repStrategy = jline.lang.constant.ReplacementStrategy.FIFO;
958 case ReplacementStrategy.SFIFO
959 repStrategy = jline.lang.constant.ReplacementStrategy.SFIFO;
960 case ReplacementStrategy.LRU
961 repStrategy = jline.lang.constant.ReplacementStrategy.LRU;
962 end
963 if ~isempty(line_node.graph)
964 node_object = javaObject('jline.lang.nodes.Cache', jnetwork, line_node.name, nitems, JLINE.from_line_matrix(line_node.itemLevelCap), repStrategy, JLINE.from_line_matrix(line_node.graph));
965 else
966 node_object = javaObject('jline.lang.nodes.Cache', jnetwork, line_node.name, nitems, JLINE.from_line_matrix(line_node.itemLevelCap), repStrategy);
967 end
968 elseif isa(line_node, 'Place')
969 node_object = javaObject('jline.lang.nodes.Place', jnetwork, line_node.getName);
970 elseif isa(line_node, 'Transition')
971 node_object = javaObject('jline.lang.nodes.Transition', jnetwork, line_node.getName);
972 % Modes are added later in from_line_network after classes are created
973 else
974 line_error(mfilename,'Node not supported by JLINE.');
975 end
976 end
977
978 function node_object = from_jline_node(jline_node, model, job_classes)
979 if isa(jline_node, 'jline.lang.nodes.Delay')
980 node_object = Delay(model, jline_node.getName.toCharArray');
981 elseif isa(jline_node, 'jline.lang.nodes.Queue')
982 schedStrategy = jline_node.getSchedStrategy;
983 switch schedStrategy.name().toCharArray'
984 case 'INF'
985 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.INF);
986 case 'FCFS'
987 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FCFS);
988 case 'LCFS'
989 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LCFS);
990 case 'SIRO'
991 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.SIRO);
992 case 'SJF'
993 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.SJF);
994 case 'LJF'
995 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LJF);
996 case 'PS'
997 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.PS);
998 case 'DPS'
999 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.DPS);
1000 case 'GPS'
1001 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.GPS);
1002 case 'SEPT'
1003 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.SEPT);
1004 case 'LEPT'
1005 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LEPT);
1006 case {'HOL', 'FCFSPRIO'}
1007 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FCFSPRIO);
1008 case 'FORK'
1009 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FORK);
1010 case 'EXT'
1011 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.EXT);
1012 case 'REF'
1013 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.REF);
1014 case 'LCFSPR'
1015 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LCFSPR);
1016 case 'SRPT'
1017 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.SRPT);
1018 case 'SRPTPRIO'
1019 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.SRPTPRIO);
1020 case 'PSJF'
1021 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.PSJF);
1022 case 'FB'
1023 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FB);
1024 case 'LRPT'
1025 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LRPT);
1026 case 'PSPRIO'
1027 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.PSPRIO);
1028 case 'DPSPRIO'
1029 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.DPSPRIO);
1030 case 'GPSPRIO'
1031 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.GPSPRIO);
1032 case 'LCFSPI'
1033 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LCFSPI);
1034 case 'LCFSPRIO'
1035 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LCFSPRIO);
1036 case 'LCFSPRPRIO'
1037 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LCFSPRPRIO);
1038 case 'LCFSPIPRIO'
1039 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LCFSPIPRIO);
1040 case 'FCFSPR'
1041 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FCFSPR);
1042 case 'FCFSPI'
1043 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FCFSPI);
1044 case 'FCFSPRPRIO'
1045 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FCFSPRPRIO);
1046 case 'FCFSPIPRIO'
1047 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FCFSPIPRIO);
1048 case 'POLLING'
1049 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.POLLING);
1050 end
1051 node_object.setNumberOfServers(jline_node.getNumberOfServers);
1052 cap = jline_node.getCap();
1053 if cap < intmax && cap > 0
1054 node_object.setCapacity(cap);
1055 end
1056 if ~isempty(JLINE.from_jline_matrix(jline_node.getLimitedLoadDependence))
1057 node_object.setLoadDependence(JLINE.from_jline_matrix(jline_node.getLimitedLoadDependence));
1058 end
1059 elseif isa(jline_node, 'jline.lang.nodes.Source')
1060 node_object = Source(model, jline_node.getName.toCharArray');
1061 elseif isa(jline_node, 'jline.lang.nodes.Sink')
1062 node_object = Sink(model, jline_node.getName.toCharArray');
1063 elseif isa(jline_node, 'jline.lang.nodes.Router')
1064 node_object = Router(model, jline_node.getName.toCharArray');
1065 elseif isa(jline_node, 'jline.lang.nodes.ClassSwitch')
1066 nClasses = job_classes.size;
1067 csMatrix = zeros(nClasses, nClasses);
1068 for r = 1:nClasses
1069 for s = 1:nClasses
1070 csMatrix(r,s) = jline_node.getServer.applyCsFun(r-1,s-1);
1071 end
1072 end
1073 node_object = ClassSwitch(model, jline_node.getName.toCharArray', csMatrix);
1074 elseif isa(jline_node, 'jline.lang.nodes.Cache')
1075 numItems = jline_node.getNumberOfItems();
1076 itemLevelCap = JLINE.from_jline_matrix(jline_node.getItemLevelCap());
1077 replPolicy = jline_node.getReplacementStrategy();
1078 switch char(replPolicy)
1079 case 'LRU'
1080 rp = ReplacementStrategy.LRU;
1081 case 'FIFO'
1082 rp = ReplacementStrategy.FIFO;
1083 case 'RR'
1084 rp = ReplacementStrategy.RR;
1085 otherwise
1086 rp = ReplacementStrategy.LRU;
1087 end
1088 node_object = Cache(model, jline_node.getName.toCharArray', numItems, itemLevelCap, rp);
1089 % hitClass, missClass, and popularity set later in jline_to_line
1090 elseif isa(jline_node, 'jline.lang.nodes.Fork')
1091 node_object = Fork(model, jline_node.getName.toCharArray');
1092 tpl = jline_node.getOutput().tasksPerLink;
1093 if tpl > 1
1094 node_object.setTasksPerLink(tpl);
1095 end
1096 elseif isa(jline_node, 'jline.lang.nodes.Join')
1097 node_object = Join(model, jline_node.getName.toCharArray');
1098 % joinOf is set later in jline_to_line after all nodes are created
1099 elseif isa(jline_node, 'jline.lang.nodes.Place')
1100 node_object = Place(model, jline_node.getName.toCharArray');
1101 elseif isa(jline_node, 'jline.lang.nodes.Transition')
1102 node_object = Transition(model, jline_node.getName.toCharArray');
1103 % Note: Mode configurations need to be set after classes are created
1104 else
1105 line_error(mfilename,'Node not supported by JLINE.');
1106 end
1107 end
1108
1109 function node_class = from_line_class(line_class, jnetwork)
1110 % Check signal classes first (before their base classes)
1111 if isa(line_class, 'ClosedSignal')
1112 % ClosedSignal -> jline.lang.ClosedSignal
1113 jSignalType = jline.lang.constant.SignalType.fromID(line_class.signalType);
1114 node_class = javaObject('jline.lang.ClosedSignal', jnetwork, line_class.getName, jSignalType, jnetwork.getNodeByName(line_class.refstat.getName), line_class.priority);
1115 elseif isa(line_class, 'Signal') || isa(line_class, 'OpenSignal')
1116 % Signal/OpenSignal -> jline.lang.Signal (includes CATASTROPHE type)
1117 jSignalType = jline.lang.constant.SignalType.fromID(line_class.signalType);
1118 node_class = javaObject('jline.lang.Signal', jnetwork, line_class.getName, jSignalType, line_class.priority);
1119 elseif isa(line_class, 'OpenClass')
1120 node_class = javaObject('jline.lang.OpenClass', jnetwork, line_class.getName, line_class.priority);
1121 elseif isa(line_class, 'SelfLoopingClass')
1122 node_class = javaObject('jline.lang.SelfLoopingClass', jnetwork, line_class.getName, line_class.population, jnetwork.getNodeByName(line_class.refstat.getName), line_class.priority);
1123 elseif isa(line_class, 'ClosedClass')
1124 node_class = javaObject('jline.lang.ClosedClass', jnetwork, line_class.getName, line_class.population, jnetwork.getNodeByName(line_class.refstat.getName), line_class.priority);
1125 else
1126 line_error(mfilename,'Class type not supported by JLINE.');
1127 end
1128 if line_class.isReferenceClass()
1129 node_class.setReferenceClass(true);
1130 end
1131 end
1132
1133 function node_class = from_jline_class(jclass, model)
1134 if isa(jclass, 'jline.lang.OpenClass')
1135 node_class = OpenClass(model, jclass.getName.toCharArray', jclass.getPriority);
1136 elseif isa(jclass, 'jline.lang.SelfLoopingClass')
1137 node_class = SelfLoopingClass(model, jclass.getName.toCharArray', jclass.getNumberOfJobs, model.getNodeByName(jclass.getReferenceStation.getName), jclass.getPriority);
1138 elseif isa(jclass, 'jline.lang.ClosedClass')
1139 node_class = ClosedClass(model, jclass.getName.toCharArray', jclass.getNumberOfJobs, model.getNodeByName(jclass.getReferenceStation.getName), jclass.getPriority);
1140 else
1141 line_error(mfilename,'Class type not supported by JLINE.');
1142 end
1143 end
1144
1145 function from_line_links(model, jmodel)
1146 connections = model.getConnectionMatrix();
1147 [m, ~] = size(connections);
1148 jnodes = jmodel.getNodes();
1149 jclasses = jmodel.getClasses();
1150 njclasses = jclasses.size();
1151 line_nodes = model.getNodes;
1152 sn = model.getStruct;
1153
1154 % Build mapping from MATLAB node index to Java node index
1155 % (accounting for skipped auto-added ClassSwitch nodes)
1156 matlab2java_node_idx = zeros(1, length(line_nodes));
1157 jidx = 0;
1158 for i = 1:length(line_nodes)
1159 if isa(line_nodes{i}, 'ClassSwitch') && line_nodes{i}.autoAdded
1160 matlab2java_node_idx(i) = -1; % Mark as skipped
1161 else
1162 matlab2java_node_idx(i) = jidx;
1163 jidx = jidx + 1;
1164 end
1165 end
1166
1167 %nodevisits = cellsum(sn.nodevisits);
1168 % [ ] Update to consider different weights/routing for classes
1169 if isempty(sn.rtorig)
1170 useLinkMethod = false; % this model did not call link()
1171 else
1172 jrt_matrix = jmodel.initRoutingMatrix();
1173 useLinkMethod = true;
1174 end
1175
1176 % For models with auto-added ClassSwitch nodes, use sn.rtorig directly
1177 % to set up routing with proper class switching
1178 hasAutoCS = false;
1179 for i = 1:length(line_nodes)
1180 if isa(line_nodes{i}, 'ClassSwitch') && line_nodes{i}.autoAdded
1181 hasAutoCS = true;
1182 break;
1183 end
1184 end
1185
1186 if useLinkMethod && hasAutoCS
1187 % Use sn.rtorig directly - it contains the full routing with class switching
1188 % sn.rtorig already excludes auto-added ClassSwitch nodes (it's based on nstations)
1189 % So we iterate over the rtorig matrix dimensions directly
1190 for r = 1:njclasses
1191 for s = 1:njclasses
1192 if ~isempty(sn.rtorig{r,s})
1193 Prs = sn.rtorig{r,s};
1194 [nrows, ncols] = size(Prs);
1195 for i = 1:nrows
1196 for j = 1:ncols
1197 if Prs(i,j) > 0
1198 % sn.rtorig uses station indices which map to non-CS nodes
1199 % Find the java node indices by matching station index to node
1200 jsrc_idx = i - 1; % Direct mapping since rtorig excludes CS
1201 jdest_idx = j - 1;
1202 jrt_matrix.set(jclasses.get(r-1), jclasses.get(s-1), jnodes.get(jsrc_idx), jnodes.get(jdest_idx), Prs(i,j));
1203 end
1204 end
1205 end
1206 end
1207 end
1208 end
1209 else
1210 % Original logic for models without auto-added ClassSwitch
1211 for i = 1:m
1212 line_node = line_nodes{i};
1213
1214 % Skip auto-added ClassSwitch nodes - Java will add them automatically
1215 if isa(line_node, 'ClassSwitch') && line_node.autoAdded
1216 continue;
1217 end
1218
1219 jnode_idx = matlab2java_node_idx(i);
1220 for k = 1:njclasses
1221 output_strat = line_node.output.outputStrategy{k};
1222 switch RoutingStrategy.fromText(output_strat{2})
1223 case RoutingStrategy.DISABLED
1224 jnodes.get(jnode_idx).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.DISABLED);
1225 case RoutingStrategy.RAND
1226 jnodes.get(jnode_idx).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.RAND);
1227 outlinks_i=find(connections(i,:));
1228 if useLinkMethod
1229 % Do NOT add routing matrix entries for RAND routing.
1230 % JAR's getRoutingMatrix computes RAND routing from
1231 % the connection matrix (matching MATLAB behavior).
1232 % Adding entries would cause link() to convert RAND
1233 % to PROB, and for closed classes would incorrectly
1234 % include Sink connections.
1235 else
1236 for j= outlinks_i(:)'
1237 jdest_idx = matlab2java_node_idx(j);
1238 if jdest_idx >= 0
1239 jmodel.addLink(jnodes.get(jnode_idx), jnodes.get(jdest_idx));
1240 end
1241 end
1242 end
1243 case RoutingStrategy.RROBIN
1244 jnodes.get(jnode_idx).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.RROBIN);
1245 outlinks_i=find(connections(i,:))';
1246 if useLinkMethod
1247 line_error(mfilename,'RROBIN cannot be used together with the link() command.');
1248 end
1249 for j= outlinks_i(:)'
1250 jdest_idx = matlab2java_node_idx(j);
1251 if jdest_idx >= 0
1252 jmodel.addLink(jnodes.get(jnode_idx), jnodes.get(jdest_idx));
1253 end
1254 end
1255 case RoutingStrategy.WRROBIN
1256 outlinks_i=find(connections(i,:))';
1257 for j= outlinks_i(:)'
1258 jdest_idx = matlab2java_node_idx(j);
1259 if jdest_idx >= 0
1260 jmodel.addLink(jnodes.get(jnode_idx), jnodes.get(jdest_idx));
1261 end
1262 end
1263 if useLinkMethod
1264 line_error(mfilename,'RROBIN cannot be used together with the link() command.');
1265 end
1266 for j= 1:length(output_strat{3})
1267 node_target = jmodel.getNodeByName(output_strat{3}{j}{1}.getName());
1268 weight = output_strat{3}{j}{2};
1269 jnodes.get(jnode_idx).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.WRROBIN, node_target, weight);
1270 end
1271 case RoutingStrategy.PROB
1272 outlinks_i=find(connections(i,:));
1273 jnodes.get(jnode_idx).setRouting(jclasses.get(k-1), jline.lang.constant.RoutingStrategy.PROB);
1274 if ~useLinkMethod
1275 for j= outlinks_i(:)'
1276 jdest_idx = matlab2java_node_idx(j);
1277 if jdest_idx >= 0
1278 jmodel.addLink(jnodes.get(jnode_idx), jnodes.get(jdest_idx));
1279 end
1280 end
1281 end
1282 if length(output_strat) >= 3
1283 probabilities = output_strat{3};
1284 for j = 1:length(probabilities)
1285 dest_idx = probabilities{j}{1}.index;
1286 jdest_idx = matlab2java_node_idx(dest_idx);
1287 if (connections(i, dest_idx) ~= 0) && jdest_idx >= 0
1288 if useLinkMethod
1289 jrt_matrix.set(jclasses.get(k-1), jclasses.get(k-1), jnodes.get(jnode_idx), jnodes.get(jdest_idx), probabilities{j}{2});
1290 else
1291 jnodes.get(jnode_idx).setProbRouting(jclasses.get(k-1), jnodes.get(jdest_idx), probabilities{j}{2});
1292 end
1293 end
1294 end
1295 end
1296 case RoutingStrategy.JSQ
1297 jnodes.get(jnode_idx).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.JSQ);
1298 outlinks_i=find(connections(i,:))';
1299 if ~useLinkMethod
1300 for j= outlinks_i(:)'
1301 jdest_idx = matlab2java_node_idx(j);
1302 if jdest_idx >= 0
1303 jmodel.addLink(jnodes.get(jnode_idx), jnodes.get(jdest_idx));
1304 end
1305 end
1306 end
1307 otherwise
1308 line_warning(mfilename, sprintf('''%s'' routing strategy not supported by JLINE, setting as Disabled.\n',output_strat{2}));
1309 jnodes.get(jnode_idx).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.DISABLED);
1310 end
1311 end
1312 end
1313 end
1314 if useLinkMethod
1315 jmodel.link(jrt_matrix);
1316 % Align the sn.rtorig be the same, treating artificial
1317 % ClassSwitch nodes as if they were explicitly specified
1318 jsn = jmodel.getStruct(true);
1319 rtorig = java.util.HashMap();
1320 if ~isempty(model.sn.rtorig)
1321 if iscell(model.sn.rtorig)
1322 for r = 1:njclasses
1323 sub_rtorig = java.util.HashMap();
1324 for s = 1:njclasses
1325 sub_rtorig.put(jclasses.get(s-1), JLINE.from_line_matrix(model.sn.rtorig{r,s}));
1326 end
1327 rtorig.put(jclasses.get(r-1), sub_rtorig);
1328 end
1329 end
1330 end
1331 jsn.rtorig = rtorig;
1332 end
1333 end
1334
1335 function model = from_jline_routing(model, jnetwork)
1336 jnodes = jnetwork.getNodes();
1337 jclasses = jnetwork.getClasses();
1338 n_nodes = jnodes.size();
1339 network_nodes = model.getNodes;
1340 network_classes = model.getClasses;
1341
1342 % Build name-to-MATLAB-node map (JAR and MATLAB may order nodes differently)
1343 node_by_name = containers.Map();
1344 for nn = 1:length(network_nodes)
1345 node_by_name(network_nodes{nn}.name) = network_nodes{nn};
1346 end
1347
1348 connections = JLINE.from_jline_matrix(jnetwork.getConnectionMatrix());
1349 [row,col] = find(connections);
1350 for i=1:length(row)
1351 from_name = char(jnodes.get(row(i)-1).getName());
1352 to_name = char(jnodes.get(col(i)-1).getName());
1353 model.addLink(node_by_name(from_name), node_by_name(to_name));
1354 end
1355
1356 for n = 1 : n_nodes
1357 jnode = jnodes.get(n-1);
1358 cur_node = node_by_name(char(jnode.getName()));
1359 output_strategies = jnode.getOutputStrategies();
1360 n_strategies = output_strategies.size();
1361 for m = 1 : n_strategies
1362 output_strat = output_strategies.get(m-1);
1363 routing_strat = output_strat.getRoutingStrategy;
1364 routing_strat_classidx = output_strat.getJobClass.getIndex();
1365 switch char(routing_strat)
1366 case 'RAND'
1367 cur_node.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.RAND);
1368 case 'RROBIN'
1369 cur_node.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.RROBIN);
1370 case 'WRROBIN'
1371 dest = output_strat.getDestination();
1372 if ~isempty(dest)
1373 dest_name = char(dest.getName());
1374 if node_by_name.isKey(dest_name)
1375 weight = output_strat.getProbability();
1376 cur_node.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.WRROBIN, node_by_name(dest_name), weight);
1377 end
1378 end
1379 case 'DISABLED'
1380 cur_node.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.DISABLED);
1381 end
1382 end
1383 end
1384 end
1385
1386 function model = from_jline_links(model, jnetwork)
1387 P = model.initRoutingMatrix;
1388 jnodes = jnetwork.getNodes();
1389 jclasses = jnetwork.getClasses();
1390 n_classes = jclasses.size();
1391 n_nodes = jnodes.size();
1392 network_nodes = model.getNodes;
1393
1394 % Build JAR-to-MATLAB node index mapping (node orders may differ)
1395 jar2ml = zeros(1, n_nodes);
1396 for jj = 1:n_nodes
1397 jar_name = char(jnodes.get(jj-1).getName());
1398 for mm = 1:length(network_nodes)
1399 if strcmp(network_nodes{mm}.name, jar_name)
1400 jar2ml(jj) = mm;
1401 break;
1402 end
1403 end
1404 end
1405
1406 hasDestinations = false;
1407 for n = 1 : n_nodes
1408 jnode = jnodes.get(n-1);
1409 output_strategies = jnode.getOutputStrategies();
1410 n_strategies = output_strategies.size();
1411 for m = 1 : n_strategies
1412 output_strat = output_strategies.get(m-1);
1413 dest = output_strat.getDestination();
1414 if~isempty(dest) % disabled strategy
1415 hasDestinations = true;
1416 in_idx = jar2ml(jnetwork.getNodeIndex(jnode)+1);
1417 out_idx = jar2ml(jnetwork.getNodeIndex(dest)+1);
1418 if n_classes == 1
1419 P{1}(in_idx,out_idx) = output_strat.getProbability();
1420 else
1421 strat_class = output_strat.getJobClass();
1422 class_idx = jnetwork.getJobClassIndex(strat_class)+1;
1423 P{class_idx,class_idx}(in_idx,out_idx) = output_strat.getProbability();
1424 end
1425 end
1426 end
1427 end
1428
1429 % If no OutputStrategy entries had destinations (e.g., model
1430 % loaded from JSON via LineModelIO.load), fall back to rtorig
1431 if ~hasDestinations
1432 sn = jnetwork.getStruct;
1433 if ~isempty(sn.rtorig)
1434 % rtorig is station-indexed (no permutation needed —
1435 % station ordering matches between JAR and MATLAB)
1436 for r = 1:n_classes
1437 for s = 1:n_classes
1438 rtMat = JLINE.from_jline_matrix(sn.rtorig.get(jclasses.get(r-1)).get(jclasses.get(s-1)));
1439 if ~isempty(rtMat)
1440 P{r,s} = rtMat;
1441 end
1442 end
1443 end
1444 end
1445 end
1446
1447 model.link(P);
1448
1449 % Restore non-PROB routing strategies (RROBIN, WRROBIN, etc.)
1450 % after link(), which sets all routing to PROB
1451 network_nodes = model.getNodes;
1452 network_classes = model.getClasses;
1453 node_by_name = containers.Map();
1454 for nn = 1:length(network_nodes)
1455 node_by_name(network_nodes{nn}.name) = network_nodes{nn};
1456 end
1457 for n = 1 : n_nodes
1458 jnode = jnodes.get(n-1);
1459 cur_node = node_by_name(char(jnode.getName()));
1460 output_strategies = jnode.getOutputStrategies();
1461 n_strategies = output_strategies.size();
1462 for m = 1 : n_strategies
1463 output_strat = output_strategies.get(m-1);
1464 routing_strat = output_strat.getRoutingStrategy;
1465 routing_strat_classidx = output_strat.getJobClass.getIndex();
1466 switch char(routing_strat)
1467 case 'RROBIN'
1468 cur_node.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.RROBIN);
1469 case 'WRROBIN'
1470 dest = output_strat.getDestination();
1471 if ~isempty(dest)
1472 dest_name = char(dest.getName());
1473 if node_by_name.isKey(dest_name)
1474 % Clear stale PROB entries before first WRROBIN weight
1475 classIdx = routing_strat_classidx;
1476 if length(cur_node.output.outputStrategy) >= classIdx && ...
1477 length(cur_node.output.outputStrategy{1, classIdx}) >= 3
1478 curStrat = cur_node.output.outputStrategy{1, classIdx}{2};
1479 if ~strcmp(curStrat, 'WeightedRoundRobin')
1480 cur_node.output.outputStrategy{1, classIdx}{3} = {};
1481 end
1482 end
1483 weight = output_strat.getProbability();
1484 cur_node.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.WRROBIN, node_by_name(dest_name), weight);
1485 end
1486 end
1487 end
1488 end
1489 end
1490
1491 % Invalidate cached struct after modifying routing strategies
1492 model.resetStruct();
1493
1494 %Align the sn.rtorig be the same (Assume Java network is
1495 %created by calling Network.link)
1496 sn = jnetwork.getStruct;
1497 rtorig = cell(n_classes, n_classes);
1498 for r = 1:n_classes
1499 for s = 1:n_classes
1500 rtorig{r,s} = JLINE.from_jline_matrix(sn.rtorig.get(jclasses.get(r-1)).get(jclasses.get(s-1)));
1501 end
1502 end
1503 model.sn.rtorig = rtorig;
1504 end
1505
1506 function [jnetwork] = from_line_network(model)
1507 %w = warning;
1508 %warning('off');
1509 sn = model.getStruct;
1510
1511 jnetwork = javaObject('jline.lang.Network', model.getName);
1512 line_nodes = model.getNodes;
1513 line_classes = model.getClasses;
1514
1515 jnodes = cell(1,length(line_nodes));
1516 jclasses = cell(1,length(line_classes));
1517
1518 for n = 1 : length(line_nodes)
1519 % Skip auto-added ClassSwitch nodes - Java's link() will add them automatically
1520 if isa(line_nodes{n}, 'ClassSwitch') && line_nodes{n}.autoAdded
1521 continue;
1522 end
1523 if isa(line_nodes{n}, 'Join')
1524 jnodes{n} = JLINE.from_line_node(line_nodes{n}, jnetwork, line_classes, jnodes{line_nodes{n}.joinOf.index}, sn);
1525 else
1526 jnodes{n} = JLINE.from_line_node(line_nodes{n}, jnetwork, line_classes, [], sn);
1527 end
1528 end
1529
1530 for n = 1 : length(line_classes)
1531 jclasses{n} = JLINE.from_line_class(line_classes{n}, jnetwork);
1532 end
1533
1534 % Set up forJobClass associations for signal classes
1535 for n = 1 : length(line_classes)
1536 if (isa(line_classes{n}, 'Signal') || isa(line_classes{n}, 'OpenSignal') || isa(line_classes{n}, 'ClosedSignal'))
1537 if ~isempty(line_classes{n}.targetJobClass)
1538 targetIdx = line_classes{n}.targetJobClass.index;
1539 jclasses{n}.forJobClass(jclasses{targetIdx});
1540 end
1541 end
1542 end
1543
1544 for n = 1: length(jnodes)
1545 if isempty(jnodes{n})
1546 continue; % Skip nodes that were not converted (e.g., auto-added ClassSwitch)
1547 end
1548 JLINE.set_service(line_nodes{n}, jnodes{n}, line_classes);
1549 JLINE.set_delayoff(line_nodes{n}, jnodes{n}, line_classes);
1550 end
1551
1552 % Set drop rules for stations (after classes are created)
1553 for n = 1: length(jnodes)
1554 if isempty(jnodes{n})
1555 continue; % Skip nodes that were not converted
1556 end
1557 if isa(line_nodes{n}, 'Station') && ~isa(line_nodes{n}, 'Source')
1558 for r = 1:length(line_classes)
1559 if length(line_nodes{n}.dropRule) >= r && ~isempty(line_nodes{n}.dropRule(r))
1560 dropRule = line_nodes{n}.dropRule(r);
1561 switch dropRule
1562 case DropStrategy.DROP
1563 jnodes{n}.setDropRule(jclasses{r}, jline.lang.constant.DropStrategy.Drop);
1564 case DropStrategy.BAS
1565 jnodes{n}.setDropRule(jclasses{r}, jline.lang.constant.DropStrategy.BlockingAfterService);
1566 case DropStrategy.WAITQ
1567 jnodes{n}.setDropRule(jclasses{r}, jline.lang.constant.DropStrategy.WaitingQueue);
1568 end
1569 end
1570 end
1571 end
1572 end
1573
1574 % Transfer LJCD (Limited Joint Class Dependence) scaling for stations
1575 % This must be done after classes are created since LJCD is indexed per-class
1576 for n = 1:length(jnodes)
1577 if isempty(jnodes{n})
1578 continue;
1579 end
1580 if isa(line_nodes{n}, 'Station') && ~isempty(line_nodes{n}.ljcdScaling) && ~isempty(line_nodes{n}.ljcdCutoffs)
1581 jCutoffs = JLINE.from_line_matrix(line_nodes{n}.ljcdCutoffs(:));
1582 K = length(line_nodes{n}.ljcdScaling);
1583 jScalingMap = java.util.HashMap();
1584 for c = 1:K
1585 if ~isempty(line_nodes{n}.ljcdScaling{c})
1586 jScalingVec = JLINE.from_line_matrix(line_nodes{n}.ljcdScaling{c}(:));
1587 jScalingMap.put(jclasses{c}, jScalingVec);
1588 end
1589 end
1590 jnodes{n}.setLimitedJointClassDependence(jScalingMap, jCutoffs);
1591 end
1592 end
1593
1594 % Set polling type and switchover times for polling queues
1595 for n = 1: length(jnodes)
1596 if isempty(jnodes{n})
1597 continue;
1598 end
1599 if isa(line_nodes{n}, 'Queue') && line_nodes{n}.schedStrategy == SchedStrategy.POLLING
1600 % Set polling type
1601 if ~isempty(line_nodes{n}.pollingType) && ~isempty(line_nodes{n}.pollingType{1})
1602 pollingType = line_nodes{n}.pollingType{1};
1603 switch pollingType
1604 case PollingType.GATED
1605 jPollingType = jline.lang.constant.PollingType.GATED;
1606 case PollingType.EXHAUSTIVE
1607 jPollingType = jline.lang.constant.PollingType.EXHAUSTIVE;
1608 case PollingType.KLIMITED
1609 jPollingType = jline.lang.constant.PollingType.KLIMITED;
1610 end
1611 if pollingType == PollingType.KLIMITED && ~isempty(line_nodes{n}.pollingPar)
1612 jnodes{n}.setPollingType(jPollingType, int32(line_nodes{n}.pollingPar));
1613 else
1614 jnodes{n}.setPollingType(jPollingType);
1615 end
1616 end
1617 % Set switchover times
1618 if ~isempty(line_nodes{n}.switchoverTime)
1619 for r = 1:length(line_classes)
1620 if length(line_nodes{n}.switchoverTime) >= r && ~isempty(line_nodes{n}.switchoverTime{r})
1621 soTime = line_nodes{n}.switchoverTime{r};
1622 if ~isa(soTime, 'Immediate')
1623 jnodes{n}.setSwitchover(jclasses{r}, JLINE.from_line_distribution(soTime));
1624 end
1625 end
1626 end
1627 end
1628 end
1629 end
1630
1631 for n = 1: length(jnodes)
1632 if isempty(jnodes{n})
1633 continue; % Skip nodes that were not converted
1634 end
1635 if isa(line_nodes{n},"ClassSwitch") && ~line_nodes{n}.autoAdded
1636 % Only set csMatrix for user-defined ClassSwitch nodes (not auto-added)
1637 JLINE.set_csMatrix(line_nodes{n}, jnodes{n}, jclasses);
1638 elseif isa(line_nodes{n},"Join")
1639 jnodes{n}.initJoinJobClasses();
1640 % Restore RAND routing for all classes, matching ClosedClass/OpenClass
1641 % constructor behavior (initJoinJobClasses sets DISABLED by default)
1642 for r = 1 : sn.nclasses
1643 jnodes{n}.setRouting(jclasses{r}, jline.lang.constant.RoutingStrategy.RAND);
1644 end
1645 elseif isa(line_nodes{n},"Cache")
1646 for r = 1 : sn.nclasses
1647 if length(line_nodes{n}.server.hitClass) >= r && ~isempty(line_nodes{n}.server.hitClass(r))
1648 if ~isa(line_nodes{n}.popularity{r},'Disabled')
1649 jnodes{n}.setRead(jclasses{r}, JLINE.from_line_distribution(line_nodes{n}.popularity{r}));
1650 jnodes{n}.setHitClass(jclasses{r}, jclasses{line_nodes{n}.server.hitClass(r)});
1651 jnodes{n}.setMissClass(jclasses{r}, jclasses{line_nodes{n}.server.missClass(r)});
1652 end
1653 end
1654 end
1655 % Transfer accessProb from MATLAB to Java
1656 if ~isempty(line_nodes{n}.accessProb)
1657 accessProbMat = line_nodes{n}.accessProb;
1658 [K1, K2] = size(accessProbMat);
1659 jAccessProb = javaArray('jline.util.matrix.Matrix', K1, K2);
1660 for k1 = 1:K1
1661 for k2 = 1:K2
1662 if ~isempty(accessProbMat{k1, k2})
1663 jAccessProb(k1, k2) = JLINE.from_line_matrix(accessProbMat{k1, k2});
1664 end
1665 end
1666 end
1667 jnodes{n}.setAccessProb(jAccessProb);
1668 end
1669 elseif isa(line_nodes{n}, "Transition")
1670 % First, add modes (must be done after classes are created)
1671 for m = 1:line_nodes{n}.getNumberOfModes()
1672 modeName = line_nodes{n}.modeNames{m};
1673 jmode = jnodes{n}.addMode(modeName);
1674 % Set timing strategy
1675 switch line_nodes{n}.timingStrategies(m)
1676 case TimingStrategy.TIMED
1677 jnodes{n}.setTimingStrategy(jmode, jline.lang.constant.TimingStrategy.TIMED);
1678 case TimingStrategy.IMMEDIATE
1679 jnodes{n}.setTimingStrategy(jmode, jline.lang.constant.TimingStrategy.IMMEDIATE);
1680 end
1681 % Set distribution
1682 jnodes{n}.setDistribution(jmode, JLINE.from_line_distribution(line_nodes{n}.distributions{m}));
1683 % Set firing weights and priorities
1684 jnodes{n}.setFiringWeights(jmode, line_nodes{n}.firingWeights(m));
1685 jnodes{n}.setFiringPriorities(jmode, int32(line_nodes{n}.firingPriorities(m)));
1686 % Set number of servers
1687 nsrv = line_nodes{n}.numberOfServers(m);
1688 if isinf(nsrv)
1689 jnodes{n}.setNumberOfServers(jmode, java.lang.Integer(intmax('int32')));
1690 else
1691 jnodes{n}.setNumberOfServers(jmode, java.lang.Integer(int32(nsrv)));
1692 end
1693 end
1694 % Now set enabling conditions, inhibiting conditions, and firing outcomes
1695 jmodes = jnodes{n}.getModes();
1696 for m = 1:line_nodes{n}.getNumberOfModes()
1697 jmode = jmodes.get(m-1);
1698 enabCond = line_nodes{n}.enablingConditions{m};
1699 inhibCond = line_nodes{n}.inhibitingConditions{m};
1700 firingOut = line_nodes{n}.firingOutcomes{m};
1701 for r = 1:sn.nclasses
1702 for i = 1:length(line_nodes)
1703 % Set enabling conditions
1704 if enabCond(i, r) > 0 && isa(line_nodes{i}, 'Place')
1705 jnodes{n}.setEnablingConditions(jmode, jclasses{r}, jnodes{i}, enabCond(i, r));
1706 end
1707 % Set inhibiting conditions
1708 if inhibCond(i, r) < Inf && isa(line_nodes{i}, 'Place')
1709 jnodes{n}.setInhibitingConditions(jmode, jclasses{r}, jnodes{i}, inhibCond(i, r));
1710 end
1711 % Set firing outcomes
1712 if firingOut(i, r) ~= 0
1713 jnodes{n}.setFiringOutcome(jmode, jclasses{r}, jnodes{i}, firingOut(i, r));
1714 end
1715 end
1716 end
1717 end
1718 end
1719 end
1720
1721 % Assume JLINE and LINE network are both created via link
1722 JLINE.from_line_links(model, jnetwork);
1723
1724 % Transfer finite capacity regions from MATLAB to Java
1725 if ~isempty(model.regions)
1726 for f = 1:length(model.regions)
1727 fcr = model.regions{f};
1728 % Convert MATLAB node list to Java list
1729 javaNodeList = java.util.ArrayList();
1730 for i = 1:length(fcr.nodes)
1731 matlabNode = fcr.nodes{i};
1732 % Find corresponding Java node by name
1733 nodeName = matlabNode.getName();
1734 for j = 1:length(line_nodes)
1735 if strcmp(line_nodes{j}.getName(), nodeName) && ~isempty(jnodes{j})
1736 javaNodeList.add(jnodes{j});
1737 break;
1738 end
1739 end
1740 end
1741 % Create Java FCR
1742 jfcr = jnetwork.addRegion(javaNodeList);
1743 % Set global max jobs
1744 if fcr.globalMaxJobs > 0 && ~isinf(fcr.globalMaxJobs)
1745 jfcr.setGlobalMaxJobs(fcr.globalMaxJobs);
1746 end
1747 % Set per-class max jobs and drop rules
1748 for r = 1:length(line_classes)
1749 if length(fcr.classMaxJobs) >= r && fcr.classMaxJobs(r) > 0 && ~isinf(fcr.classMaxJobs(r))
1750 jfcr.setClassMaxJobs(jclasses{r}, fcr.classMaxJobs(r));
1751 end
1752 if length(fcr.dropRule) >= r
1753 % Convert MATLAB DropStrategy numeric to Java DropStrategy enum
1754 jDropStrategy = jline.lang.constant.DropStrategy.fromID(fcr.dropRule(r));
1755 jfcr.setDropRule(jclasses{r}, jDropStrategy);
1756 end
1757 end
1758 % Transfer linear constraints if set
1759 if fcr.hasLinearConstraints()
1760 jA = JLINE.from_line_matrix(fcr.constraintA);
1761 jb = JLINE.from_line_matrix(fcr.constraintB);
1762 jfcr.setLinearConstraints(jA, jb);
1763 end
1764 end
1765 end
1766
1767 jnetwork.initDefault;
1768 for n = 1: length(line_nodes)
1769 if isempty(jnodes{n})
1770 continue; % Skip nodes that were not converted
1771 end
1772 if line_nodes{n}.isStateful
1773 jnodes{n}.setState(JLINE.from_line_matrix(line_nodes{n}.getState));
1774 jnodes{n}.setStateSpace(JLINE.from_line_matrix(line_nodes{n}.getStateSpace));
1775 jnodes{n}.setStatePrior(JLINE.from_line_matrix(line_nodes{n}.getStatePrior));
1776 end
1777 end
1778 % Force struct refresh so sn.state reflects updated node states
1779 jnetwork.setHasStruct(false);
1780
1781 end
1782
1783 function jnetwork = line_to_jline(model)
1784 jnetwork = LINE2JLINE(model);
1785 end
1786
1787 function model = jline_to_line(jnetwork)
1788 if isa(jnetwork,'JNetwork')
1789 jnetwork = jnetwork.obj;
1790 end
1791 %javaaddpath(jar_loc);
1792 model = Network(char(jnetwork.getName));
1793 network_nodes = jnetwork.getNodes;
1794 job_classes = jnetwork.getClasses;
1795
1796 line_nodes = cell(network_nodes.size,1);
1797 line_classes = cell(job_classes.size,1);
1798
1799
1800 for n = 1 : network_nodes.size
1801 if ~isa(network_nodes.get(n-1), 'jline.lang.nodes.ClassSwitch')
1802 line_nodes{n} = JLINE.from_jline_node(network_nodes.get(n-1), model, job_classes);
1803 end
1804 end
1805
1806 for n = 1 : job_classes.size
1807 line_classes{n} = JLINE.from_jline_class(job_classes.get(n-1), model);
1808 end
1809
1810 for n = 1 : network_nodes.size
1811 if isa(network_nodes.get(n-1), 'jline.lang.nodes.ClassSwitch')
1812 line_nodes{n} = JLINE.from_jline_node(network_nodes.get(n-1), model, job_classes);
1813 end
1814 end
1815
1816 % Deferred Fork/Join linking: set joinOf on Join nodes
1817 for n = 1 : network_nodes.size
1818 jnode = network_nodes.get(n-1);
1819 if isa(jnode, 'jline.lang.nodes.Join') && ~isempty(jnode.joinOf)
1820 forkName = char(jnode.joinOf.getName);
1821 for m = 1 : network_nodes.size
1822 if ~isempty(line_nodes{m}) && isa(line_nodes{m}, 'Fork') && strcmp(line_nodes{m}.name, forkName)
1823 line_nodes{n}.joinOf = line_nodes{m};
1824 break;
1825 end
1826 end
1827 end
1828 end
1829
1830 % Deferred Cache setup: set hitClass, missClass, popularity
1831 for n = 1 : network_nodes.size
1832 jnode = network_nodes.get(n-1);
1833 if isa(jnode, 'jline.lang.nodes.Cache') && isa(line_nodes{n}, 'Cache')
1834 cacheNode = line_nodes{n};
1835 % hitClass and missClass are stored as index vectors
1836 hitClassVec = JLINE.from_jline_matrix(jnode.getHitClass());
1837 missClassVec = JLINE.from_jline_matrix(jnode.getMissClass());
1838 for r = 1:job_classes.size
1839 hitIdx = hitClassVec(r);
1840 if hitIdx >= 0 && (hitIdx + 1) <= job_classes.size
1841 cacheNode.setHitClass(line_classes{r}, line_classes{hitIdx + 1});
1842 end
1843 missIdx = missClassVec(r);
1844 if missIdx >= 0 && (missIdx + 1) <= job_classes.size
1845 cacheNode.setMissClass(line_classes{r}, line_classes{missIdx + 1});
1846 end
1847 end
1848 % Popularity distributions
1849 for r = 1:job_classes.size
1850 try
1851 popDist = jnode.popularityGet(0, r-1);
1852 if ~isempty(popDist) && popDist.isDiscrete()
1853 matlabDist = JLINE.from_jline_distribution(popDist);
1854 if ~isempty(matlabDist)
1855 cacheNode.setRead(line_classes{r}, matlabDist);
1856 end
1857 end
1858 catch
1859 % No popularity for this class
1860 end
1861 end
1862 end
1863 end
1864
1865 for n = 1 : network_nodes.size
1866 JLINE.set_line_service(network_nodes.get(n-1), line_nodes{n}, job_classes, line_classes);
1867 end
1868
1869 % Configure Transition modes (distributions, enabling/inhibiting/firing, etc.)
1870 for n = 1 : network_nodes.size
1871 jnode = network_nodes.get(n-1);
1872 if isa(jnode, 'jline.lang.nodes.Transition') && isa(line_nodes{n}, 'Transition')
1873 tnode = line_nodes{n};
1874 jmodes = jnode.getModes();
1875 nmodes = jmodes.size();
1876 for m = 1 : nmodes
1877 jmode = jmodes.get(m-1);
1878 modeName = char(jmode.getName());
1879 % addMode if not yet present (Transition starts with one default mode)
1880 if m > tnode.getNumberOfModes()
1881 tnode.addMode(modeName);
1882 else
1883 tnode.setModeNames(m, modeName);
1884 end
1885 % Timing strategy
1886 ts = jnode.timingStrategies.get(jmode);
1887 if ~isempty(ts)
1888 tsName = char(ts.name());
1889 if strcmp(tsName, 'IMMEDIATE')
1890 tnode.setTimingStrategy(m, TimingStrategy.IMMEDIATE);
1891 else
1892 tnode.setTimingStrategy(m, TimingStrategy.TIMED);
1893 end
1894 end
1895 % Distribution
1896 jdist = jnode.getFiringDistribution(jmode);
1897 if ~isempty(jdist)
1898 matlabDist = JLINE.from_jline_distribution(jdist);
1899 if ~isempty(matlabDist)
1900 tnode.setDistribution(m, matlabDist);
1901 end
1902 end
1903 % Number of servers
1904 numSrv = jnode.getNumberOfModeServers(jmode);
1905 if numSrv == intmax('int32') || numSrv == intmax('int64')
1906 tnode.setNumberOfServers(m, Inf);
1907 else
1908 tnode.setNumberOfServers(m, double(numSrv));
1909 end
1910 % Firing priority and weight (read from matrices by mode index)
1911 if jnode.firingPriorities.getNumElements() > (m-1)
1912 tnode.setFiringPriorities(m, jnode.firingPriorities.get(m-1));
1913 end
1914 if jnode.firingWeights.getNumElements() > (m-1)
1915 tnode.setFiringWeights(m, jnode.firingWeights.get(m-1));
1916 end
1917 % Enabling conditions
1918 ecMat = jnode.enablingConditions.get(jmode);
1919 if ~isempty(ecMat)
1920 nrows = ecMat.getNumRows();
1921 ncols = ecMat.getNumCols();
1922 for ni = 1 : nrows
1923 for ci = 1 : ncols
1924 val = ecMat.get(ni-1, ci-1);
1925 if val > 0 && ni <= length(line_nodes) && isa(line_nodes{ni}, 'Place')
1926 tnode.setEnablingConditions(m, ci, line_nodes{ni}, val);
1927 end
1928 end
1929 end
1930 end
1931 % Inhibiting conditions
1932 icMat = jnode.inhibitingConditions.get(jmode);
1933 if ~isempty(icMat)
1934 nrows = icMat.getNumRows();
1935 ncols = icMat.getNumCols();
1936 for ni = 1 : nrows
1937 for ci = 1 : ncols
1938 val = icMat.get(ni-1, ci-1);
1939 if isfinite(val) && val > 0 && ni <= length(line_nodes) && isa(line_nodes{ni}, 'Place')
1940 tnode.setInhibitingConditions(m, ci, line_nodes{ni}, val);
1941 end
1942 end
1943 end
1944 end
1945 % Firing outcomes
1946 foMat = jnode.firingOutcomes.get(jmode);
1947 if ~isempty(foMat)
1948 nrows = foMat.getNumRows();
1949 ncols = foMat.getNumCols();
1950 for ni = 1 : nrows
1951 for ci = 1 : ncols
1952 val = foMat.get(ni-1, ci-1);
1953 if val ~= 0 && ni <= length(line_nodes)
1954 tnode.setFiringOutcome(m, ci, line_nodes{ni}, val);
1955 end
1956 end
1957 end
1958 end
1959 end
1960 end
1961 end
1962
1963 % Check for state-dependent routing (RROBIN, WRROBIN, JSQ)
1964 % These cannot go through link(P) because it overrides routing strategies
1965 hasSDRouting = false;
1966 for n = 1 : network_nodes.size
1967 jnode = network_nodes.get(n-1);
1968 output_strategies = jnode.getOutputStrategies();
1969 for m = 1 : output_strategies.size()
1970 rs = char(output_strategies.get(m-1).getRoutingStrategy);
1971 if any(strcmp(rs, {'RROBIN','WRROBIN','JSQ','KCHOICES'}))
1972 hasSDRouting = true;
1973 break;
1974 end
1975 end
1976 if hasSDRouting; break; end
1977 end
1978
1979 if hasSDRouting
1980 % State-dependent routing: use addLink + setRouting
1981 model = JLINE.from_jline_routing(model, jnetwork);
1982 elseif ~isempty(jnetwork.getStruct.rtorig)
1983 % Use link() method
1984 model = JLINE.from_jline_links(model, jnetwork);
1985 else
1986 % Do not use link() method
1987 model = JLINE.from_jline_routing(model, jnetwork);
1988 end
1989
1990 % Restore initial state on Place nodes after linking
1991 for n = 1 : network_nodes.size
1992 jnode = network_nodes.get(n-1);
1993 if isa(jnode, 'jline.lang.nodes.Place') && ~isempty(line_nodes{n}) && isa(line_nodes{n}, 'Place')
1994 jst = jnode.getState();
1995 if ~isempty(jst) && ~jst.isEmpty()
1996 line_nodes{n}.setState(JLINE.from_jline_matrix(jst));
1997 end
1998 end
1999 end
2000 end
2001
2002 function matrix = arraylist_to_matrix(jline_matrix)
2003 if isempty(jline_matrix)
2004 matrix = [];
2005 else
2006 matrix = zeros(jline_matrix.size(), 1);
2007 for row = 1:jline_matrix.size()
2008 matrix(row, 1) = jline_matrix.get(row-1);
2009 end
2010 end
2011 end
2012
2013 function matrix = from_jline_matrix(jline_matrix)
2014 if isempty(jline_matrix)
2015 matrix = [];
2016 else
2017 matrix = zeros(jline_matrix.getNumRows(), jline_matrix.getNumCols());
2018 for row = 1:jline_matrix.getNumRows()
2019 for col = 1:jline_matrix.getNumCols()
2020 val = jline_matrix.get(row-1, col-1);
2021 if (val >= 33333333 && val <= 33333334)
2022 matrix(row, col) = GlobalConstants.Immediate;
2023 elseif (val >= -33333334 && val <= -33333333)
2024 matrix(row, col) = -GlobalConstants.Immediate;
2025 elseif (val >= 2147483647 - 1) % Integer.MAX_VALUE with -1 tolerance
2026 matrix(row, col) = Inf;
2027 elseif (val <= -2147483648 + 1) % Integer.MIN_VALUE with +1 tolerance
2028 matrix(row, col) = -Inf;
2029 else
2030 matrix(row, col) = val;
2031 end
2032 end
2033 end
2034 end
2035 end
2036
2037 function jline_matrix = from_line_matrix(matrix)
2038 [rows, cols] = size(matrix);
2039 jline_matrix = jline.util.matrix.Matrix(rows, cols);
2040 for row = 1:rows
2041 for col = 1:cols
2042 if matrix(row,col) ~= 0
2043 jline_matrix.set(row-1, col-1, matrix(row, col));
2044 end
2045 end
2046 end
2047 end
2048
2049 function lsn = from_jline_struct_layered(jlayerednetwork, jlsn)
2050 lsn = LayeredNetworkStruct();
2051 lsn.nidx= jlsn.nidx;
2052 lsn.nhosts= jlsn.nhosts;
2053 lsn.ntasks= jlsn.ntasks;
2054 lsn.nentries= jlsn.nentries;
2055 lsn.nacts= jlsn.nacts;
2056 lsn.ncalls= jlsn.ncalls;
2057 lsn.hshift= jlsn.hshift;
2058 lsn.tshift= jlsn.tshift;
2059 lsn.eshift= jlsn.eshift;
2060 lsn.ashift= jlsn.ashift;
2061 lsn.cshift= jlsn.cshift;
2062 for h=1:jlsn.nhosts
2063 lsn.tasksof{h,1} = JLINE.arraylist_to_matrix(jlsn.tasksof.get(uint32(h)))';
2064 end
2065 for t=1:jlsn.ntasks
2066 lsn.entriesof{lsn.tshift+t,1} = JLINE.arraylist_to_matrix(jlsn.entriesof.get(uint32(jlsn.tshift+t)))';
2067 end
2068 for t=1:(jlsn.ntasks+jlsn.nentries)
2069 lsn.actsof{lsn.tshift+t,1} = JLINE.arraylist_to_matrix(jlsn.actsof.get(uint32(jlsn.tshift+t)))';
2070 end
2071 for a=1:jlsn.nacts
2072 lsn.callsof{lsn.ashift+a,1} = JLINE.arraylist_to_matrix(jlsn.callsof.get(uint32(jlsn.ashift+a)))';
2073 end
2074 for i = 1:jlsn.sched.size
2075 lsn.sched(i,1) = SchedStrategy.(char(jlsn.sched.get(uint32(i))));
2076 end
2077 for i = 1:jlsn.names.size
2078 lsn.names{i,1} = jlsn.names.get(uint32(i));
2079 lsn.hashnames{i,1} = jlsn.hashnames.get(uint32(i));
2080 end
2081 lsn.mult = JLINE.from_jline_matrix(jlsn.mult);
2082 lsn.mult = lsn.mult(2:(lsn.eshift+1))'; % remove 0-padding
2083 lsn.maxmult = JLINE.from_jline_matrix(jlsn.maxmult);
2084 lsn.maxmult = lsn.maxmult(2:(lsn.eshift+1))'; % remove 0-padding
2085
2086 lsn.repl = JLINE.from_jline_matrix(jlsn.repl)';
2087 lsn.repl = lsn.repl(2:end); % remove 0-padding
2088 lsn.type = JLINE.from_jline_matrix(jlsn.type)';
2089 lsn.type = lsn.type(2:end); % remove 0-padding
2090 lsn.parent = JLINE.from_jline_matrix(jlsn.parent);
2091 lsn.parent = lsn.parent(2:end); % remove 0-padding
2092 lsn.nitems = JLINE.from_jline_matrix(jlsn.nitems);
2093 % Ensure proper column vector format matching MATLAB's (nhosts+ntasks+nentries) x 1
2094 if isrow(lsn.nitems)
2095 lsn.nitems = lsn.nitems(2:end)'; % remove 0-padding and transpose
2096 else
2097 lsn.nitems = lsn.nitems(2:end); % remove 0-padding (already column)
2098 end
2099 % Ensure correct size
2100 expectedSize = lsn.nhosts + lsn.ntasks + lsn.nentries;
2101 if length(lsn.nitems) < expectedSize
2102 lsn.nitems(expectedSize,1) = 0;
2103 elseif length(lsn.nitems) > expectedSize
2104 lsn.nitems = lsn.nitems(1:expectedSize);
2105 end
2106 lsn.replacestrat = JLINE.from_jline_matrix(jlsn.replacestrat);
2107 lsn.replacestrat = lsn.replacestrat(2:end)'; % remove 0-padding
2108 for i = 1:jlsn.callnames.size
2109 lsn.callnames{i,1} = jlsn.callnames.get(uint32(i));
2110 lsn.callhashnames{i,1} = jlsn.callhashnames.get(uint32(i));
2111 end
2112 for i = 1:jlsn.calltype.size % calltype may be made into a matrix in Java
2113 ct = char(jlsn.calltype.get(uint32(i)));
2114 lsn.calltype(i) = CallType.(ct);
2115 end
2116 lsn.calltype = sparse(lsn.calltype'); % remove 0-padding
2117 lsn.callpair = JLINE.from_jline_matrix(jlsn.callpair);
2118 lsn.callpair = lsn.callpair(2:end,2:end); % remove 0-paddings
2119 if isempty(lsn.callpair)
2120 lsn.callpair=[];
2121 end
2122 lsn.actpretype = sparse(JLINE.from_jline_matrix(jlsn.actpretype)');
2123 lsn.actpretype = lsn.actpretype(2:end); % remove 0-padding
2124 lsn.actposttype = sparse(JLINE.from_jline_matrix(jlsn.actposttype)');
2125 lsn.actposttype = lsn.actposttype(2:end); % remove 0-padding
2126 lsn.graph = JLINE.from_jline_matrix(jlsn.graph);
2127 lsn.graph = lsn.graph(2:end,2:end); % remove 0-paddings
2128 lsn.dag = JLINE.from_jline_matrix(jlsn.dag);
2129 lsn.dag = lsn.dag(2:end,2:end); % remove 0-paddings
2130 lsn.taskgraph = JLINE.from_jline_matrix(jlsn.taskgraph);
2131 lsn.taskgraph = sparse(lsn.taskgraph(2:end,2:end)); % remove 0-paddings
2132 lsn.replygraph = JLINE.from_jline_matrix(jlsn.replygraph);
2133 lsn.replygraph = logical(lsn.replygraph(2:end,2:end)); % remove 0-paddings
2134 lsn.iscache = JLINE.from_jline_matrix(jlsn.iscache);
2135 % Ensure proper column vector format matching MATLAB's (nhosts+ntasks) x 1
2136 expectedCacheSize = lsn.nhosts + lsn.ntasks;
2137 if isrow(lsn.iscache)
2138 if length(lsn.iscache) > expectedCacheSize
2139 lsn.iscache = lsn.iscache(2:(expectedCacheSize+1))'; % remove 0-padding and transpose
2140 else
2141 lsn.iscache = lsn.iscache'; % just transpose
2142 end
2143 end
2144 % Ensure correct size
2145 if length(lsn.iscache) < expectedCacheSize
2146 lsn.iscache(expectedCacheSize,1) = 0;
2147 elseif length(lsn.iscache) > expectedCacheSize
2148 lsn.iscache = lsn.iscache(1:expectedCacheSize);
2149 end
2150 lsn.iscaller = JLINE.from_jline_matrix(jlsn.iscaller);
2151 lsn.iscaller = full(lsn.iscaller(2:end,2:end)); % remove 0-paddings
2152 lsn.issynccaller = JLINE.from_jline_matrix(jlsn.issynccaller);
2153 lsn.issynccaller = full(lsn.issynccaller(2:end,2:end)); % remove 0-paddings
2154 lsn.isasynccaller = JLINE.from_jline_matrix(jlsn.isasynccaller);
2155 lsn.isasynccaller = full(lsn.isasynccaller(2:end,2:end)); % remove 0-paddings
2156 lsn.isref = JLINE.from_jline_matrix(jlsn.isref);
2157 lsn.isref = lsn.isref(2:end)'; % remove 0-paddings
2158 end
2159
2160 function sn = from_jline_struct(jnetwork, jsn)
2161 %lst and rtfun are not implemented
2162 %Due to the transformation of Java lambda to matlab function
2163 if nargin<2
2164 jsn = jnetwork.getStruct(false);
2165 end
2166 jclasses = jnetwork.getClasses();
2167 jnodes = jnetwork.getNodes();
2168 jstateful = jnetwork.getStatefulNodes();
2169 jstations = jnetwork.getStations();
2170 sn = NetworkStruct();
2171
2172 sn.nnodes = jsn.nnodes;
2173 sn.nclasses = jsn.nclasses;
2174 sn.nclosedjobs = jsn.nclosedjobs;
2175 sn.nstations = jsn.nstations;
2176 sn.nstateful = jsn.nstateful;
2177 sn.nchains = jsn.nchains;
2178
2179 sn.refstat = JLINE.from_jline_matrix(jsn.refstat) + 1;
2180 sn.njobs = JLINE.from_jline_matrix(jsn.njobs);
2181 sn.nservers = JLINE.from_jline_matrix(jsn.nservers);
2182 sn.connmatrix = JLINE.from_jline_matrix(jsn.connmatrix);
2183 % Fix for Java getConnectionMatrix bug: ensure connmatrix is nnodes x nnodes
2184 if size(sn.connmatrix,1) < sn.nnodes
2185 sn.connmatrix(sn.nnodes,1) = 0;
2186 end
2187 if size(sn.connmatrix,2) < sn.nnodes
2188 sn.connmatrix(1,sn.nnodes) = 0;
2189 end
2190 sn.scv = JLINE.from_jline_matrix(jsn.scv);
2191 sn.isstation = logical(JLINE.from_jline_matrix(jsn.isstation));
2192 sn.isstateful = logical(JLINE.from_jline_matrix(jsn.isstateful));
2193 sn.isstatedep = logical(JLINE.from_jline_matrix(jsn.isstatedep));
2194 sn.nodeToStateful = JLINE.from_jline_matrix(jsn.nodeToStateful)+1;
2195 sn.nodeToStateful(sn.nodeToStateful==0) = nan;
2196 sn.nodeToStation = JLINE.from_jline_matrix(jsn.nodeToStation)+1;
2197 sn.nodeToStation(sn.nodeToStation==0) = nan;
2198 sn.stationToNode = JLINE.from_jline_matrix(jsn.stationToNode)+1;
2199 sn.stationToNode(sn.stationToNode==0) = nan;
2200 sn.stationToStateful = JLINE.from_jline_matrix(jsn.stationToStateful)+1;
2201 sn.stationToStateful(sn.stationToStateful==0) = nan;
2202 sn.statefulToStation = JLINE.from_jline_matrix(jsn.statefulToStation)+1;
2203 sn.statefulToStation(sn.statefulToStation==0) = nan;
2204 sn.statefulToNode = JLINE.from_jline_matrix(jsn.statefulToNode)+1;
2205 sn.statefulToNode(sn.statefulToNode==0) = nan;
2206 sn.rates = JLINE.from_jline_matrix(jsn.rates);
2207 sn.fj = JLINE.from_jline_matrix(jsn.fj);
2208 sn.classprio = JLINE.from_jline_matrix(jsn.classprio);
2209 sn.phases = JLINE.from_jline_matrix(jsn.phases);
2210 sn.phasessz = JLINE.from_jline_matrix(jsn.phasessz);
2211 sn.phaseshift = JLINE.from_jline_matrix(jsn.phaseshift);
2212 sn.schedparam = JLINE.from_jline_matrix(jsn.schedparam);
2213 sn.chains = logical(JLINE.from_jline_matrix(jsn.chains));
2214 sn.rt = JLINE.from_jline_matrix(jsn.rt);
2215 sn.nvars = JLINE.from_jline_matrix(jsn.nvars);
2216 sn.rtnodes = JLINE.from_jline_matrix(jsn.rtnodes);
2217 sn.csmask = logical(JLINE.from_jline_matrix(jsn.csmask));
2218 sn.isslc = logical(JLINE.from_jline_matrix(jsn.isslc));
2219 sn.cap = JLINE.from_jline_matrix(jsn.cap);
2220 sn.classcap = JLINE.from_jline_matrix(jsn.classcap);
2221 sn.refclass = JLINE.from_jline_matrix(jsn.refclass)+1;
2222 sn.lldscaling = JLINE.from_jline_matrix(jsn.lldscaling);
2223
2224 if ~isempty(jsn.cdscaling) && jsn.cdscaling.size() > 0
2225 % Convert Java SerializableFunction to MATLAB function handles
2226 sn.cdscaling = cell(sn.nstations, 1);
2227 % Iterate through the map entries to handle null values properly
2228 entrySet = jsn.cdscaling.entrySet();
2229 entryIter = entrySet.iterator();
2230 stationFunMap = containers.Map();
2231 while entryIter.hasNext()
2232 entry = entryIter.next();
2233 stationName = char(entry.getKey().getName());
2234 try
2235 jfun = entry.getValue();
2236 if ~isempty(jfun)
2237 stationFunMap(stationName) = jfun;
2238 end
2239 catch
2240 % getValue() returns null for default lambda functions
2241 % Skip and use default value
2242 end
2243 end
2244 % Assign functions to stations
2245 for i = 1:sn.nstations
2246 jstation = jstations.get(i-1);
2247 stationName = char(jstation.getName());
2248 if isKey(stationFunMap, stationName)
2249 jfun = stationFunMap(stationName);
2250 % Create a MATLAB function handle that calls the Java apply() method
2251 sn.cdscaling{i} = @(ni) JLINE.call_java_cdscaling(jfun, ni);
2252 else
2253 sn.cdscaling{i} = @(ni) 1;
2254 end
2255 end
2256 else
2257 sn.cdscaling = cell(sn.nstations, 0);
2258 end
2259
2260 if ~isempty(jsn.nodetype)
2261 sn.nodetype = zeros(sn.nnodes, 1);
2262 for i = 1:jsn.nodetype.size
2263 nodetype = jsn.nodetype.get(i-1);
2264 switch nodetype.name().toCharArray'
2265 case 'Queue'
2266 sn.nodetype(i) = NodeType.Queue;
2267 case 'Delay'
2268 sn.nodetype(i) = NodeType.Delay;
2269 case 'Source'
2270 sn.nodetype(i) = NodeType.Source;
2271 case 'Sink'
2272 sn.nodetype(i) = NodeType.Sink;
2273 case 'Join'
2274 sn.nodetype(i) = NodeType.Join;
2275 case 'Fork'
2276 sn.nodetype(i) = NodeType.Fork;
2277 case 'ClassSwitch'
2278 sn.nodetype(i) = NodeType.ClassSwitch;
2279 case 'Logger'
2280 sn.nodetype(i) = NodeType.Logger;
2281 case 'Cache'
2282 sn.nodetype(i) = NodeType.Cache;
2283 case 'Place'
2284 sn.nodetype(i) = NodeType.Place;
2285 case 'Transition'
2286 sn.nodetype(i) = NodeType.Transition;
2287 case 'Router'
2288 sn.nodetype(i) = NodeType.Router;
2289 end
2290 end
2291 else
2292 sn.nodetype = [];
2293 end
2294
2295 if ~isempty(jsn.classnames)
2296 for i = 1:jsn.classnames.size
2297 sn.classnames(i,1) = jsn.classnames.get(i-1);
2298 end
2299 else
2300 sn.classnames = [];
2301 end
2302
2303 if ~isempty(jsn.nodenames)
2304 for i = 1:jsn.nodenames.size
2305 sn.nodenames(i,1) = jsn.nodenames.get(i-1);
2306 end
2307 else
2308 sn.nodenames = [];
2309 end
2310
2311 if ~isempty(jsn.rtorig) && jsn.rtorig.size()>0
2312 sn.rtorig = cell(sn.nclasses, sn.nclasses);
2313 for r = 1:sn.nclasses
2314 for s = 1:sn.nclasses
2315 sn.rtorig{r,s} = JLINE.from_jline_matrix(jsn.rtorig.get(jclasses.get(r-1)).get(jclasses.get(s-1)));
2316 end
2317 end
2318 else
2319 sn.rtorig = {};
2320 end
2321
2322 if ~isempty(jsn.state)
2323 sn.state = cell(sn.nstateful, 1);
2324 for i = 1:sn.nstateful
2325 sn.state{i} = JLINE.from_jline_matrix(jstateful.get(i-1).getState());
2326 end
2327 else
2328 sn.state = {};
2329 end
2330
2331 if ~isempty(jsn.stateprior)
2332 sn.stateprior = cell(sn.nstateful, 1);
2333 for i = 1:sn.nstateful
2334 sn.stateprior{i} = JLINE.from_jline_matrix(jstateful.get(i-1).getStatePrior());
2335 end
2336 else
2337 sn.stateprior = {};
2338 end
2339
2340 if ~isempty(jsn.space)
2341 sn.space = cell(sn.nstateful, 1);
2342 for i = 1:sn.nstateful
2343 sn.space{i} = JLINE.from_jline_matrix(jstateful.get(i-1).getStateSpace());
2344 end
2345 else
2346 sn.space = {};
2347 end
2348
2349 if ~isempty(jsn.routing)
2350 sn.routing = zeros(sn.nnodes, sn.nclasses);
2351 for i = 1:sn.nnodes
2352 for j = 1:sn.nclasses
2353 routingStrategy = jsn.routing.get(jnodes.get(i-1)).get(jclasses.get(j-1));
2354 switch routingStrategy.name().toCharArray'
2355 case 'PROB'
2356 sn.routing(i,j) = RoutingStrategy.PROB;
2357 case 'RAND'
2358 sn.routing(i,j) = RoutingStrategy.RAND;
2359 case 'RROBIN'
2360 sn.routing(i,j) = RoutingStrategy.RROBIN;
2361 case 'WRROBIN'
2362 sn.routing(i,j) = RoutingStrategy.WRROBIN;
2363 case 'JSQ'
2364 sn.routing(i,j) = RoutingStrategy.JSQ;
2365 case 'DISABLED'
2366 sn.routing(i,j) = RoutingStrategy.DISABLED;
2367 case 'FIRING'
2368 sn.routing(i,j) = RoutingStrategy.FIRING;
2369 case 'KCHOICES'
2370 sn.routing(i,j) = RoutingStrategy.KCHOICES;
2371 end
2372 end
2373 end
2374 else
2375 sn.routing = [];
2376 end
2377
2378 if ~isempty(jsn.procid)
2379 sn.procid = nan(sn.nstations, sn.nclasses); % Initialize with NaN to match MATLAB behavior
2380 for i = 1:sn.nstations
2381 for j = 1:sn.nclasses
2382 stationMap = jsn.procid.get(jstations.get(i-1));
2383 if isempty(stationMap)
2384 sn.procid(i,j) = ProcessType.DISABLED;
2385 continue;
2386 end
2387 processType = stationMap.get(jclasses.get(j-1));
2388 if isempty(processType)
2389 sn.procid(i,j) = ProcessType.DISABLED;
2390 continue;
2391 end
2392 switch processType.name.toCharArray'
2393 case 'EXP'
2394 sn.procid(i,j) = ProcessType.EXP;
2395 case 'ERLANG'
2396 sn.procid(i,j) = ProcessType.ERLANG;
2397 case 'HYPEREXP'
2398 sn.procid(i,j) = ProcessType.HYPEREXP;
2399 case 'PH'
2400 sn.procid(i,j) = ProcessType.PH;
2401 case 'APH'
2402 sn.procid(i,j) = ProcessType.APH;
2403 case 'MAP'
2404 sn.procid(i,j) = ProcessType.MAP;
2405 case 'UNIFORM'
2406 sn.procid(i,j) = ProcessType.UNIFORM;
2407 case 'DET'
2408 sn.procid(i,j) = ProcessType.DET;
2409 case 'COXIAN'
2410 sn.procid(i,j) = ProcessType.COXIAN;
2411 case 'GAMMA'
2412 sn.procid(i,j) = ProcessType.GAMMA;
2413 case 'PARETO'
2414 sn.procid(i,j) = ProcessType.PARETO;
2415 case 'WEIBULL'
2416 sn.procid(i,j) = ProcessType.WEIBULL;
2417 case 'LOGNORMAL'
2418 sn.procid(i,j) = ProcessType.LOGNORMAL;
2419 case 'MMPP2'
2420 sn.procid(i,j) = ProcessType.MMPP2;
2421 case 'REPLAYER'
2422 sn.procid(i,j) = ProcessType.REPLAYER;
2423 case 'TRACE'
2424 sn.procid(i,j) = ProcessType.TRACE;
2425 case 'IMMEDIATE'
2426 sn.procid(i,j) = ProcessType.IMMEDIATE;
2427 case 'DISABLED'
2428 sn.procid(i,j) = ProcessType.DISABLED;
2429 case 'COX2'
2430 sn.procid(i,j) = ProcessType.COX2;
2431 case 'BMAP'
2432 sn.procid(i,j) = ProcessType.BMAP;
2433 case 'ME'
2434 sn.procid(i,j) = ProcessType.ME;
2435 case 'RAP'
2436 sn.procid(i,j) = ProcessType.RAP;
2437 case 'BINOMIAL'
2438 sn.procid(i,j) = ProcessType.BINOMIAL;
2439 case 'POISSON'
2440 sn.procid(i,j) = ProcessType.POISSON;
2441 case 'GEOMETRIC'
2442 sn.procid(i,j) = ProcessType.GEOMETRIC;
2443 case 'DUNIFORM'
2444 sn.procid(i,j) = ProcessType.DUNIFORM;
2445 case 'BERNOULLI'
2446 sn.procid(i,j) = ProcessType.BERNOULLI;
2447 case 'PRIOR'
2448 sn.procid(i,j) = ProcessType.PRIOR;
2449 otherwise
2450 % Unknown ProcessType - default to DISABLED
2451 sn.procid(i,j) = ProcessType.DISABLED;
2452 end
2453 end
2454 end
2455 else
2456 sn.procid = [];
2457 end
2458
2459 if ~isempty(jsn.mu)
2460 sn.mu = cell(sn.nstations, 1);
2461 for i = 1:sn.nstations
2462 sn.mu{i} = cell(1, sn.nclasses);
2463 for j = 1:sn.nclasses
2464 sn.mu{i}{j} = JLINE.from_jline_matrix(jsn.mu.get(jstations.get(i-1)).get(jclasses.get(j-1)));
2465 end
2466 end
2467 else
2468 sn.mu = {};
2469 end
2470
2471 if ~isempty(jsn.phi)
2472 sn.phi = cell(sn.nstations, 1);
2473 for i = 1:sn.nstations
2474 sn.phi{i} = cell(1, sn.nclasses);
2475 for j = 1:sn.nclasses
2476 sn.phi{i}{j} = JLINE.from_jline_matrix(jsn.phi.get(jstations.get(i-1)).get(jclasses.get(j-1)));
2477 end
2478 end
2479 else
2480 sn.phi = {};
2481 end
2482
2483 if ~isempty(jsn.proc)
2484 sn.proc = cell(sn.nstations, 1);
2485 for i = 1:sn.nstations
2486 sn.proc{i} = cell(1, sn.nclasses);
2487 for j = 1:sn.nclasses
2488 proc_i_j = jsn.proc.get(jstations.get(i-1)).get(jclasses.get(j-1));
2489 sn.proc{i}{j} = cell(1, proc_i_j.size);
2490 for k = 1:proc_i_j.size
2491 sn.proc{i}{j}{k} = JLINE.from_jline_matrix(proc_i_j.get(uint32(k-1)));
2492 end
2493 end
2494 end
2495 else
2496 sn.proc = {};
2497 end
2498
2499 if ~isempty(jsn.pie)
2500 sn.pie = cell(sn.nstations, 1);
2501 for i = 1:sn.nstations
2502 sn.pie{i} = cell(1, sn.nclasses);
2503 for j = 1:sn.nclasses
2504 sn.pie{i}{j} = JLINE.from_jline_matrix(jsn.pie.get(jstations.get(i-1)).get(jclasses.get(j-1)));
2505 end
2506 end
2507 else
2508 sn.pie = {};
2509 end
2510
2511 if ~isempty(jsn.sched)
2512 sn.sched = zeros(sn.nstations, 1);
2513 for i = 1:sn.nstations
2514 schedStrategy = jsn.sched.get(jstations.get(i-1));
2515 switch schedStrategy.name.toCharArray'
2516 case 'INF'
2517 sn.sched(i) = SchedStrategy.INF;
2518 case 'FCFS'
2519 sn.sched(i) = SchedStrategy.FCFS;
2520 case 'LCFS'
2521 sn.sched(i) = SchedStrategy.LCFS;
2522 case 'LCFSPR'
2523 sn.sched(i) = SchedStrategy.LCFSPR;
2524 case 'SIRO'
2525 sn.sched(i) = SchedStrategy.SIRO;
2526 case 'SJF'
2527 sn.sched(i) = SchedStrategy.SJF;
2528 case 'LJF'
2529 sn.sched(i) = SchedStrategy.LJF;
2530 case 'PS'
2531 sn.sched(i) = SchedStrategy.PS;
2532 case 'DPS'
2533 sn.sched(i) = SchedStrategy.DPS;
2534 case 'GPS'
2535 sn.sched(i) = SchedStrategy.GPS;
2536 case 'PSPRIO'
2537 sn.sched(i) = SchedStrategy.PSPRIO;
2538 case 'DPSPRIO'
2539 sn.sched(i) = SchedStrategy.DPSPRIO;
2540 case 'GPSPRIO'
2541 sn.sched(i) = SchedStrategy.GPSPRIO;
2542 case 'SEPT'
2543 sn.sched(i) = SchedStrategy.SEPT;
2544 case 'LEPT'
2545 sn.sched(i) = SchedStrategy.LEPT;
2546 case {'HOL', 'FCFSPRIO'}
2547 sn.sched(i) = SchedStrategy.FCFSPRIO;
2548 case 'FORK'
2549 sn.sched(i) = SchedStrategy.FORK;
2550 case 'EXT'
2551 sn.sched(i) = SchedStrategy.EXT;
2552 case 'REF'
2553 sn.sched(i) = SchedStrategy.REF;
2554 end
2555 end
2556 else
2557 sn.sched = [];
2558 end
2559
2560 if ~isempty(jsn.inchain)
2561 sn.inchain = cell(1, sn.nchains);
2562 for i = 1:sn.nchains
2563 sn.inchain{1,i} = JLINE.from_jline_matrix(jsn.inchain.get(uint32(i-1)))+1;
2564 end
2565 else
2566 sn.inchain = {};
2567 end
2568
2569 if ~isempty(jsn.visits)
2570 sn.visits = cell(sn.nchains, 1);
2571 for i = 1:sn.nchains
2572 sn.visits{i,1} = JLINE.from_jline_matrix(jsn.visits.get(uint32(i-1)));
2573 end
2574 else
2575 sn.visits = {};
2576 end
2577
2578 if ~isempty(jsn.nodevisits)
2579 sn.nodevisits = cell(1, sn.nchains);
2580 for i = 1:sn.nchains
2581 sn.nodevisits{1,i} = JLINE.from_jline_matrix(jsn.nodevisits.get(uint32(i-1)));
2582 end
2583 else
2584 sn.nodevisits = {};
2585 end
2586
2587 if ~isempty(jsn.droprule)
2588 sn.droprule = zeros(sn.nstations, sn.nclasses);
2589 for i = 1:sn.nstations
2590 for j = 1:sn.nclasses
2591 dropStrategy = jsn.droprule.get(jstations.get(i-1)).get(jclasses.get(j-1));
2592 switch dropStrategy.name.toCharArray'
2593 case 'WaitingQueue'
2594 sn.droprule(i,j) = DropStrategy.WAITQ;
2595 case 'Drop'
2596 sn.droprule(i,j) = DropStrategy.DROP;
2597 case 'BlockingAfterService'
2598 sn.droprule(i,j) = DropStrategy.BAS;
2599 end
2600 end
2601 end
2602 else
2603 sn.droprule = [];
2604 end
2605
2606 if ~isempty(jsn.nodeparam)
2607 sn.nodeparam = cell(sn.nnodes, 1);
2608
2609 for i = 1:sn.nnodes
2610 jnode = jnodes.get(i-1);
2611 jparam = jsn.nodeparam.get(jnode);
2612
2613 %if jparam.isEmpty
2614 % sn.nodeparam{i} = [];
2615 % continue;
2616 %end
2617
2618 % StationNodeParam
2619 if isa(jparam, 'jline.lang.nodeparam.StationNodeParam')
2620 if ~isempty(jparam.fileName)
2621 sn.nodeparam{i}.fileName = cell(1, sn.nclasses);
2622 for r = 1:sn.nclasses
2623 fname = jparam.fileName.get(r-1);
2624 if ~isempty(fname)
2625 sn.nodeparam{i}.fileName{r} = char(fname);
2626 end
2627 end
2628 end
2629 end
2630
2631 % TransitionNodeParam
2632 if isa(jparam, 'jline.lang.nodeparam.TransitionNodeParam')
2633 if ~isempty(jparam.firingprocid)
2634 sn.nodeparam{i}.firingprocid = containers.Map('KeyType', 'char', 'ValueType', 'any');
2635 keys = jparam.firingprocid.keySet.iterator;
2636 while keys.hasNext
2637 key = keys.next;
2638 proc = jparam.firingprocid.get(key);
2639 sn.nodeparam{i}.firingprocid(char(key.toString)) = char(proc.toString);
2640 end
2641 end
2642 if ~isempty(jparam.firingphases)
2643 sn.nodeparam{i}.firingphases = JLINE.from_jline_matrix(jparam.firingphases);
2644 end
2645 if ~isempty(jparam.fireweight)
2646 sn.nodeparam{i}.fireweight = JLINE.from_jline_matrix(jparam.fireweight);
2647 end
2648 end
2649
2650 % JoinNodeParam
2651 if isa(jparam, 'jline.lang.nodeparam.JoinNodeParam')
2652 if ~isempty(jparam.joinStrategy)
2653 sn.nodeparam{i}.joinStrategy = cell(1, sn.nclasses);
2654 sn.nodeparam{i}.fanIn = cell(1, sn.nclasses);
2655 for r = 1:sn.nclasses
2656 jclass = jclasses.get(r-1);
2657 joinStrategy = jparam.joinStrategy.get(jclass);
2658 if ~isempty(joinStrategy)
2659 strategyStr = char(joinStrategy.name.toString);
2660 switch strategyStr
2661 case 'STD'
2662 sn.nodeparam{i}.joinStrategy{r} = JoinStrategy.STD;
2663 case 'PARTIAL'
2664 sn.nodeparam{i}.joinStrategy{r} = JoinStrategy.PARTIAL;
2665 otherwise
2666 sn.nodeparam{i}.joinStrategy{r} = strategyStr;
2667 end
2668 sn.nodeparam{i}.fanIn{r} = jparam.fanIn.get(jclass);
2669 end
2670 end
2671 end
2672 end
2673
2674 % RoutingNodeParam
2675 if isa(jparam, 'jline.lang.nodeparam.RoutingNodeParam')
2676 for r = 1:sn.nclasses
2677 jclass = jclasses.get(r-1);
2678
2679 if ~isempty(jparam.weights) && jparam.weights.containsKey(jclass)
2680 sn.nodeparam{i}.weights{r} = JLINE.from_jline_matrix(jparam.weights.get(jclass));
2681 end
2682
2683 if ~isempty(jparam.outlinks) && jparam.outlinks.containsKey(jclass)
2684 sn.nodeparam{i}.outlinks{r} = JLINE.from_jline_matrix(jparam.outlinks.get(jclass));
2685 end
2686 end
2687 end
2688
2689 % ForkNodeParam
2690 if isa(jparam, 'jline.lang.nodeparam.ForkNodeParam')
2691 if ~isnan(jparam.fanOut)
2692 sn.nodeparam{i}.fanOut = jparam.fanOut;
2693 end
2694 end
2695
2696 % CacheNodeParam
2697 if isa(jparam, 'jline.lang.nodeparam.CacheNodeParam')
2698 % nitems
2699 if ~isnan(jparam.nitems)
2700 sn.nodeparam{i}.nitems = jparam.nitems;
2701 end
2702
2703 % accost
2704 if ~isempty(jparam.accost)
2705 % For Java 2D arrays (Matrix[][]), size(arr,2) returns 1 in MATLAB
2706 % We need to get length of first row to get actual second dimension
2707 K1 = size(jparam.accost, 1);
2708 if K1 > 0
2709 firstRow = jparam.accost(1); % Get first row (Java array)
2710 K2 = length(firstRow);
2711 else
2712 K2 = 0;
2713 end
2714 sn.nodeparam{i}.accost = cell(K1, K2);
2715 for k1 = 1:K1
2716 for k2 = 1:K2
2717 mat = jparam.accost(k1, k2); % MATLAB handles Java array indexing
2718 if ~isempty(mat)
2719 sn.nodeparam{i}.accost{k1, k2} = JLINE.from_jline_matrix(mat);
2720 end
2721 end
2722 end
2723 end
2724
2725 % itemcap
2726 if ~isempty(jparam.itemcap)
2727 sn.nodeparam{i}.itemcap = JLINE.from_jline_matrix(jparam.itemcap);
2728 end
2729
2730 % pread - convert from Java Map<Integer, List<Double>> to MATLAB cell array {R}
2731 if ~isempty(jparam.pread)
2732 nclasses = sn.nclasses;
2733 sn.nodeparam{i}.pread = cell(1, nclasses);
2734 for r = 1:nclasses
2735 list = jparam.pread.get(int32(r-1)); % Java 0-based indexing
2736 if ~isempty(list)
2737 values = zeros(1, list.size);
2738 for j = 1:list.size
2739 values(j) = list.get(j-1);
2740 end
2741 sn.nodeparam{i}.pread{r} = values;
2742 else
2743 sn.nodeparam{i}.pread{r} = NaN;
2744 end
2745 end
2746 end
2747
2748 % replacestrat
2749 if ~isempty(jparam.replacestrat)
2750 switch char(jparam.replacestrat)
2751 case 'RR'
2752 sn.nodeparam{i}.replacestrat = ReplacementStrategy.RR;
2753 case 'FIFO'
2754 sn.nodeparam{i}.replacestrat = ReplacementStrategy.FIFO;
2755 case 'SFIFO'
2756 sn.nodeparam{i}.replacestrat = ReplacementStrategy.SFIFO;
2757 case 'LRU'
2758 sn.nodeparam{i}.replacestrat = ReplacementStrategy.LRU;
2759 end
2760 end
2761
2762 % hitclass
2763 if ~isempty(jparam.hitclass)
2764 sn.nodeparam{i}.hitclass = 1+JLINE.from_jline_matrix(jparam.hitclass);
2765 end
2766
2767 % missclass
2768 if ~isempty(jparam.missclass)
2769 sn.nodeparam{i}.missclass =1+ JLINE.from_jline_matrix(jparam.missclass);
2770 end
2771
2772 % actual hit/miss probabilities
2773 if ~isempty(jparam.actualhitprob)
2774 sn.nodeparam{i}.actualhitprob = JLINE.from_jline_matrix(jparam.actualhitprob);
2775 end
2776 if ~isempty(jparam.actualmissprob)
2777 sn.nodeparam{i}.actualmissprob = JLINE.from_jline_matrix(jparam.actualmissprob);
2778 end
2779 end
2780 end
2781 else
2782 sn.nodeparam = {};
2783 end
2784
2785 % if ~isempty(jsn.nodeparam)
2786 % sn.nodeparam = cell(sn.nnodes, 1);
2787 % % Note that JLINE only support node parameters related to
2788 % % Fork, Join, WWROBIN and RROBIN
2789 % for i = 1:sn.nnodes
2790 % if jsn.nodeparam.get(jnodes.get(i-1)).isEmpty
2791 % sn.nodeparam{i} = [];
2792 % else
2793 % if ~isnan(jsn.nodeparam.get(jnodes.get(i-1)).nitems)
2794 % sn.nodeparam{i}.nitems = jsn.nodeparam.get(jnodes.get(i-1)).nitems;
2795 % end
2796 % if ~isnan(jsn.nodeparam.get(jnodes.get(i-1)).fanOut)
2797 % sn.nodeparam{i}.fanOut = jsn.nodeparam.get(jnodes.get(i-1)).fanOut;
2798 % end
2799 % if ~isempty(jsn.nodeparam.get(jnodes.get(i-1)).joinStrategy)
2800 % if ~jsn.nodeparam.get(jnodes.get(i-1)).joinStrategy.isEmpty
2801 % sn.nodeparam{i}.joinStrategy = cell(1, sn.nclasses);
2802 % sn.nodeparam{i}.fanIn = cell(1, sn.nclasses);
2803 % for r = 1:sn.nclasses
2804 % joinStrategy = jsn.nodeparam.get(jnodes.get(i-1)).joinStrategy.get(jclasses.get(r-1));
2805 % switch joinStrategy.name.toCharArray'
2806 % case 'STD'
2807 % sn.nodeparam{i}.joinStrategy{r} = JoinStrategy.STD;
2808 % case 'PARTIAL'
2809 % sn.nodeparam{i}.joinStrategy{r} = JoinStrategy.PARTIAL;
2810 % end
2811 % sn.nodeparam{i}.fanIn{r} = jsn.nodeparam.get(jnodes.get(i-1)).fanIn.get(jclasses.get(r-1));
2812 % end
2813 % end
2814 % end
2815 %
2816 % if ~isempty(jsn.nodeparam.get(jnodes.get(i-1)).weights)
2817 % for r = 1:sn.nclasses
2818 % sn.nodeparam{i}{r}.weights = JLINE.from_jline_matrix(jsn.nodeparam.get(jnodes.get(i-1)).weights.get(jclasses.get(r-1)));
2819 % end
2820 % end
2821 %
2822 % if ~isempty(jsn.nodeparam.get(jnodes.get(i-1)).outlinks)
2823 % for r = 1:sn.nclasses
2824 % sn.nodeparam{i}{r}.outlinks = JLINE.from_jline_matrix(jsn.nodeparam.get(jnodes.get(i-1)).outlinks.get(jclasses.get(r-1)));
2825 % end
2826 % end
2827 % end
2828 % end
2829 % else
2830 % sn.nodeparam = {};
2831 % end
2832
2833 if ~isempty(jsn.sync)
2834 jsync = jsn.sync;
2835 sn.sync = cell(jsync.size, 1);
2836 for i = 1:jsync.size
2837 jsync_i = jsync.get(uint32(i-1));
2838 sn.sync{i,1} = struct('active',cell(1),'passive',cell(1));
2839
2840 jactive = jsync_i.active.get(uint32(0));
2841 jpassive = jsync_i.passive.get(uint32(0));
2842
2843 %Currently assume that prob would always be a value
2844 %instead of lambda function (No idea of how to convert
2845 %Java lambda function to matlab lambda function)
2846 switch jactive.getEvent.name.toCharArray'
2847 case 'INIT'
2848 sn.sync{i,1}.active{1} = Event(EventType.INIT, jactive.getNode+1, jactive.getJobClass+1, ...
2849 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2850 jactive.getT, jactive.getJob);
2851 case 'LOCAL'
2852 sn.sync{i,1}.active{1} = Event(EventType.LOCAL, jactive.getNode+1, jactive.getJobClass+1, ...
2853 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2854 jactive.getT, jactive.getJob);
2855 case 'ARV'
2856 sn.sync{i,1}.active{1} = Event(EventType.ARV, jactive.getNode+1, jactive.getJobClass+1, ...
2857 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2858 jactive.getT, jactive.getJob);
2859 case 'DEP'
2860 sn.sync{i,1}.active{1} = Event(EventType.DEP, jactive.getNode+1, jactive.getJobClass+1, ...
2861 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2862 jactive.getT, jactive.getJob);
2863 case 'PHASE'
2864 sn.sync{i,1}.active{1} = Event(EventType.PHASE, jactive.getNode+1, jactive.getJobClass+1, ...
2865 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2866 jactive.getT, jactive.getJob);
2867 case 'READ'
2868 sn.sync{i,1}.active{1} = Event(EventType.READ, jactive.getNode+1, jactive.getJobClass+1, ...
2869 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2870 jactive.getT, jactive.getJob);
2871 case 'STAGE'
2872 sn.sync{i,1}.active{1} = Event(EventType.STAGE, jactive.getNode+1, jactive.getJobClass+1, ...
2873 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2874 jactive.getT, jactive.getJob);
2875 end
2876
2877 switch jpassive.getEvent.name.toCharArray'
2878 case 'INIT'
2879 sn.sync{i,1}.passive{1} = Event(EventType.INIT, jpassive.getNode+1, jpassive.getJobClass+1, ...
2880 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2881 jpassive.getT, jpassive.getJob);
2882 case 'LOCAL'
2883 sn.sync{i,1}.passive{1} = Event(EventType.LOCAL, jpassive.getNode+1, jpassive.getJobClass+1, ...
2884 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2885 jpassive.getT, jpassive.getJob);
2886 case 'ARV'
2887 sn.sync{i,1}.passive{1} = Event(EventType.ARV, jpassive.getNode+1, jpassive.getJobClass+1, ...
2888 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2889 jpassive.getT, jpassive.getJob);
2890 case 'DEP'
2891 sn.sync{i,1}.passive{1} = Event(EventType.DEP, jpassive.getNode+1, jpassive.getJobClass+1, ...
2892 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2893 jpassive.getT, jpassive.getJob);
2894 case 'PHASE'
2895 sn.sync{i,1}.passive{1} = Event(EventType.PHASE, jpassive.getNode+1, jpassive.getJobClass+1, ...
2896 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2897 jpassive.getT, jpassive.getJob);
2898 case 'READ'
2899 sn.sync{i,1}.passive{1} = Event(EventType.READ, jpassive.getNode+1, jpassive.getJobClass+1, ...
2900 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2901 jpassive.getT, jpassive.getJob);
2902 case 'STAGE'
2903 sn.sync{i,1}.passive{1} = Event(EventType.STAGE, jpassive.getNode+1, jpassive.getJobClass+1, ...
2904 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2905 jpassive.getT, jpassive.getJob);
2906 end
2907 end
2908 else
2909 sn.sync = {};
2910 end
2911 end
2912
2913 function [QN,UN,RN,WN,AN,TN] = arrayListToResults(alist)
2914 switch class(alist)
2915 case 'jline.solvers.LayeredNetworkAvgTable'
2916 QN = JLINE.arraylist_to_matrix(alist.getQLen());
2917 UN = JLINE.arraylist_to_matrix(alist.getUtil());
2918 RN = JLINE.arraylist_to_matrix(alist.getRespT());
2919 WN = JLINE.arraylist_to_matrix(alist.getResidT());
2920 AN = NaN*JLINE.arraylist_to_matrix(alist.getTput()); % getArvR not yet available in JLINE
2921 TN = JLINE.arraylist_to_matrix(alist.getTput());
2922 otherwise
2923 QN = JLINE.arraylist_to_matrix(alist.getQLen());
2924 UN = JLINE.arraylist_to_matrix(alist.getUtil());
2925 RN = JLINE.arraylist_to_matrix(alist.getRespT());
2926 WN = JLINE.arraylist_to_matrix(alist.getResidT());
2927 AN = JLINE.arraylist_to_matrix(alist.getArvR());
2928 TN = JLINE.arraylist_to_matrix(alist.getTput());
2929 end
2930 end
2931
2932 function featSupported = getFeatureSet()
2933 % FEATSUPPORTED = GETFEATURESET()
2934
2935 featSupported = SolverFeatureSet;
2936 featSupported.setTrue({'Sink','Source',...
2937 'ClassSwitch','Delay','DelayStation','Queue',...
2938 'APH','Coxian','Erlang','Exp','HyperExp',...
2939 'StatelessClassSwitcher','InfiniteServer','SharedServer','Buffer','Dispatcher',...
2940 'Server','JobSink','RandomSource','ServiceTunnel',...
2941 'SchedStrategy_INF','SchedStrategy_PS',...
2942 'RoutingStrategy_PROB','RoutingStrategy_RAND',...
2943 'ClosedClass','OpenClass'});
2944 end
2945
2946 function [bool, featSupported] = supports(model)
2947 % [BOOL, FEATSUPPORTED] = SUPPORTS(MODEL)
2948
2949 featUsed = model.getUsedLangFeatures();
2950 featSupported = JLINE.getFeatureSet();
2951 bool = SolverFeatureSet.supports(featSupported, featUsed);
2952 end
2953
2954
2955 function solverOptions = parseSolverOptions(solverOptions, options)
2956 fn = fieldnames(options);
2957 fn2 = fieldnames(solverOptions);
2958 for f = 1:length(fn)
2959 found = 0;
2960 for j = 1:length(fn2)
2961 if strcmp(fn{f}, fn2{j})
2962 found = 1;
2963 switch fn{f}
2964 case 'seed'
2965 solverOptions.seed = options.seed;
2966 case 'samples'
2967 solverOptions.samples = options.samples;
2968 case 'confint'
2969 % Parse confint - can be a level (0.95) or 0 to disable
2970 [confintEnabled, confintLevel] = Solver.parseConfInt(options.confint);
2971 if confintEnabled
2972 solverOptions.confint = confintLevel;
2973 else
2974 solverOptions.confint = 0;
2975 end
2976 case 'method'
2977 solverOptions.method = options.method;
2978 case 'config'
2979 if isfield(options.config,'eventcache')
2980 solverOptions.config.eventcache = options.config.eventcache;
2981 end
2982 if isfield(options.config,'fork_join')
2983 solverOptions.config.fork_join = options.config.fork_join;
2984 end
2985 if isfield(options.config,'highvar')
2986 solverOptions.config.highvar = options.config.highvar;
2987 end
2988 if isfield(options.config,'multiserver')
2989 solverOptions.config.multiserver = options.config.multiserver;
2990 end
2991 if isfield(options.config,'np_priority')
2992 solverOptions.config.np_priority = options.config.np_priority;
2993 end
2994 case 'verbose'
2995 switch options.(fn{f})
2996 case {VerboseLevel.SILENT}
2997 solverOptions.verbose = solverOptions.verbose.SILENT;
2998 case {VerboseLevel.STD}
2999 solverOptions.verbose = solverOptions.verbose.STD;
3000 case {VerboseLevel.DEBUG}
3001 solverOptions.verbose = solverOptions.verbose.DEBUG;
3002 end
3003 case 'init_sol'
3004 solverOptions.(fn{f}) = JLINE.from_line_matrix(options.init_sol);
3005 case 'cutoff'
3006 if isscalar(options.cutoff)
3007 solverOptions.(fn{f}) = jline.util.matrix.Matrix.singleton(options.cutoff);
3008 else
3009 solverOptions.(fn{f}) = JLINE.from_line_matrix(options.cutoff);
3010 end
3011 case 'odesolvers'
3012 case 'rewardIterations'
3013 solverOptions.rewardIterations = java.lang.Integer(options.rewardIterations);
3014 otherwise
3015 solverOptions.(fn{f}) = options.(fn{f});
3016 end
3017
3018 break;
3019 end
3020 end
3021 if ~found
3022 line_printf('Could not find option %s in the JLINE options.\n', fn{f});
3023 end
3024 end
3025 end
3026
3027 function [ssa] = SolverSSA(network_object, options)
3028 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.SSA);
3029 if nargin>1
3030 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3031 end
3032 jline.util.Maths.setRandomNumbersMatlab(true);
3033 ssa = jline.solvers.ssa.SolverSSA(network_object, solverOptions);
3034 end
3035
3036 function [qns] = SolverQNS(network_object, options)
3037 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.QNS);
3038 if nargin>1
3039 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3040 end
3041 qns = jline.solvers.qns.SolverQNS(network_object, solverOptions);
3042 end
3043
3044 function [mam] = SolverMAM(network_object, options)
3045 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.MAM);
3046 if nargin>1
3047 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3048 end
3049 mam = jline.solvers.mam.SolverMAM(network_object, solverOptions);
3050 end
3051
3052 function [jmt] = SolverJMT(network_object, options)
3053 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.JMT);
3054 if nargin>1
3055 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3056 end
3057 jmt = jline.solvers.jmt.SolverJMT(network_object, solverOptions);
3058 end
3059
3060 function [ctmc] = SolverCTMC(network_object, options)
3061 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.CTMC);
3062 if nargin>1
3063 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3064 end
3065 ctmc = jline.solvers.ctmc.SolverCTMC(network_object,solverOptions);
3066 end
3067
3068 function [fluid] = SolverFluid(network_object, options)
3069 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.FLUID);
3070 if nargin>1
3071 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3072 end
3073 fluid = jline.solvers.fluid.SolverFluid(network_object, solverOptions);
3074 end
3075
3076 function [QN, UN, RN, TN, CN, XN, t, QNt, UNt, TNt, xvec] = runFluidAnalyzer(network, options)
3077 % RUNFLUIDANALYZER Run JLINE fluid analyzer and return results
3078 %
3079 % [QN, UN, RN, TN, CN, XN, T, QNT, UNT, TNT, XVEC] = JLINE.runFluidAnalyzer(NETWORK, OPTIONS)
3080 %
3081 % Runs the JLINE fluid solver on the given network and converts
3082 % results back to MATLAB data structures.
3083 %
3084 % Input:
3085 % network - LINE Network model
3086 % options - Solver options structure with fields:
3087 % .method - solver method
3088 % .stiff - use stiff ODE solver
3089 %
3090 % Output:
3091 % QN, UN, RN, TN - Steady-state metrics [M x K]
3092 % CN, XN - System metrics [1 x K]
3093 % t - Time vector [Tmax x 1]
3094 % QNt, UNt, TNt - Transient metrics {M x K} cells
3095 % xvec - State vector structure
3096
3097 jmodel = LINE2JLINE(network);
3098 jsolver = JLINE.SolverFluid(jmodel);
3099 import jline.solvers.fluid.*;
3100
3101 jsolver.options.method = options.method;
3102 jsolver.options.stiff = options.stiff;
3103 result = jsolver.runMethodSpecificAnalyzerViaLINE();
3104
3105 % Convert JLINE result to MATLAB data structures
3106 M = jmodel.getNumberOfStatefulNodes();
3107 K = jmodel.getNumberOfClasses();
3108
3109 QN = NaN * zeros(M, K);
3110 UN = NaN * zeros(M, K);
3111 RN = NaN * zeros(M, K);
3112 TN = NaN * zeros(M, K);
3113 CN = NaN * zeros(1, K);
3114 XN = NaN * zeros(1, K);
3115
3116 QNt = cell(M, K);
3117 UNt = cell(M, K);
3118 TNt = cell(M, K);
3119
3120 Tmax = result.t.length();
3121 t = NaN * zeros(Tmax, 1);
3122
3123 for ist = 1:M
3124 for jst = 1:K
3125 QN(ist, jst) = result.QN.get(ist-1, jst-1);
3126 UN(ist, jst) = result.UN.get(ist-1, jst-1);
3127 RN(ist, jst) = result.RN.get(ist-1, jst-1);
3128 TN(ist, jst) = result.TN.get(ist-1, jst-1);
3129 end
3130 end
3131
3132 for jst = 1:K
3133 CN(1, jst) = result.CN.get(0, jst-1);
3134 XN(1, jst) = result.XN.get(0, jst-1);
3135 end
3136
3137 for ist = 1:M
3138 for jst = 1:K
3139 for p = 1:Tmax
3140 QNt{ist, jst}(p, 1) = result.QNt(ist, jst).get(p-1, 0);
3141 UNt{ist, jst}(p, 1) = result.UNt(ist, jst).get(p-1, 0);
3142 TNt{ist, jst}(p, 1) = result.TNt(ist, jst).get(p-1, 0);
3143 end
3144 end
3145 end
3146
3147 for p = 1:Tmax
3148 t(p, 1) = result.t.get(p-1, 0);
3149 end
3150
3151 % JLINE does not return odeStateVec
3152 xvec.odeStateVec = [];
3153 xvec.sn = network;
3154 end
3155
3156 function [ldes] = SolverLDES(network_object, options)
3157 % Create LDES-specific options object
3158 ldesOptions = jline.solvers.ldes.LDESOptions();
3159 if nargin>1
3160 % Copy standard options
3161 ldesOptions.samples = options.samples;
3162 ldesOptions.seed = options.seed;
3163 % Parse confint
3164 [confintEnabled, confintLevel] = Solver.parseConfInt(options.confint);
3165 if confintEnabled
3166 ldesOptions.confint = confintLevel;
3167 else
3168 ldesOptions.confint = 0;
3169 end
3170 % Pass timespan for transient analysis
3171 if isfield(options, 'timespan') && length(options.timespan) >= 2
3172 ldesOptions.timespan = options.timespan;
3173 end
3174 % Pass LDES-specific options if configured
3175 if isfield(options, 'config')
3176 % Transient detection options
3177 if isfield(options.config, 'tranfilter')
3178 ldesOptions.tranfilter = options.config.tranfilter;
3179 end
3180 if isfield(options.config, 'mserbatch')
3181 ldesOptions.mserbatch = options.config.mserbatch;
3182 end
3183 if isfield(options.config, 'warmupfrac')
3184 ldesOptions.warmupfrac = options.config.warmupfrac;
3185 end
3186 % Confidence interval options
3187 if isfield(options.config, 'cimethod')
3188 ldesOptions.cimethod = options.config.cimethod;
3189 end
3190 if isfield(options.config, 'obmoverlap')
3191 ldesOptions.obmoverlap = options.config.obmoverlap;
3192 end
3193 if isfield(options.config, 'ciminbatch')
3194 ldesOptions.ciminbatch = options.config.ciminbatch;
3195 end
3196 if isfield(options.config, 'ciminobs')
3197 ldesOptions.ciminobs = options.config.ciminobs;
3198 end
3199 if isfield(options.config, 'spectralLowFreqFrac')
3200 ldesOptions.spectralLowFreqFrac = options.config.spectralLowFreqFrac;
3201 end
3202 % Convergence options
3203 if isfield(options.config, 'cnvgon')
3204 ldesOptions.cnvgon = options.config.cnvgon;
3205 end
3206 if isfield(options.config, 'cnvgtol')
3207 ldesOptions.cnvgtol = options.config.cnvgtol;
3208 end
3209 if isfield(options.config, 'cnvgbatch')
3210 ldesOptions.cnvgbatch = options.config.cnvgbatch;
3211 end
3212 if isfield(options.config, 'cnvgchk')
3213 ldesOptions.cnvgchk = options.config.cnvgchk;
3214 end
3215 end
3216 end
3217 ldes = jline.solvers.ldes.SolverLDES(network_object, ldesOptions);
3218 end
3219
3220 function [mva] = SolverMVA(network_object, options)
3221 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.MVA);
3222 if nargin>1
3223 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3224 end
3225 mva = jline.solvers.mva.SolverMVA(network_object, solverOptions);
3226 end
3227
3228 function [nc] = SolverNC(network_object, options)
3229 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.NC);
3230 if nargin>1
3231 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3232 end
3233 nc = jline.solvers.nc.SolverNC(network_object, solverOptions);
3234 end
3235
3236 function [auto] = SolverAuto(network_object, options)
3237 solverOptions = jline.solvers.auto.AUTOptions();
3238 if nargin>1
3239 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3240 end
3241 auto = jline.solvers.auto.SolverAUTO(network_object, solverOptions);
3242 end
3243
3244 function streamOpts = StreamingOptions(varargin)
3245 % STREAMINGOPTIONS Create Java StreamingOptions for SSA/LDES stream() method
3246 %
3247 % @brief Creates StreamingOptions for streaming simulation metrics
3248 %
3249 % @param varargin Name-value pairs for options:
3250 % 'transport' - 'http' (recommended) or 'grpc' (default: 'http')
3251 % 'endpoint' - Receiver endpoint (default: 'localhost:8080/metrics' for HTTP)
3252 % 'mode' - 'sampled' or 'time_window' (default: 'sampled')
3253 % 'sampleFrequency' - Push every N events in sampled mode (default: 100)
3254 % 'timeWindowSeconds' - Window duration in time_window mode (default: 1.0)
3255 % 'serviceName' - Service identifier (default: 'line-stream')
3256 % 'includeQueueLength' - Include queue length metrics (default: true)
3257 % 'includeUtilization' - Include utilization metrics (default: true)
3258 % 'includeThroughput' - Include throughput metrics (default: true)
3259 % 'includeResponseTime' - Include response time metrics (default: true)
3260 % 'includeArrivalRate' - Include arrival rate metrics (default: true)
3261 %
3262 % @return streamOpts Java StreamingOptions object
3263 %
3264 % Example:
3265 % @code
3266 % streamOpts = JLINE.StreamingOptions('transport', 'http', 'sampleFrequency', 50);
3267 % @endcode
3268
3269 streamOpts = jline.streaming.StreamingOptions();
3270
3271 % Parse optional arguments
3272 p = inputParser;
3273 addParameter(p, 'transport', 'http', @ischar);
3274 addParameter(p, 'endpoint', '', @ischar); % Empty means use default for transport
3275 addParameter(p, 'mode', 'sampled', @ischar);
3276 addParameter(p, 'sampleFrequency', 100, @isnumeric);
3277 addParameter(p, 'timeWindowSeconds', 1.0, @isnumeric);
3278 addParameter(p, 'serviceName', 'line-stream', @ischar);
3279 addParameter(p, 'includeQueueLength', true, @islogical);
3280 addParameter(p, 'includeUtilization', true, @islogical);
3281 addParameter(p, 'includeThroughput', true, @islogical);
3282 addParameter(p, 'includeResponseTime', true, @islogical);
3283 addParameter(p, 'includeArrivalRate', true, @islogical);
3284 parse(p, varargin{:});
3285
3286 % Set transport type
3287 transportTypes = javaMethod('values', 'jline.streaming.StreamingOptions$TransportType');
3288 switch lower(p.Results.transport)
3289 case 'http'
3290 streamOpts.transport = transportTypes(1); % HTTP
3291 case 'grpc'
3292 streamOpts.transport = transportTypes(2); % GRPC
3293 otherwise
3294 streamOpts.transport = transportTypes(1); % Default to HTTP
3295 end
3296
3297 % Set endpoint (use provided or default based on transport)
3298 if ~isempty(p.Results.endpoint)
3299 streamOpts.endpoint = p.Results.endpoint;
3300 end
3301 % If empty, StreamingOptions uses its default for the transport type
3302
3303 % Set mode
3304 streamModes = javaMethod('values', 'jline.streaming.StreamingOptions$StreamMode');
3305 switch lower(p.Results.mode)
3306 case 'sampled'
3307 streamOpts.mode = streamModes(1); % SAMPLED
3308 case 'time_window'
3309 streamOpts.mode = streamModes(2); % TIME_WINDOW
3310 otherwise
3311 streamOpts.mode = streamModes(1); % Default to SAMPLED
3312 end
3313
3314 % Set other options
3315 streamOpts.sampleFrequency = p.Results.sampleFrequency;
3316 streamOpts.timeWindowSeconds = p.Results.timeWindowSeconds;
3317 streamOpts.serviceName = p.Results.serviceName;
3318 streamOpts.includeQueueLength = p.Results.includeQueueLength;
3319 streamOpts.includeUtilization = p.Results.includeUtilization;
3320 streamOpts.includeThroughput = p.Results.includeThroughput;
3321 streamOpts.includeResponseTime = p.Results.includeResponseTime;
3322 streamOpts.includeArrivalRate = p.Results.includeArrivalRate;
3323 end
3324
3325 function result = convertSampleResult(jresult)
3326 % CONVERTSAMPLERESULT Convert Java sample result to MATLAB struct
3327 %
3328 % @brief Converts Java SampleNodeState to MATLAB structure
3329 %
3330 % @param jresult Java SampleNodeState object
3331 % @return result MATLAB struct with fields: t, state, isaggregate
3332
3333 result = struct();
3334
3335 % Convert time matrix
3336 if ~isempty(jresult.t)
3337 result.t = JLINE.from_jline_matrix(jresult.t);
3338 else
3339 result.t = [];
3340 end
3341
3342 % Convert state matrix
3343 if ~isempty(jresult.state) && isa(jresult.state, 'jline.util.matrix.Matrix')
3344 result.state = JLINE.from_jline_matrix(jresult.state);
3345 else
3346 result.state = [];
3347 end
3348
3349 result.isaggregate = jresult.isaggregate;
3350 end
3351
3352 function [ln] = SolverLN(layered_network_object, options)
3353 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.LN);
3354 if nargin>1
3355 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3356 end
3357 ln = jline.solvers.ln.SolverLN(layered_network_object, solverOptions);
3358 end
3359
3360 function serfun = handle_to_serializablefun(handle, sn)
3361 % HANDLE_TO_SERIALIZABLEFUN Convert MATLAB function handle to Java SerializableFunction
3362 %
3363 % This function pre-computes the function values for all possible state
3364 % combinations and creates a Java PrecomputedCDFunction object.
3365 %
3366 % @param handle MATLAB function handle that takes a vector ni and returns a scalar
3367 % @param sn Network struct containing njobs (population per class)
3368 % @return serfun Java PrecomputedCDFunction object
3369
3370 % Get number of classes and maximum populations
3371 nclasses = sn.nclasses;
3372 njobs = sn.njobs; % Population per class
3373
3374 % For open classes (njobs=0), use a reasonable bound
3375 maxPop = njobs;
3376 for r = 1:nclasses
3377 if maxPop(r) == 0 || isinf(maxPop(r))
3378 % For open classes, use sum of closed class populations or 100 as bound
3379 maxPop(r) = max(100, sum(njobs(isfinite(njobs) & njobs > 0)));
3380 end
3381 end
3382
3383 % Create Java PrecomputedCDFunction object
3384 serfun = jline.util.PrecomputedCDFunction(nclasses);
3385
3386 % Enumerate all possible state combinations and pre-compute function values
3387 % Use recursive enumeration to handle arbitrary number of classes
3388 JLINE.enumerate_states(handle, serfun, maxPop, zeros(1, nclasses), 1);
3389 end
3390
3391 function enumerate_states(handle, serfun, maxPop, currentState, classIdx)
3392 % ENUMERATE_STATES Recursively enumerate all state combinations
3393 %
3394 % @param handle MATLAB function handle
3395 % @param serfun Java PrecomputedCDFunction object to populate
3396 % @param maxPop Maximum population per class
3397 % @param currentState Current state being built
3398 % @param classIdx Current class index being enumerated
3399
3400 nclasses = length(maxPop);
3401
3402 if classIdx > nclasses
3403 % We have a complete state, compute and store the function value
3404 try
3405 value = handle(currentState);
3406 % Convert to Java int array and add to serfun
3407 jstate = jline.util.matrix.Matrix(1, nclasses);
3408 for r = 1:nclasses
3409 jstate.set(0, r-1, currentState(r));
3410 end
3411 serfun.addValue(jstate, value);
3412 catch
3413 % If function evaluation fails, skip this state
3414 end
3415 return;
3416 end
3417
3418 % Enumerate all populations for current class
3419 for n = 0:maxPop(classIdx)
3420 currentState(classIdx) = n;
3421 JLINE.enumerate_states(handle, serfun, maxPop, currentState, classIdx + 1);
3422 end
3423 end
3424
3425 function result = call_java_cdscaling(jfun, ni)
3426 % CALL_JAVA_CDSCALING Call a Java SerializableFunction for class dependence
3427 %
3428 % This function converts a MATLAB vector to a Java Matrix and calls
3429 % the Java function's apply() method.
3430 %
3431 % @param jfun Java SerializableFunction<Matrix, Double> object
3432 % @param ni MATLAB vector representing the state (jobs per class)
3433 % @return result The scaling factor returned by the Java function
3434
3435 % Convert MATLAB vector to Java Matrix
3436 if isrow(ni)
3437 jmatrix = jline.util.matrix.Matrix(1, length(ni));
3438 for r = 1:length(ni)
3439 jmatrix.set(0, r-1, ni(r));
3440 end
3441 else
3442 jmatrix = jline.util.matrix.Matrix(length(ni), 1);
3443 for r = 1:length(ni)
3444 jmatrix.set(r-1, 0, ni(r));
3445 end
3446 end
3447
3448 % Call the Java function and convert result to MATLAB double
3449 jresult = jfun.apply(jmatrix);
3450 result = double(jresult);
3451 end
3452
3453 function jSched = to_jline_sched_strategy(schedId)
3454 % Convert MATLAB SchedStrategy id to jline SchedStrategy enum
3455 switch schedId
3456 case SchedStrategy.REF
3457 jSched = jline.lang.constant.SchedStrategy.REF;
3458 case SchedStrategy.INF
3459 jSched = jline.lang.constant.SchedStrategy.INF;
3460 case SchedStrategy.FCFS
3461 jSched = jline.lang.constant.SchedStrategy.FCFS;
3462 case SchedStrategy.LCFS
3463 jSched = jline.lang.constant.SchedStrategy.LCFS;
3464 case SchedStrategy.SIRO
3465 jSched = jline.lang.constant.SchedStrategy.SIRO;
3466 case SchedStrategy.SJF
3467 jSched = jline.lang.constant.SchedStrategy.SJF;
3468 case SchedStrategy.LJF
3469 jSched = jline.lang.constant.SchedStrategy.LJF;
3470 case SchedStrategy.PS
3471 jSched = jline.lang.constant.SchedStrategy.PS;
3472 case SchedStrategy.DPS
3473 jSched = jline.lang.constant.SchedStrategy.DPS;
3474 case SchedStrategy.GPS
3475 jSched = jline.lang.constant.SchedStrategy.GPS;
3476 case SchedStrategy.SEPT
3477 jSched = jline.lang.constant.SchedStrategy.SEPT;
3478 case SchedStrategy.LEPT
3479 jSched = jline.lang.constant.SchedStrategy.LEPT;
3480 case {SchedStrategy.HOL, SchedStrategy.FCFSPRIO}
3481 jSched = jline.lang.constant.SchedStrategy.FCFSPRIO;
3482 case SchedStrategy.FORK
3483 jSched = jline.lang.constant.SchedStrategy.FORK;
3484 case SchedStrategy.EXT
3485 jSched = jline.lang.constant.SchedStrategy.EXT;
3486 case SchedStrategy.LCFSPR
3487 jSched = jline.lang.constant.SchedStrategy.LCFSPR;
3488 case SchedStrategy.PSPRIO
3489 jSched = jline.lang.constant.SchedStrategy.PSPRIO;
3490 case SchedStrategy.DPSPRIO
3491 jSched = jline.lang.constant.SchedStrategy.DPSPRIO;
3492 case SchedStrategy.GPSPRIO
3493 jSched = jline.lang.constant.SchedStrategy.GPSPRIO;
3494 otherwise
3495 jSched = jline.lang.constant.SchedStrategy.FCFS;
3496 end
3497 end
3498
3499 function jwf = from_line_workflow(line_wf)
3500 % Convert a MATLAB Workflow to a JAR Workflow.
3501 jwf = javaObject('jline.lang.workflow.Workflow', java.lang.String(line_wf.getName()));
3502 acts = line_wf.activities;
3503 for a = 1:length(acts)
3504 act = acts{a};
3505 actName = java.lang.String(act.name);
3506 if ~isempty(act.hostDemand) && isa(act.hostDemand, 'Distribution')
3507 jdist = JLINE.from_line_distribution(act.hostDemand);
3508 jwf.addActivity(actName, jdist);
3509 else
3510 jwf.addActivity(actName, 1.0);
3511 end
3512 end
3513 precs = line_wf.precedences;
3514 for p = 1:length(precs)
3515 prec = precs(p);
3516 preActs = java.util.ArrayList();
3517 for k = 1:length(prec.preActs)
3518 preActs.add(java.lang.String(prec.preActs{k}));
3519 end
3520 postActs = java.util.ArrayList();
3521 for k = 1:length(prec.postActs)
3522 postActs.add(java.lang.String(prec.postActs{k}));
3523 end
3524 preTypeStr = java.lang.String(ActivityPrecedenceType.toText(prec.preType));
3525 postTypeStr = java.lang.String(ActivityPrecedenceType.toText(prec.postType));
3526 if ~isempty(prec.preParams)
3527 preParamsMat = JLINE.from_line_matrix(prec.preParams(:)');
3528 else
3529 preParamsMat = javaObject('jline.util.matrix.Matrix', 0, 0);
3530 end
3531 if ~isempty(prec.postParams)
3532 postParamsMat = JLINE.from_line_matrix(prec.postParams(:)');
3533 else
3534 postParamsMat = javaObject('jline.util.matrix.Matrix', 0, 0);
3535 end
3536 jprec = javaObject('jline.lang.layered.ActivityPrecedence', ...
3537 preActs, postActs, preTypeStr, postTypeStr, preParamsMat, postParamsMat);
3538 jwf.addPrecedence(jprec);
3539 end
3540 end
3541
3542 function jenv = from_line_environment(line_env)
3543 % Convert a MATLAB Environment to a JAR Environment.
3544 E = height(line_env.envGraph.Nodes);
3545 jenv = javaObject('jline.lang.Environment', java.lang.String(line_env.getName()), int32(E));
3546 for e = 1:E
3547 stageName = char(line_env.envGraph.Nodes.Name{e});
3548 stageType = char(line_env.envGraph.Nodes.Type{e});
3549 stageModel = line_env.ensemble{e};
3550 jmodel = JLINE.from_line_network(stageModel);
3551 jenv.addStage(int32(e-1), java.lang.String(stageName), java.lang.String(stageType), jmodel);
3552 end
3553 if ~isempty(line_env.env)
3554 [Erows, Ecols] = size(line_env.env);
3555 for e = 1:Erows
3556 for h = 1:Ecols
3557 d = line_env.env{e,h};
3558 if isempty(d) || isa(d, 'Disabled')
3559 continue;
3560 end
3561 jdist = JLINE.from_line_distribution(d);
3562 jenv.addTransition(int32(e-1), int32(h-1), jdist);
3563 end
3564 end
3565 end
3566 jenv.init();
3567 end
3568
3569 end
3570end
Definition mmt.m:124