2 % JLINE Conversion utilities
for JLINE format models
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.
8 % @brief JLINE format conversion and Java interoperability utilities
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
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');
25 jar_loc = which(
'jline.jar');
30 function model = from_line_layered_network(line_layered_network)
31 sn = line_layered_network.getStruct;
34 model = javaObject(
'jline.lang.layered.LayeredNetwork', line_layered_network.getName);
37 P = cell(1,sn.nhosts);
40 sn_mult_h = java.lang.Integer.MAX_VALUE;
42 sn_mult_h = sn.mult(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);
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);
93 P{h}.setReplication(sn.repl(h));
98 T = cell(1,sn.ntasks);
101 if isinf(sn.mult(tidx))
102 sn_mult_tidx = java.lang.Integer.MAX_VALUE;
104 sn_mult_tidx = sn.mult(tidx);
106 % Check
if this is a CacheTask
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;
119 jReplacestrat = jline.lang.constant.ReplacementStrategy.FIFO;
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);
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);
130 T{t}.on(
P{sn.parent(tidx)});
132 T{t}.setReplication(sn.repl(tidx));
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);
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)));
146 T{t}.setThinkTime(jline.lang.processes.HyperExp.fitMeanAndSCV(sn.think_mean(tidx), sn.think_scv(tidx)));
148 case ProcessType.COXIAN
149 T{t}.setThinkTime(jline.lang.processes.Coxian.fitMeanAndSCV(sn.think_mean(tidx), sn.think_scv(tidx)));
151 T{t}.setThinkTime(jline.lang.processes.APH.fitMeanAndSCV(sn.think_mean(tidx), sn.think_scv(tidx)));
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})));
157 T{t}.setThinkTime(jline.lang.processes.Exp(1/sn.think_mean(tidx)));
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})));
164 T{t}.setThinkTime(jline.lang.processes.Exp(1/sn.think_mean(tidx)));
167 line_error(mfilename,sprintf(
'JLINE conversion does not support the %s distribution for task think time yet.',
char(sn.think_type(tidx))));
171 if sn.isfunction(tidx) && ~isnan(sn.setuptime_mean(tidx)) && sn.setuptime_mean(tidx) > 1e-8
172 T{t}.setSetupTime(sn.setuptime_mean(tidx));
175 if sn.isfunction(tidx) && ~isnan(sn.delayofftime_mean(tidx)) && sn.delayofftime_mean(tidx) > 1e-8
176 T{t}.setDelayOffTime(sn.delayofftime_mean(tidx));
180 E = cell(1,sn.nentries);
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});
189 % Default to uniform distribution
190 jPopularity = javaObject(
'jline.lang.processes.DiscreteSampler', jline.util.matrix.Matrix.uniformDistribution(sn.nitems(eidx)));
192 E{e} = javaObject(
'jline.lang.layered.ItemEntry', model, sn.names{eidx}, sn.nitems(eidx), jPopularity);
194 E{e} = javaObject(
'jline.lang.layered.Entry', model, sn.names{eidx});
196 E{e}.on(T{sn.parent(eidx)-sn.tshift});
200 A = cell(1,sn.nacts);
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;
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));
219 jHostDem = jline.lang.processes.HyperExp.fitMeanAndSCV(sn.hostdem_mean(aidx), sn.hostdem_scv(aidx));
221 case ProcessType.COXIAN
222 jHostDem = jline.lang.processes.Coxian.fitMeanAndSCV(sn.hostdem_mean(aidx), sn.hostdem_scv(aidx));
224 jHostDem = jline.lang.processes.APH.fitMeanAndSCV(sn.hostdem_mean(aidx), sn.hostdem_scv(aidx));
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}));
230 jHostDem = javaObject(
'jline.lang.processes.Exp', 1/sn.hostdem_mean(aidx));
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}));
237 jHostDem = javaObject(
'jline.lang.processes.Exp', 1/sn.hostdem_mean(aidx));
240 jHostDem = javaObject(
'jline.lang.processes.Det', sn.hostdem_mean(aidx));
242 line_error(mfilename,sprintf(
'JLINE conversion does not support the %s distribution for host demand yet.',
char(sn.hostdem_type(aidx))));
244 A{a} = javaObject(
'jline.lang.layered.Activity', model, sn.names{aidx}, jHostDem);
247 boundTo = find(sn.graph((sn.eshift+1):(sn.eshift+sn.nentries),aidx));
250 A{a}.boundTo(E{boundTo});
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});
262 if ~isempty(sn.callpair)
263 cidxs = find(sn.callpair(:,1)==aidx);
264 calls = sn.callpair(:,2);
266 switch sn.calltype(c)
268 A{a}.synchCall(E{calls(c)-sn.eshift},sn.callproc_mean(c));
270 A{a}.asynchCall(E{calls(c)-sn.eshift},sn.callproc_mean(c));
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);
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)));
292 P{h}.setThinkTime(jline.lang.processes.HyperExp.fitMeanAndSCV(sn.think_mean(h), sn.think_scv(h)));
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)));
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)));
302 P{h}.setThinkTime(jline.lang.processes.Exp(1/sn.think_mean(h)));
305 line_error(mfilename,sprintf(
'JLINE conversion does not support the %s distribution yet.',
char(sn.think_type(h))));
310 %% Sequential precedences
312 aidx = sn.ashift + ai;
313 tidx = sn.parent(aidx);
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}));
325 %%%%%%%%%%%%%%%%%%%%%%%%%%% translated up to here
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);
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)
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)
350 % Found start of a loop: aidx is the entry, bidx is first loop body activity
352 precActs = java.util.ArrayList();
354 % Follow the chain of POST_LOOP activities
357 precActs.add(sprintf("%s", sn.names{curIdx}));
358 processedLoops(curIdx - sn.ashift) = true;
360 % Find successors of current activity
361 curSuccessors = find(sn.graph(curIdx,:));
362 curSuccessors = curSuccessors(curSuccessors > sn.ashift);
364 % Check for loop termination: find the end activity
365 % End activity has weight = 1/counts (not the back-edge weight)
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
374 weight = full(sn.graph(curIdx, succIdx));
375 if weight > 0 && weight < 1
376 % This is the end activity (weight = 1/counts)
379 % This is the next activity in the loop body (weight = 1.0)
386 % Found end activity - calculate counts and output
387 weight = full(sn.graph(curIdx, endIdx));
391 counts = 1; % Fallback to prevent division by zero
393 precActs.add(sprintf("%s", sn.names{endIdx}));
394 processedLoops(endIdx - sn.ashift) = true;
396 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.Loop(sn.names{aidx}, precActs, jline.util.matrix.Matrix(counts)));
399 % Continue to next activity in loop body
402 % No more successors - shouldn't happen in valid loop
406 break; % Only process one loop starting from
this activity
411 %% OrFork precedences (POST_OR)
415 aidx = sn.ashift + ai;
416 tidx = sn.parent(aidx);
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));
429 precActs.add(sprintf(
"%s", sn.names{bidx}));
430 probs(end+1)=full(sn.graph(aidx,bidx));
438 probsMatrix = jline.util.matrix.Matrix(1,length(probs));
439 for i=1:length(probs)
440 probsMatrix.set(0,i-1,probs(i));
442 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.OrFork(sn.names{precMarker+sn.ashift}, precActs, probsMatrix));
447 %% AndFork precedences (POST_AND)
451 aidx = sn.ashift + ai;
452 tidx = sn.parent(aidx);
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
459 postActs = java.util.ArrayList();
460 postActs.add(sprintf(
"%s", sn.names{bidx}));
462 postActs.add(sprintf(
"%s", sn.names{bidx}));
465 if precMarker == 0 % start a
new orjoin
466 precMarker = aidx-sn.ashift;
472 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.AndFork(sn.names{precMarker+sn.ashift}, postActs));
477 %% CacheAccess precedences (POST_CACHE)
481 aidx = sn.ashift + ai;
482 tidx = sn.parent(aidx);
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
489 postActs = java.util.ArrayList();
490 postActs.add(sprintf(
"%s", sn.names{bidx}));
492 postActs.add(sprintf(
"%s", sn.names{bidx}));
495 if precMarker == 0 % start a
new cache access
496 precMarker = aidx-sn.ashift;
502 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.CacheAccess(sn.names{precMarker+sn.ashift}, postActs));
508 %% OrJoin precedences (PRE_OR)
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}));
523 precActs.add(sprintf("%s", sn.names{aidx}));
529 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.OrJoin(precActs, sn.names{precMarker+sn.ashift}));
534 %% AndJoin precedences (PRE_AND)
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}));
549 precActs.add(sprintf(
"%s", sn.names{aidx}));
555 % Find quorum parameter from original precedence structure
556 postActName = sn.names{precMarker+sn.ashift};
557 localTaskIdx = tidx - sn.tshift;
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;
571 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.AndJoin(precActs, sn.names{precMarker+sn.ashift}));
573 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.AndJoin(precActs, sn.names{precMarker+sn.ashift}, quorum));
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));
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);
601 mu = line_dist.getParam(1).paramValue;
602 phi = line_dist.getParam(2).paramValue;
606 for i = 1:length(phi)
607 jline_phi.add(phi(i));
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')
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');
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}));
664 jdist = javaObject(
'jline.lang.processes.Prior', jdists, probs);
666 line_error(mfilename,
'Distribution not supported by JLINE.');
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]);
705 jmu = jdist.getParam(1).getValue;
706 jphi = jdist.getParam(2).getValue;
707 mu = zeros(1, jmu.size);
708 phi = zeros(1, jphi.size);
710 mu(i) = jmu.get(i-1);
713 phi(i) = jphi.get(i-1);
715 matlab_dist = Coxian(mu, phi);
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);
727 for i = 1:jxMat.length
728 x(i) = jxMat.get(i-1);
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);
743 dists{k} = JLINE.from_jline_distribution(jdists.get(k-1));
745 probs = jdist.getProbabilities();
746 matlab_dist = Prior(dists, probs);
748 line_error(mfilename,
'Distribution not supported by JLINE.');
752 function set_csMatrix(line_node, jnode, jclasses)
753 nClasses = length(line_node.model.classes);
754 csMatrix = jnode.initClassSwitchMatrix();
757 csMatrix.set(jclasses{i}, jclasses{j}, line_node.server.csFun(i,j,0,0));
760 jnode.setClassSwitchingMatrix(csMatrix);
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'))
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});
774 line_error(mfilename,
'Node not supported by JLINE.');
776 service_dist = JLINE.from_line_distribution(matlab_dist);
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);
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')
792 % Check if setupTime property exists and
is not empty
793 if ~isprop(line_node, 'setupTime') || isempty(line_node.setupTime)
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);
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')
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'))
828 line_error(mfilename,'Node not supported by JLINE.');
833 function node_object = from_line_node(line_node, jnetwork, ~, forkNode, sn)
834 % Handle optional sn argument
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);
909 nservers = line_node.getNumberOfServers;
911 node_object.setNumberOfServers(java.lang.Integer.MAX_VALUE);
913 node_object.setNumberOfServers(line_node.getNumberOfServers);
915 if ~isempty(line_node.lldScaling)
916 node_object.setLoadDependence(JLINE.from_line_matrix(line_node.lldScaling));
918 if ~isempty(line_node.lcdScaling)
920 line_error(mfilename, "Class-dependent models require sn struct for MATLAB-to-JAVA translation.");
922 node_object.setLimitedClassDependence(JLINE.handle_to_serializablefun(line_node.lcdScaling, sn));
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);
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);
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;
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));
966 node_object = javaObject('jline.lang.
nodes.Cache', jnetwork, line_node.name, nitems, JLINE.from_line_matrix(line_node.itemLevelCap), repStrategy);
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
974 line_error(mfilename,'Node not supported by JLINE.');
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'
985 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.INF);
987 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FCFS);
989 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LCFS);
991 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.SIRO);
993 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.SJF);
995 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LJF);
997 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.PS);
999 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.DPS);
1001 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.GPS);
1003 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.SEPT);
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);
1009 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FORK);
1011 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.EXT);
1013 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.REF);
1015 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.LCFSPR);
1017 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.SRPT);
1019 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.SRPTPRIO);
1021 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.PSJF);
1023 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.FB);
1025 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LRPT);
1027 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.PSPRIO);
1029 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.DPSPRIO);
1031 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.GPSPRIO);
1033 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LCFSPI);
1035 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.LCFSPRIO);
1037 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LCFSPRPRIO);
1039 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.LCFSPIPRIO);
1041 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FCFSPR);
1043 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.FCFSPI);
1045 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FCFSPRPRIO);
1047 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.FCFSPIPRIO);
1049 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.POLLING);
1051 node_object.setNumberOfServers(jline_node.getNumberOfServers);
1052 cap = jline_node.getCap();
1053 if cap < intmax && cap > 0
1054 node_object.setCapacity(cap);
1056 if ~isempty(JLINE.from_jline_matrix(jline_node.getLimitedLoadDependence))
1057 node_object.setLoadDependence(JLINE.from_jline_matrix(jline_node.getLimitedLoadDependence));
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);
1070 csMatrix(r,s) = jline_node.getServer.applyCsFun(r-1,s-1);
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)
1080 rp = ReplacementStrategy.LRU;
1082 rp = ReplacementStrategy.FIFO;
1084 rp = ReplacementStrategy.RR;
1086 rp = ReplacementStrategy.LRU;
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;
1094 node_object.setTasksPerLink(tpl);
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
1105 line_error(mfilename,'Node not supported by JLINE.');
1109 function node_class = from_line_class(line_class, jnetwork)
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);
1126 line_error(mfilename,'Class type not supported by JLINE.');
1128 if line_class.isReferenceClass()
1129 node_class.setReferenceClass(true);
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);
1141 line_error(mfilename,'Class type not supported by JLINE.');
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;
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));
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
1162 matlab2java_node_idx(i) = jidx;
1168 % [ ] Update to consider different weights/routing
for classes
1169 if isempty(sn.rtorig)
1170 useLinkMethod = false; % this model did not call link()
1172 jrt_matrix = jmodel.initRoutingMatrix();
1173 useLinkMethod = true;
1176 % For models with auto-added ClassSwitch
nodes, use sn.rtorig directly
1177 % to set up routing with proper class switching
1179 for i = 1:length(line_nodes)
1180 if isa(line_nodes{i},
'ClassSwitch') && line_nodes{i}.autoAdded
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
1192 if ~isempty(sn.rtorig{r,s})
1193 Prs = sn.rtorig{r,s};
1194 [nrows, ncols] = size(Prs);
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
1202 jrt_matrix.set(jclasses.get(r-1), jclasses.get(s-1), jnodes.get(jsrc_idx), jnodes.get(jdest_idx), Prs(i,j));
1210 % Original logic
for models without
auto-added ClassSwitch
1212 line_node = line_nodes{i};
1214 % Skip
auto-added ClassSwitch
nodes - Java will add them automatically
1215 if isa(line_node, 'ClassSwitch') && line_node.autoAdded
1219 jnode_idx = matlab2java_node_idx(i);
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,:));
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.
1236 for j= outlinks_i(:)'
1237 jdest_idx = matlab2java_node_idx(j);
1239 jmodel.addLink(jnodes.get(jnode_idx), jnodes.get(jdest_idx));
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,:))
';
1247 line_error(mfilename,'RROBIN cannot be used together with the link() command.
');
1249 for j= outlinks_i(:)'
1250 jdest_idx = matlab2java_node_idx(j);
1252 jmodel.addLink(jnodes.get(jnode_idx), jnodes.get(jdest_idx));
1255 case RoutingStrategy.WRROBIN
1256 outlinks_i=find(connections(i,:))
';
1257 for j= outlinks_i(:)'
1258 jdest_idx = matlab2java_node_idx(j);
1260 jmodel.addLink(jnodes.get(jnode_idx), jnodes.get(jdest_idx));
1264 line_error(mfilename,
'RROBIN cannot be used together with the link() command.');
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);
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);
1275 for j= outlinks_i(:)
'
1276 jdest_idx = matlab2java_node_idx(j);
1278 jmodel.addLink(jnodes.get(jnode_idx), jnodes.get(jdest_idx));
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
1289 jrt_matrix.set(jclasses.get(k-1), jclasses.get(k-1), jnodes.get(jnode_idx), jnodes.get(jdest_idx), probabilities{j}{2});
1291 jnodes.get(jnode_idx).setProbRouting(jclasses.get(k-1), jnodes.get(jdest_idx), probabilities{j}{2});
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,:))';
1300 for j= outlinks_i(:)
'
1301 jdest_idx = matlab2java_node_idx(j);
1303 jmodel.addLink(jnodes.get(jnode_idx), jnodes.get(jdest_idx));
1307 case RoutingStrategy.KCHOICES
1308 jnodes.get(jnode_idx).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.KCHOICES);
1309 if length(output_strat) >= 3 && length(output_strat{3}) >= 2
1310 kparam = output_strat{3}{1};
1311 memparam = logical(output_strat{3}{2});
1312 jnodes.get(jnode_idx).setKChoicesRouting(jclasses.get(k-1), int32(kparam), memparam);
1314 outlinks_i=find(connections(i,:))';
1316 for j= outlinks_i(:)
'
1317 jdest_idx = matlab2java_node_idx(j);
1319 jmodel.addLink(jnodes.get(jnode_idx), jnodes.get(jdest_idx));
1323 case RoutingStrategy.RL
1324 jnodes.get(jnode_idx).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.RL);
1325 outlinks_i=find(connections(i,:))';
1327 for j= outlinks_i(:)
'
1328 jdest_idx = matlab2java_node_idx(j);
1330 jmodel.addLink(jnodes.get(jnode_idx), jnodes.get(jdest_idx));
1334 % Forward the value function, action nodes, and
1335 % state size from outputStrategy{r}{3..5} so the
1336 % JAR sub_rl can replicate MATLAB's decisions.
1337 if length(output_strat) >= 5
1338 valFnRaw = output_strat{3};
1339 nodesNeedAction = output_strat{4};
1340 stateSize = output_strat{5};
1341 if ~isempty(valFnRaw)
1343 % Tabular: flatten N-D
array to a row vector and pass shape.
1344 shp = size(valFnRaw);
1345 jvfFlat = jline.util.matrix.Matrix(1, numel(valFnRaw));
1347 for f = 1:numel(flat)
1348 jvfFlat.set(0, f-1,
double(flat(f)));
1350 jshape = int32(shp(:)
');
1351 jnna = int32(nodesNeedAction(:)' - 1); % MATLAB->Java 0-based
1352 jnodes.get(jnode_idx).setRLRouting(jclasses.get(k-1), jvfFlat, jshape, jnna, int32(stateSize));
1354 % Linear approx: coefficient row vector.
1355 coeff = valFnRaw(:)
';
1356 jvf = jline.util.matrix.Matrix(1, numel(coeff));
1357 for f = 1:numel(coeff)
1358 jvf.set(0, f-1, double(coeff(f)));
1360 jnna = int32(nodesNeedAction(:)' - 1);
1361 jnodes.get(jnode_idx).setRLRouting(jclasses.get(k-1), jvf, int32([]), jnna, int32(stateSize));
1366 line_warning(mfilename, sprintf(
'''%s
'' routing strategy not supported by JLINE, setting as Disabled.\n
',output_strat{2}));
1367 jnodes.get(jnode_idx).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.DISABLED);
1373 jmodel.link(jrt_matrix);
1374 % Align the sn.rtorig be the same, treating artificial
1375 % ClassSwitch nodes as if they were explicitly specified
1376 jsn = jmodel.getStruct(true);
1377 rtorig = java.util.HashMap();
1378 if ~isempty(model.sn.rtorig)
1379 if iscell(model.sn.rtorig)
1381 sub_rtorig = java.util.HashMap();
1383 sub_rtorig.put(jclasses.get(s-1), JLINE.from_line_matrix(model.sn.rtorig{r,s}));
1385 rtorig.put(jclasses.get(r-1), sub_rtorig);
1389 jsn.rtorig = rtorig;
1393 function model = from_jline_routing(model, jnetwork)
1394 jnodes = jnetwork.getNodes();
1395 jclasses = jnetwork.getClasses();
1396 n_nodes = jnodes.size();
1397 network_nodes = model.getNodes;
1398 network_classes = model.getClasses;
1400 % Build name-to-MATLAB-node map (JAR and MATLAB may order nodes differently)
1401 node_by_name = containers.Map();
1402 for nn = 1:length(network_nodes)
1403 node_by_name(network_nodes{nn}.name) = network_nodes{nn};
1406 connections = JLINE.from_jline_matrix(jnetwork.getConnectionMatrix());
1407 [row,col] = find(connections);
1409 from_name = char(jnodes.get(row(i)-1).getName());
1410 to_name = char(jnodes.get(col(i)-1).getName());
1411 model.addLink(node_by_name(from_name), node_by_name(to_name));
1415 jnode = jnodes.get(n-1);
1416 cur_node = node_by_name(char(jnode.getName()));
1417 output_strategies = jnode.getOutputStrategies();
1418 n_strategies = output_strategies.size();
1419 for m = 1 : n_strategies
1420 output_strat = output_strategies.get(m-1);
1421 routing_strat = output_strat.getRoutingStrategy;
1422 routing_strat_classidx = output_strat.getJobClass.getIndex();
1423 switch char(routing_strat)
1425 cur_node.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.RAND);
1427 cur_node.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.RROBIN);
1429 dest = output_strat.getDestination();
1431 dest_name = char(dest.getName());
1432 if node_by_name.isKey(dest_name)
1433 weight = output_strat.getProbability();
1434 cur_node.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.WRROBIN, node_by_name(dest_name), weight);
1438 cur_node.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.DISABLED);
1444 function model = from_jline_links(model, jnetwork)
1445 P = model.initRoutingMatrix;
1446 jnodes = jnetwork.getNodes();
1447 jclasses = jnetwork.getClasses();
1448 n_classes = jclasses.size();
1449 n_nodes = jnodes.size();
1450 network_nodes = model.getNodes;
1452 % Build JAR-to-MATLAB node index mapping (node orders may differ)
1453 jar2ml = zeros(1, n_nodes);
1455 jar_name = char(jnodes.get(jj-1).getName());
1456 for mm = 1:length(network_nodes)
1457 if strcmp(network_nodes{mm}.name, jar_name)
1464 hasDestinations = false;
1466 jnode = jnodes.get(n-1);
1467 output_strategies = jnode.getOutputStrategies();
1468 n_strategies = output_strategies.size();
1469 for m = 1 : n_strategies
1470 output_strat = output_strategies.get(m-1);
1471 dest = output_strat.getDestination();
1472 if~isempty(dest) % disabled strategy
1473 hasDestinations = true;
1474 in_idx = jar2ml(jnetwork.getNodeIndex(jnode)+1);
1475 out_idx = jar2ml(jnetwork.getNodeIndex(dest)+1);
1477 P{1}(in_idx,out_idx) = output_strat.getProbability();
1479 strat_class = output_strat.getJobClass();
1480 class_idx = jnetwork.getJobClassIndex(strat_class)+1;
1481 P{class_idx,class_idx}(in_idx,out_idx) = output_strat.getProbability();
1487 % If no OutputStrategy entries had destinations (e.g., model
1488 % loaded from JSON via LineModelIO.load), fall back to rtorig
1490 sn = jnetwork.getStruct;
1491 if ~isempty(sn.rtorig)
1492 % rtorig is station-indexed (no permutation needed —
1493 % station ordering matches between JAR and MATLAB)
1496 rtMat = JLINE.from_jline_matrix(sn.rtorig.get(jclasses.get(r-1)).get(jclasses.get(s-1)));
1507 % Restore non-PROB routing strategies (RROBIN, WRROBIN, etc.)
1508 % after link(), which sets all routing to PROB
1509 network_nodes = model.getNodes;
1510 network_classes = model.getClasses;
1511 node_by_name = containers.Map();
1512 for nn = 1:length(network_nodes)
1513 node_by_name(network_nodes{nn}.name) = network_nodes{nn};
1516 jnode = jnodes.get(n-1);
1517 cur_node = node_by_name(char(jnode.getName()));
1518 output_strategies = jnode.getOutputStrategies();
1519 n_strategies = output_strategies.size();
1520 for m = 1 : n_strategies
1521 output_strat = output_strategies.get(m-1);
1522 routing_strat = output_strat.getRoutingStrategy;
1523 routing_strat_classidx = output_strat.getJobClass.getIndex();
1524 switch char(routing_strat)
1526 cur_node.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.RROBIN);
1528 dest = output_strat.getDestination();
1530 dest_name = char(dest.getName());
1531 if node_by_name.isKey(dest_name)
1532 % Clear stale PROB entries before first WRROBIN weight
1533 classIdx = routing_strat_classidx;
1534 if length(cur_node.output.outputStrategy) >= classIdx && ...
1535 length(cur_node.output.outputStrategy{1, classIdx}) >= 3
1536 curStrat = cur_node.output.outputStrategy{1, classIdx}{2};
1537 if ~strcmp(curStrat, 'WeightedRoundRobin
')
1538 cur_node.output.outputStrategy{1, classIdx}{3} = {};
1541 weight = output_strat.getProbability();
1542 cur_node.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.WRROBIN, node_by_name(dest_name), weight);
1549 % Invalidate cached struct after modifying routing strategies
1550 model.resetStruct();
1552 %Align the sn.rtorig be the same (Assume Java network is
1553 %created by calling Network.link)
1554 sn = jnetwork.getStruct;
1555 rtorig = cell(n_classes, n_classes);
1558 rtorig{r,s} = JLINE.from_jline_matrix(sn.rtorig.get(jclasses.get(r-1)).get(jclasses.get(s-1)));
1561 model.sn.rtorig = rtorig;
1564 function [jnetwork] = from_line_network(model)
1567 sn = model.getStruct;
1569 jnetwork = javaObject('jline.lang.Network
', model.getName);
1570 line_nodes = model.getNodes;
1571 line_classes = model.getClasses;
1573 jnodes = cell(1,length(line_nodes));
1574 jclasses = cell(1,length(line_classes));
1576 for n = 1 : length(line_nodes)
1577 % Skip auto-added ClassSwitch nodes - Java's link() will add them automatically
1578 if isa(line_nodes{n},
'ClassSwitch') && line_nodes{n}.autoAdded
1581 if isa(line_nodes{n},
'Join')
1582 jnodes{n} = JLINE.from_line_node(line_nodes{n}, jnetwork, line_classes, jnodes{line_nodes{n}.joinOf.index}, sn);
1584 jnodes{n} = JLINE.from_line_node(line_nodes{n}, jnetwork, line_classes, [], sn);
1588 for n = 1 : length(line_classes)
1589 jclasses{n} = JLINE.from_line_class(line_classes{n}, jnetwork);
1592 % Set up forJobClass associations
for signal
classes
1593 for n = 1 : length(line_classes)
1594 if (isa(line_classes{n},
'Signal') || isa(line_classes{n},
'OpenSignal') || isa(line_classes{n},
'ClosedSignal'))
1595 if ~isempty(line_classes{n}.targetJobClass)
1596 targetIdx = line_classes{n}.targetJobClass.index;
1597 jclasses{n}.forJobClass(jclasses{targetIdx});
1602 for n = 1: length(jnodes)
1603 if isempty(jnodes{n})
1604 continue; % Skip
nodes that were not converted (e.g.,
auto-added ClassSwitch)
1606 JLINE.set_service(line_nodes{n}, jnodes{n}, line_classes);
1607 JLINE.set_delayoff(line_nodes{n}, jnodes{n}, line_classes);
1610 % Set drop rules
for stations (after
classes are created)
1611 for n = 1: length(jnodes)
1612 if isempty(jnodes{n})
1613 continue; % Skip
nodes that were not converted
1615 if isa(line_nodes{n},
'Station') && ~isa(line_nodes{n},
'Source')
1616 for r = 1:length(line_classes)
1617 if length(line_nodes{n}.dropRule) >= r && ~isempty(line_nodes{n}.dropRule(r))
1618 dropRule = line_nodes{n}.dropRule(r);
1620 case DropStrategy.DROP
1621 jnodes{n}.setDropRule(jclasses{r}, jline.lang.constant.DropStrategy.Drop);
1622 case DropStrategy.BAS
1623 jnodes{n}.setDropRule(jclasses{r}, jline.lang.constant.DropStrategy.BlockingAfterService);
1624 case DropStrategy.WAITQ
1625 jnodes{n}.setDropRule(jclasses{r}, jline.lang.constant.DropStrategy.WaitingQueue);
1632 % Transfer LJCD (Limited Joint Class Dependence) scaling
for stations
1633 % This must be done after
classes are created since LJCD
is indexed per-class
1634 for n = 1:length(jnodes)
1635 if isempty(jnodes{n})
1638 if isa(line_nodes{n},
'Station') && ~isempty(line_nodes{n}.ljcdScaling) && ~isempty(line_nodes{n}.ljcdCutoffs)
1639 jCutoffs = JLINE.from_line_matrix(line_nodes{n}.ljcdCutoffs(:));
1640 K = length(line_nodes{n}.ljcdScaling);
1641 jScalingMap = java.util.HashMap();
1643 if ~isempty(line_nodes{n}.ljcdScaling{c})
1644 jScalingVec = JLINE.from_line_matrix(line_nodes{n}.ljcdScaling{c}(:));
1645 jScalingMap.put(jclasses{c}, jScalingVec);
1648 jnodes{n}.setLimitedJointClassDependence(jScalingMap, jCutoffs);
1652 % Set polling type and switchover times
for polling queues
1653 for n = 1: length(jnodes)
1654 if isempty(jnodes{n})
1657 if isa(line_nodes{n},
'Queue') && line_nodes{n}.schedStrategy == SchedStrategy.POLLING
1659 if ~isempty(line_nodes{n}.pollingType) && ~isempty(line_nodes{n}.pollingType{1})
1660 pollingType = line_nodes{n}.pollingType{1};
1662 case PollingType.GATED
1663 jPollingType = jline.lang.constant.PollingType.GATED;
1664 case PollingType.EXHAUSTIVE
1665 jPollingType = jline.lang.constant.PollingType.EXHAUSTIVE;
1666 case PollingType.KLIMITED
1667 jPollingType = jline.lang.constant.PollingType.KLIMITED;
1669 if pollingType == PollingType.KLIMITED && ~isempty(line_nodes{n}.pollingPar)
1670 jnodes{n}.setPollingType(jPollingType, int32(line_nodes{n}.pollingPar));
1672 jnodes{n}.setPollingType(jPollingType);
1675 % Set switchover times
1676 if ~isempty(line_nodes{n}.switchoverTime)
1677 for r = 1:length(line_classes)
1678 if length(line_nodes{n}.switchoverTime) >= r && ~isempty(line_nodes{n}.switchoverTime{r})
1679 soTime = line_nodes{n}.switchoverTime{r};
1680 if ~isa(soTime,
'Immediate')
1681 jnodes{n}.setSwitchover(jclasses{r}, JLINE.from_line_distribution(soTime));
1689 for n = 1: length(jnodes)
1690 if isempty(jnodes{n})
1691 continue; % Skip
nodes that were not converted
1693 if isa(line_nodes{n},
"ClassSwitch") && ~line_nodes{n}.autoAdded
1694 % Only set csMatrix
for user-defined ClassSwitch
nodes (not auto-added)
1695 JLINE.set_csMatrix(line_nodes{n}, jnodes{n}, jclasses);
1696 elseif isa(line_nodes{n},
"Join")
1697 jnodes{n}.initJoinJobClasses();
1698 % Restore RAND routing
for all
classes, matching ClosedClass/OpenClass
1699 % constructor behavior (initJoinJobClasses sets DISABLED by
default)
1700 for r = 1 : sn.nclasses
1701 jnodes{n}.setRouting(jclasses{r}, jline.lang.constant.RoutingStrategy.RAND);
1703 elseif isa(line_nodes{n},
"Cache")
1704 for r = 1 : sn.nclasses
1705 if length(line_nodes{n}.server.hitClass) >= r && ~isempty(line_nodes{n}.server.hitClass(r))
1706 if ~isa(line_nodes{n}.popularity{r},
'Disabled')
1707 jnodes{n}.setRead(jclasses{r}, JLINE.from_line_distribution(line_nodes{n}.popularity{r}));
1708 jnodes{n}.setHitClass(jclasses{r}, jclasses{line_nodes{n}.server.hitClass(r)});
1709 jnodes{n}.setMissClass(jclasses{r}, jclasses{line_nodes{n}.server.missClass(r)});
1713 % Transfer accessProb from MATLAB to Java
1714 if ~isempty(line_nodes{n}.accessProb)
1715 accessProbMat = line_nodes{n}.accessProb;
1716 [K1, K2] = size(accessProbMat);
1717 jAccessProb = javaArray(
'jline.util.matrix.Matrix', K1, K2);
1720 if ~isempty(accessProbMat{k1, k2})
1721 jAccessProb(k1, k2) = JLINE.from_line_matrix(accessProbMat{k1, k2});
1725 jnodes{n}.setAccessProb(jAccessProb);
1727 elseif isa(line_nodes{n},
"Transition")
1728 % First, add modes (must be done after
classes are created)
1729 for m = 1:line_nodes{n}.getNumberOfModes()
1730 modeName = line_nodes{n}.modeNames{m};
1731 jmode = jnodes{n}.addMode(modeName);
1732 % Set timing strategy
1733 switch line_nodes{n}.timingStrategies(m)
1734 case TimingStrategy.TIMED
1735 jnodes{n}.setTimingStrategy(jmode, jline.lang.constant.TimingStrategy.TIMED);
1736 case TimingStrategy.IMMEDIATE
1737 jnodes{n}.setTimingStrategy(jmode, jline.lang.constant.TimingStrategy.IMMEDIATE);
1740 jnodes{n}.setDistribution(jmode, JLINE.from_line_distribution(line_nodes{n}.distributions{m}));
1741 % Set firing weights and priorities
1742 jnodes{n}.setFiringWeights(jmode, line_nodes{n}.firingWeights(m));
1743 jnodes{n}.setFiringPriorities(jmode, int32(line_nodes{n}.firingPriorities(m)));
1744 % Set number of servers
1745 nsrv = line_nodes{n}.numberOfServers(m);
1747 jnodes{n}.setNumberOfServers(jmode, java.lang.Integer(intmax(
'int32')));
1749 jnodes{n}.setNumberOfServers(jmode, java.lang.Integer(int32(nsrv)));
1752 % Now set enabling conditions, inhibiting conditions, and firing outcomes
1753 jmodes = jnodes{n}.getModes();
1754 for m = 1:line_nodes{n}.getNumberOfModes()
1755 jmode = jmodes.get(m-1);
1756 enabCond = line_nodes{n}.enablingConditions{m};
1757 inhibCond = line_nodes{n}.inhibitingConditions{m};
1758 firingOut = line_nodes{n}.firingOutcomes{m};
1759 for r = 1:sn.nclasses
1760 for i = 1:length(line_nodes)
1761 % Set enabling conditions
1762 if enabCond(i, r) > 0 && isa(line_nodes{i},
'Place')
1763 jnodes{n}.setEnablingConditions(jmode, jclasses{r}, jnodes{i}, enabCond(i, r));
1765 % Set inhibiting conditions
1766 if inhibCond(i, r) < Inf && isa(line_nodes{i},
'Place')
1767 jnodes{n}.setInhibitingConditions(jmode, jclasses{r}, jnodes{i}, inhibCond(i, r));
1769 % Set firing outcomes
1770 if firingOut(i, r) ~= 0
1771 jnodes{n}.setFiringOutcome(jmode, jclasses{r}, jnodes{i}, firingOut(i, r));
1779 % Assume JLINE and LINE network are both created via link
1780 JLINE.from_line_links(model, jnetwork);
1782 % Transfer finite capacity regions from MATLAB to Java
1783 if ~isempty(model.regions)
1784 for f = 1:length(model.regions)
1785 fcr = model.regions{f};
1786 % Convert MATLAB node list to Java list
1787 javaNodeList = java.util.ArrayList();
1788 for i = 1:length(fcr.nodes)
1789 matlabNode = fcr.
nodes{i};
1790 % Find corresponding Java node by name
1791 nodeName = matlabNode.getName();
1792 for j = 1:length(line_nodes)
1793 if strcmp(line_nodes{j}.getName(), nodeName) && ~isempty(jnodes{j})
1794 javaNodeList.add(jnodes{j});
1800 jfcr = jnetwork.addRegion(javaNodeList);
1801 % Set global max jobs
1802 if fcr.globalMaxJobs > 0 && ~isinf(fcr.globalMaxJobs)
1803 jfcr.setGlobalMaxJobs(fcr.globalMaxJobs);
1805 % Set per-class max jobs and drop rules
1806 for r = 1:length(line_classes)
1807 if length(fcr.classMaxJobs) >= r && fcr.classMaxJobs(r) > 0 && ~isinf(fcr.classMaxJobs(r))
1808 jfcr.setClassMaxJobs(jclasses{r}, fcr.classMaxJobs(r));
1810 if length(fcr.dropRule) >= r
1811 % Convert MATLAB DropStrategy numeric to Java DropStrategy
enum
1812 jDropStrategy = jline.lang.constant.DropStrategy.fromID(fcr.dropRule(r));
1813 jfcr.setDropRule(jclasses{r}, jDropStrategy);
1816 % Transfer linear constraints
if set
1817 if fcr.hasLinearConstraints()
1818 jA = JLINE.from_line_matrix(fcr.constraintA);
1819 jb = JLINE.from_line_matrix(fcr.constraintB);
1820 jfcr.setLinearConstraints(jA, jb);
1825 jnetwork.initDefault;
1826 for n = 1: length(line_nodes)
1827 if isempty(jnodes{n})
1828 continue; % Skip
nodes that were not converted
1830 if line_nodes{n}.isStateful
1831 jnodes{n}.setState(JLINE.from_line_matrix(line_nodes{n}.getState));
1832 jnodes{n}.setStateSpace(JLINE.from_line_matrix(line_nodes{n}.getStateSpace));
1833 jnodes{n}.setStatePrior(JLINE.from_line_matrix(line_nodes{n}.getStatePrior));
1836 % Force
struct refresh so sn.state reflects updated node states
1837 jnetwork.setHasStruct(
false);
1841 function jnetwork = line_to_jline(model)
1842 jnetwork = LINE2JLINE(model);
1845 function model = jline_to_line(jnetwork)
1846 if isa(jnetwork,
'JNetwork')
1847 jnetwork = jnetwork.obj;
1849 %javaaddpath(jar_loc);
1850 model = Network(
char(jnetwork.getName));
1851 network_nodes = jnetwork.getNodes;
1852 job_classes = jnetwork.getClasses;
1854 line_nodes = cell(network_nodes.size,1);
1855 line_classes = cell(job_classes.size,1);
1858 for n = 1 : network_nodes.size
1859 if ~isa(network_nodes.get(n-1), 'jline.lang.
nodes.ClassSwitch')
1860 line_nodes{n} = JLINE.from_jline_node(network_nodes.get(n-1), model, job_classes);
1864 for n = 1 : job_classes.size
1865 line_classes{n} = JLINE.from_jline_class(job_classes.get(n-1), model);
1868 for n = 1 : network_nodes.size
1869 if isa(network_nodes.get(n-1),
'jline.lang.nodes.ClassSwitch')
1870 line_nodes{n} = JLINE.from_jline_node(network_nodes.get(n-1), model, job_classes);
1874 % Deferred Fork/Join linking: set joinOf on Join
nodes
1875 for n = 1 : network_nodes.size
1876 jnode = network_nodes.get(n-1);
1877 if isa(jnode,
'jline.lang.nodes.Join') && ~isempty(jnode.joinOf)
1878 forkName =
char(jnode.joinOf.getName);
1879 for m = 1 : network_nodes.size
1880 if ~isempty(line_nodes{m}) && isa(line_nodes{m},
'Fork') && strcmp(line_nodes{m}.name, forkName)
1881 line_nodes{n}.joinOf = line_nodes{m};
1888 % Deferred Cache setup: set hitClass, missClass, popularity
1889 for n = 1 : network_nodes.size
1890 jnode = network_nodes.get(n-1);
1891 if isa(jnode,
'jline.lang.nodes.Cache') && isa(line_nodes{n},
'Cache')
1892 cacheNode = line_nodes{n};
1893 % hitClass and missClass are stored as index vectors
1894 hitClassVec = JLINE.from_jline_matrix(jnode.getHitClass());
1895 missClassVec = JLINE.from_jline_matrix(jnode.getMissClass());
1896 for r = 1:job_classes.size
1897 hitIdx = hitClassVec(r);
1898 if hitIdx >= 0 && (hitIdx + 1) <= job_classes.size
1899 cacheNode.setHitClass(line_classes{r}, line_classes{hitIdx + 1});
1901 missIdx = missClassVec(r);
1902 if missIdx >= 0 && (missIdx + 1) <= job_classes.size
1903 cacheNode.setMissClass(line_classes{r}, line_classes{missIdx + 1});
1906 % Popularity distributions
1907 for r = 1:job_classes.size
1909 popDist = jnode.popularityGet(0, r-1);
1910 if ~isempty(popDist) && popDist.isDiscrete()
1911 matlabDist = JLINE.from_jline_distribution(popDist);
1912 if ~isempty(matlabDist)
1913 cacheNode.setRead(line_classes{r}, matlabDist);
1917 % No popularity
for this class
1923 for n = 1 : network_nodes.size
1924 JLINE.set_line_service(network_nodes.get(n-1), line_nodes{n}, job_classes, line_classes);
1927 % Configure Transition modes (distributions, enabling/inhibiting/firing, etc.)
1928 for n = 1 : network_nodes.size
1929 jnode = network_nodes.get(n-1);
1930 if isa(jnode, 'jline.lang.
nodes.Transition') && isa(line_nodes{n},
'Transition')
1931 tnode = line_nodes{n};
1932 jmodes = jnode.getModes();
1933 nmodes = jmodes.size();
1935 jmode = jmodes.get(m-1);
1936 modeName = char(jmode.getName());
1937 % addMode
if not yet present (Transition starts with one
default mode)
1938 if m > tnode.getNumberOfModes()
1939 tnode.addMode(modeName);
1941 tnode.setModeNames(m, modeName);
1944 ts = jnode.timingStrategies.get(jmode);
1946 tsName = char(ts.name());
1947 if strcmp(tsName,
'IMMEDIATE')
1948 tnode.setTimingStrategy(m, TimingStrategy.IMMEDIATE);
1950 tnode.setTimingStrategy(m, TimingStrategy.TIMED);
1954 jdist = jnode.getFiringDistribution(jmode);
1956 matlabDist = JLINE.from_jline_distribution(jdist);
1957 if ~isempty(matlabDist)
1958 tnode.setDistribution(m, matlabDist);
1962 numSrv = jnode.getNumberOfModeServers(jmode);
1963 if numSrv == intmax('int32') || numSrv == intmax('int64')
1964 tnode.setNumberOfServers(m, Inf);
1966 tnode.setNumberOfServers(m,
double(numSrv));
1968 % Firing priority and weight (read from matrices by mode index)
1969 if jnode.firingPriorities.getNumElements() > (m-1)
1970 tnode.setFiringPriorities(m, jnode.firingPriorities.get(m-1));
1972 if jnode.firingWeights.getNumElements() > (m-1)
1973 tnode.setFiringWeights(m, jnode.firingWeights.get(m-1));
1975 % Enabling conditions
1976 ecMat = jnode.enablingConditions.get(jmode);
1978 nrows = ecMat.getNumRows();
1979 ncols = ecMat.getNumCols();
1982 val = ecMat.get(ni-1, ci-1);
1983 if val > 0 && ni <= length(line_nodes) && isa(line_nodes{ni},
'Place')
1984 tnode.setEnablingConditions(m, ci, line_nodes{ni}, val);
1989 % Inhibiting conditions
1990 icMat = jnode.inhibitingConditions.get(jmode);
1992 nrows = icMat.getNumRows();
1993 ncols = icMat.getNumCols();
1996 val = icMat.get(ni-1, ci-1);
1997 if isfinite(val) && val > 0 && ni <= length(line_nodes) && isa(line_nodes{ni},
'Place')
1998 tnode.setInhibitingConditions(m, ci, line_nodes{ni}, val);
2004 foMat = jnode.firingOutcomes.get(jmode);
2006 nrows = foMat.getNumRows();
2007 ncols = foMat.getNumCols();
2010 val = foMat.get(ni-1, ci-1);
2011 if val ~= 0 && ni <= length(line_nodes)
2012 tnode.setFiringOutcome(m, ci, line_nodes{ni}, val);
2021 % Check
for state-dependent routing (RROBIN, WRROBIN, JSQ)
2022 % These cannot go through link(
P) because it overrides routing strategies
2023 hasSDRouting = false;
2024 for n = 1 : network_nodes.size
2025 jnode = network_nodes.get(n-1);
2026 output_strategies = jnode.getOutputStrategies();
2027 for m = 1 : output_strategies.size()
2028 rs = char(output_strategies.get(m-1).getRoutingStrategy);
2029 if any(strcmp(rs, {
'RROBIN',
'WRROBIN',
'JSQ',
'KCHOICES'}))
2030 hasSDRouting = true;
2034 if hasSDRouting; break; end
2038 % State-dependent routing: use addLink + setRouting
2039 model = JLINE.from_jline_routing(model, jnetwork);
2040 elseif ~isempty(jnetwork.getStruct.rtorig)
2042 model = JLINE.from_jline_links(model, jnetwork);
2044 % Do not use link() method
2045 model = JLINE.from_jline_routing(model, jnetwork);
2048 % Restore initial state on Place
nodes after linking
2049 for n = 1 : network_nodes.size
2050 jnode = network_nodes.get(n-1);
2051 if isa(jnode, 'jline.lang.
nodes.Place') && ~isempty(line_nodes{n}) && isa(line_nodes{n},
'Place')
2052 jst = jnode.getState();
2053 if ~isempty(jst) && ~jst.isEmpty()
2054 line_nodes{n}.setState(JLINE.from_jline_matrix(jst));
2060 function matrix = arraylist_to_matrix(jline_matrix)
2061 if isempty(jline_matrix)
2064 matrix = zeros(jline_matrix.size(), 1);
2065 for row = 1:jline_matrix.size()
2066 matrix(row, 1) = jline_matrix.get(row-1);
2071 function matrix = from_jline_matrix(jline_matrix)
2072 if isempty(jline_matrix)
2075 matrix = zeros(jline_matrix.getNumRows(), jline_matrix.getNumCols());
2076 for row = 1:jline_matrix.getNumRows()
2077 for col = 1:jline_matrix.getNumCols()
2078 val = jline_matrix.get(row-1, col-1);
2079 if (val >= 33333333 && val <= 33333334)
2080 matrix(row, col) = GlobalConstants.Immediate;
2081 elseif (val >= -33333334 && val <= -33333333)
2082 matrix(row, col) = -GlobalConstants.Immediate;
2083 elseif (val >= 2147483647 - 1) % Integer.MAX_VALUE with -1 tolerance
2084 matrix(row, col) = Inf;
2085 elseif (val <= -2147483648 + 1) % Integer.MIN_VALUE with +1 tolerance
2086 matrix(row, col) = -Inf;
2088 matrix(row, col) = val;
2095 function jline_matrix = from_line_matrix(matrix)
2096 [rows, cols] = size(matrix);
2097 jline_matrix = jline.util.matrix.Matrix(rows, cols);
2100 if matrix(row,col) ~= 0
2101 jline_matrix.set(row-1, col-1, matrix(row, col));
2107 function lsn = from_jline_struct_layered(jlayerednetwork, jlsn)
2108 lsn = LayeredNetworkStruct();
2109 lsn.nidx= jlsn.nidx;
2110 lsn.nhosts= jlsn.nhosts;
2111 lsn.ntasks= jlsn.ntasks;
2112 lsn.nentries= jlsn.nentries;
2113 lsn.nacts= jlsn.nacts;
2114 lsn.ncalls= jlsn.ncalls;
2115 lsn.hshift= jlsn.hshift;
2116 lsn.tshift= jlsn.tshift;
2117 lsn.eshift= jlsn.eshift;
2118 lsn.ashift= jlsn.ashift;
2119 lsn.cshift= jlsn.cshift;
2121 lsn.tasksof{h,1} = JLINE.arraylist_to_matrix(jlsn.tasksof.get(uint32(h)))
';
2124 lsn.entriesof{lsn.tshift+t,1} = JLINE.arraylist_to_matrix(jlsn.entriesof.get(uint32(jlsn.tshift+t)))';
2126 for t=1:(jlsn.ntasks+jlsn.nentries)
2127 lsn.actsof{lsn.tshift+t,1} = JLINE.arraylist_to_matrix(jlsn.actsof.get(uint32(jlsn.tshift+t)))';
2130 lsn.callsof{lsn.ashift+a,1} = JLINE.arraylist_to_matrix(jlsn.callsof.get(uint32(jlsn.ashift+a)))';
2132 for i = 1:jlsn.sched.size
2133 lsn.sched(i,1) = SchedStrategy.(char(jlsn.sched.get(uint32(i))));
2135 for i = 1:jlsn.names.size
2136 lsn.names{i,1} = jlsn.names.get(uint32(i));
2137 lsn.hashnames{i,1} = jlsn.hashnames.get(uint32(i));
2139 lsn.mult = JLINE.from_jline_matrix(jlsn.mult);
2140 lsn.mult = lsn.mult(2:(lsn.eshift+1))
'; % remove 0-padding
2141 lsn.maxmult = JLINE.from_jline_matrix(jlsn.maxmult);
2142 lsn.maxmult = lsn.maxmult(2:(lsn.eshift+1))'; % remove 0-padding
2144 lsn.repl = JLINE.from_jline_matrix(jlsn.repl)';
2145 lsn.repl = lsn.repl(2:end); % remove 0-padding
2146 lsn.type = JLINE.from_jline_matrix(jlsn.type)';
2147 lsn.type = lsn.type(2:end); % remove 0-padding
2148 lsn.parent = JLINE.from_jline_matrix(jlsn.parent);
2149 lsn.parent = lsn.parent(2:end); % remove 0-padding
2150 lsn.nitems = JLINE.from_jline_matrix(jlsn.nitems);
2151 % Ensure proper column vector format matching MATLAB
's (nhosts+ntasks+nentries) x 1
2152 if isrow(lsn.nitems)
2153 lsn.nitems = lsn.nitems(2:end)'; % remove 0-padding and transpose
2155 lsn.nitems = lsn.nitems(2:end); % remove 0-padding (already column)
2157 % Ensure correct size
2158 expectedSize = lsn.nhosts + lsn.ntasks + lsn.nentries;
2159 if length(lsn.nitems) < expectedSize
2160 lsn.nitems(expectedSize,1) = 0;
2161 elseif length(lsn.nitems) > expectedSize
2162 lsn.nitems = lsn.nitems(1:expectedSize);
2164 lsn.replacestrat = JLINE.from_jline_matrix(jlsn.replacestrat);
2165 lsn.replacestrat = lsn.replacestrat(2:end)
'; % remove 0-padding
2166 for i = 1:jlsn.callnames.size
2167 lsn.callnames{i,1} = jlsn.callnames.get(uint32(i));
2168 lsn.callhashnames{i,1} = jlsn.callhashnames.get(uint32(i));
2170 for i = 1:jlsn.calltype.size % calltype may be made into a matrix in Java
2171 ct = char(jlsn.calltype.get(uint32(i)));
2172 lsn.calltype(i) = CallType.(ct);
2174 lsn.calltype = sparse(lsn.calltype'); % remove 0-padding
2175 lsn.callpair = JLINE.from_jline_matrix(jlsn.callpair);
2176 lsn.callpair = lsn.callpair(2:end,2:end); % remove 0-paddings
2177 if isempty(lsn.callpair)
2180 lsn.actpretype = sparse(JLINE.from_jline_matrix(jlsn.actpretype)
');
2181 lsn.actpretype = lsn.actpretype(2:end); % remove 0-padding
2182 lsn.actposttype = sparse(JLINE.from_jline_matrix(jlsn.actposttype)');
2183 lsn.actposttype = lsn.actposttype(2:end); % remove 0-padding
2184 lsn.graph = JLINE.from_jline_matrix(jlsn.graph);
2185 lsn.graph = lsn.graph(2:end,2:end); % remove 0-paddings
2186 lsn.dag = JLINE.from_jline_matrix(jlsn.dag);
2187 lsn.dag = lsn.dag(2:end,2:end); % remove 0-paddings
2188 lsn.taskgraph = JLINE.from_jline_matrix(jlsn.taskgraph);
2189 lsn.taskgraph = sparse(lsn.taskgraph(2:end,2:end)); % remove 0-paddings
2190 lsn.replygraph = JLINE.from_jline_matrix(jlsn.replygraph);
2191 lsn.replygraph = logical(lsn.replygraph(2:end,2:end)); % remove 0-paddings
2192 lsn.iscache = JLINE.from_jline_matrix(jlsn.iscache);
2193 % Ensure proper column vector format matching MATLAB
's (nhosts+ntasks) x 1
2194 expectedCacheSize = lsn.nhosts + lsn.ntasks;
2195 if isrow(lsn.iscache)
2196 if length(lsn.iscache) > expectedCacheSize
2197 lsn.iscache = lsn.iscache(2:(expectedCacheSize+1))'; % remove 0-padding and transpose
2199 lsn.iscache = lsn.iscache'; % just transpose
2202 % Ensure correct size
2203 if length(lsn.iscache) < expectedCacheSize
2204 lsn.iscache(expectedCacheSize,1) = 0;
2205 elseif length(lsn.iscache) > expectedCacheSize
2206 lsn.iscache = lsn.iscache(1:expectedCacheSize);
2208 lsn.iscaller = JLINE.from_jline_matrix(jlsn.iscaller);
2209 lsn.iscaller = full(lsn.iscaller(2:end,2:end)); % remove 0-paddings
2210 lsn.issynccaller = JLINE.from_jline_matrix(jlsn.issynccaller);
2211 lsn.issynccaller = full(lsn.issynccaller(2:end,2:end)); % remove 0-paddings
2212 lsn.isasynccaller = JLINE.from_jline_matrix(jlsn.isasynccaller);
2213 lsn.isasynccaller = full(lsn.isasynccaller(2:end,2:end)); % remove 0-paddings
2214 lsn.isref = JLINE.from_jline_matrix(jlsn.isref);
2215 lsn.isref = lsn.isref(2:end)
'; % remove 0-paddings
2218 function sn = from_jline_struct(jnetwork, jsn)
2219 %lst and rtfun are not implemented
2220 %Due to the transformation of Java lambda to matlab function
2222 jsn = jnetwork.getStruct(false);
2224 jclasses = jnetwork.getClasses();
2225 jnodes = jnetwork.getNodes();
2226 jstateful = jnetwork.getStatefulNodes();
2227 jstations = jnetwork.getStations();
2228 sn = NetworkStruct();
2230 sn.nnodes = jsn.nnodes;
2231 sn.nclasses = jsn.nclasses;
2232 sn.nclosedjobs = jsn.nclosedjobs;
2233 sn.nstations = jsn.nstations;
2234 sn.nstateful = jsn.nstateful;
2235 sn.nchains = jsn.nchains;
2237 sn.refstat = JLINE.from_jline_matrix(jsn.refstat) + 1;
2238 sn.njobs = JLINE.from_jline_matrix(jsn.njobs);
2239 sn.nservers = JLINE.from_jline_matrix(jsn.nservers);
2240 sn.connmatrix = JLINE.from_jline_matrix(jsn.connmatrix);
2241 % Fix for Java getConnectionMatrix bug: ensure connmatrix is nnodes x nnodes
2242 if size(sn.connmatrix,1) < sn.nnodes
2243 sn.connmatrix(sn.nnodes,1) = 0;
2245 if size(sn.connmatrix,2) < sn.nnodes
2246 sn.connmatrix(1,sn.nnodes) = 0;
2248 sn.scv = JLINE.from_jline_matrix(jsn.scv);
2249 sn.isstation = logical(JLINE.from_jline_matrix(jsn.isstation));
2250 sn.isstateful = logical(JLINE.from_jline_matrix(jsn.isstateful));
2251 sn.isstatedep = logical(JLINE.from_jline_matrix(jsn.isstatedep));
2252 sn.nodeToStateful = JLINE.from_jline_matrix(jsn.nodeToStateful)+1;
2253 sn.nodeToStateful(sn.nodeToStateful==0) = nan;
2254 sn.nodeToStation = JLINE.from_jline_matrix(jsn.nodeToStation)+1;
2255 sn.nodeToStation(sn.nodeToStation==0) = nan;
2256 sn.stationToNode = JLINE.from_jline_matrix(jsn.stationToNode)+1;
2257 sn.stationToNode(sn.stationToNode==0) = nan;
2258 sn.stationToStateful = JLINE.from_jline_matrix(jsn.stationToStateful)+1;
2259 sn.stationToStateful(sn.stationToStateful==0) = nan;
2260 sn.statefulToStation = JLINE.from_jline_matrix(jsn.statefulToStation)+1;
2261 sn.statefulToStation(sn.statefulToStation==0) = nan;
2262 sn.statefulToNode = JLINE.from_jline_matrix(jsn.statefulToNode)+1;
2263 sn.statefulToNode(sn.statefulToNode==0) = nan;
2264 sn.rates = JLINE.from_jline_matrix(jsn.rates);
2265 sn.fj = JLINE.from_jline_matrix(jsn.fj);
2266 sn.classprio = JLINE.from_jline_matrix(jsn.classprio);
2267 sn.phases = JLINE.from_jline_matrix(jsn.phases);
2268 sn.phasessz = JLINE.from_jline_matrix(jsn.phasessz);
2269 sn.phaseshift = JLINE.from_jline_matrix(jsn.phaseshift);
2270 sn.schedparam = JLINE.from_jline_matrix(jsn.schedparam);
2271 sn.chains = logical(JLINE.from_jline_matrix(jsn.chains));
2272 sn.rt = JLINE.from_jline_matrix(jsn.rt);
2273 sn.nvars = JLINE.from_jline_matrix(jsn.nvars);
2274 sn.rtnodes = JLINE.from_jline_matrix(jsn.rtnodes);
2275 sn.csmask = logical(JLINE.from_jline_matrix(jsn.csmask));
2276 sn.isslc = logical(JLINE.from_jline_matrix(jsn.isslc));
2277 sn.cap = JLINE.from_jline_matrix(jsn.cap);
2278 sn.classcap = JLINE.from_jline_matrix(jsn.classcap);
2279 sn.refclass = JLINE.from_jline_matrix(jsn.refclass)+1;
2280 sn.lldscaling = JLINE.from_jline_matrix(jsn.lldscaling);
2282 if ~isempty(jsn.cdscaling) && jsn.cdscaling.size() > 0
2283 % Convert Java SerializableFunction to MATLAB function handles
2284 sn.cdscaling = cell(sn.nstations, 1);
2285 % Iterate through the map entries to handle null values properly
2286 entrySet = jsn.cdscaling.entrySet();
2287 entryIter = entrySet.iterator();
2288 stationFunMap = containers.Map();
2289 while entryIter.hasNext()
2290 entry = entryIter.next();
2291 stationName = char(entry.getKey().getName());
2293 jfun = entry.getValue();
2295 stationFunMap(stationName) = jfun;
2298 % getValue() returns null for default lambda functions
2299 % Skip and use default value
2302 % Assign functions to stations
2303 for i = 1:sn.nstations
2304 jstation = jstations.get(i-1);
2305 stationName = char(jstation.getName());
2306 if isKey(stationFunMap, stationName)
2307 jfun = stationFunMap(stationName);
2308 % Create a MATLAB function handle that calls the Java apply() method
2309 sn.cdscaling{i} = @(ni) JLINE.call_java_cdscaling(jfun, ni);
2311 sn.cdscaling{i} = @(ni) 1;
2315 sn.cdscaling = cell(sn.nstations, 0);
2318 if ~isempty(jsn.nodetype)
2319 sn.nodetype = zeros(sn.nnodes, 1);
2320 for i = 1:jsn.nodetype.size
2321 nodetype = jsn.nodetype.get(i-1);
2322 switch nodetype.name().toCharArray'
2324 sn.nodetype(i) = NodeType.Queue;
2326 sn.nodetype(i) = NodeType.Delay;
2328 sn.nodetype(i) = NodeType.Source;
2330 sn.nodetype(i) = NodeType.Sink;
2332 sn.nodetype(i) = NodeType.Join;
2334 sn.nodetype(i) = NodeType.Fork;
2336 sn.nodetype(i) = NodeType.ClassSwitch;
2338 sn.nodetype(i) = NodeType.Logger;
2340 sn.nodetype(i) = NodeType.Cache;
2342 sn.nodetype(i) = NodeType.Place;
2344 sn.nodetype(i) = NodeType.Transition;
2346 sn.nodetype(i) = NodeType.Router;
2353 if ~isempty(jsn.classnames)
2354 for i = 1:jsn.classnames.size
2355 sn.classnames(i,1) = jsn.classnames.get(i-1);
2361 if ~isempty(jsn.nodenames)
2362 for i = 1:jsn.nodenames.size
2363 sn.nodenames(i,1) = jsn.nodenames.get(i-1);
2369 if ~isempty(jsn.rtorig) && jsn.rtorig.size()>0
2370 sn.rtorig = cell(sn.nclasses, sn.nclasses);
2371 for r = 1:sn.nclasses
2372 for s = 1:sn.nclasses
2373 sn.rtorig{r,s} = JLINE.from_jline_matrix(jsn.rtorig.get(jclasses.get(r-1)).get(jclasses.get(s-1)));
2380 if ~isempty(jsn.state)
2381 sn.state = cell(sn.nstateful, 1);
2382 for i = 1:sn.nstateful
2383 sn.state{i} = JLINE.from_jline_matrix(jstateful.get(i-1).getState());
2389 if ~isempty(jsn.stateprior)
2390 sn.stateprior = cell(sn.nstateful, 1);
2391 for i = 1:sn.nstateful
2392 sn.stateprior{i} = JLINE.from_jline_matrix(jstateful.get(i-1).getStatePrior());
2398 if ~isempty(jsn.space)
2399 sn.space = cell(sn.nstateful, 1);
2400 for i = 1:sn.nstateful
2401 sn.space{i} = JLINE.from_jline_matrix(jstateful.get(i-1).getStateSpace());
2407 if ~isempty(jsn.routing)
2408 sn.routing = zeros(sn.nnodes, sn.nclasses);
2410 for j = 1:sn.nclasses
2411 routingStrategy = jsn.routing.get(jnodes.get(i-1)).get(jclasses.get(j-1));
2412 switch routingStrategy.name().toCharArray'
2414 sn.routing(i,j) = RoutingStrategy.PROB;
2416 sn.routing(i,j) = RoutingStrategy.RAND;
2418 sn.routing(i,j) = RoutingStrategy.RROBIN;
2420 sn.routing(i,j) = RoutingStrategy.WRROBIN;
2422 sn.routing(i,j) = RoutingStrategy.JSQ;
2424 sn.routing(i,j) = RoutingStrategy.DISABLED;
2426 sn.routing(i,j) = RoutingStrategy.FIRING;
2428 sn.routing(i,j) = RoutingStrategy.KCHOICES;
2436 if ~isempty(jsn.procid)
2437 sn.procid = nan(sn.nstations, sn.nclasses); % Initialize with NaN to match MATLAB behavior
2438 for i = 1:sn.nstations
2439 for j = 1:sn.nclasses
2440 stationMap = jsn.procid.get(jstations.get(i-1));
2441 if isempty(stationMap)
2442 sn.procid(i,j) = ProcessType.DISABLED;
2445 processType = stationMap.get(jclasses.get(j-1));
2446 if isempty(processType)
2447 sn.procid(i,j) = ProcessType.DISABLED;
2450 switch processType.name.toCharArray'
2452 sn.procid(i,j) = ProcessType.EXP;
2454 sn.procid(i,j) = ProcessType.ERLANG;
2456 sn.procid(i,j) = ProcessType.HYPEREXP;
2458 sn.procid(i,j) = ProcessType.PH;
2460 sn.procid(i,j) = ProcessType.APH;
2462 sn.procid(i,j) = ProcessType.MAP;
2464 sn.procid(i,j) = ProcessType.UNIFORM;
2466 sn.procid(i,j) = ProcessType.DET;
2468 sn.procid(i,j) = ProcessType.COXIAN;
2470 sn.procid(i,j) = ProcessType.GAMMA;
2472 sn.procid(i,j) = ProcessType.PARETO;
2474 sn.procid(i,j) = ProcessType.WEIBULL;
2476 sn.procid(i,j) = ProcessType.LOGNORMAL;
2478 sn.procid(i,j) = ProcessType.MMPP2;
2480 sn.procid(i,j) = ProcessType.REPLAYER;
2482 sn.procid(i,j) = ProcessType.TRACE;
2484 sn.procid(i,j) = ProcessType.IMMEDIATE;
2486 sn.procid(i,j) = ProcessType.DISABLED;
2488 sn.procid(i,j) = ProcessType.COX2;
2490 sn.procid(i,j) = ProcessType.BMAP;
2492 sn.procid(i,j) = ProcessType.ME;
2494 sn.procid(i,j) = ProcessType.RAP;
2496 sn.procid(i,j) = ProcessType.BINOMIAL;
2498 sn.procid(i,j) = ProcessType.POISSON;
2500 sn.procid(i,j) = ProcessType.GEOMETRIC;
2502 sn.procid(i,j) = ProcessType.DUNIFORM;
2504 sn.procid(i,j) = ProcessType.BERNOULLI;
2506 sn.procid(i,j) = ProcessType.PRIOR;
2508 % Unknown ProcessType - default to DISABLED
2509 sn.procid(i,j) = ProcessType.DISABLED;
2518 sn.mu = cell(sn.nstations, 1);
2519 for i = 1:sn.nstations
2520 sn.mu{i} = cell(1, sn.nclasses);
2521 for j = 1:sn.nclasses
2522 sn.mu{i}{j} = JLINE.from_jline_matrix(jsn.mu.get(jstations.get(i-1)).get(jclasses.get(j-1)));
2529 if ~isempty(jsn.phi)
2530 sn.phi = cell(sn.nstations, 1);
2531 for i = 1:sn.nstations
2532 sn.phi{i} = cell(1, sn.nclasses);
2533 for j = 1:sn.nclasses
2534 sn.phi{i}{j} = JLINE.from_jline_matrix(jsn.phi.get(jstations.get(i-1)).get(jclasses.get(j-1)));
2541 if ~isempty(jsn.proc)
2542 sn.proc = cell(sn.nstations, 1);
2543 for i = 1:sn.nstations
2544 sn.proc{i} = cell(1, sn.nclasses);
2545 for j = 1:sn.nclasses
2546 proc_i_j = jsn.proc.get(jstations.get(i-1)).get(jclasses.get(j-1));
2547 sn.proc{i}{j} = cell(1, proc_i_j.size);
2548 for k = 1:proc_i_j.size
2549 sn.proc{i}{j}{k} = JLINE.from_jline_matrix(proc_i_j.get(uint32(k-1)));
2557 if ~isempty(jsn.pie)
2558 sn.pie = cell(sn.nstations, 1);
2559 for i = 1:sn.nstations
2560 sn.pie{i} = cell(1, sn.nclasses);
2561 for j = 1:sn.nclasses
2562 sn.pie{i}{j} = JLINE.from_jline_matrix(jsn.pie.get(jstations.get(i-1)).get(jclasses.get(j-1)));
2569 if ~isempty(jsn.sched)
2570 sn.sched = zeros(sn.nstations, 1);
2571 for i = 1:sn.nstations
2572 schedStrategy = jsn.sched.get(jstations.get(i-1));
2573 switch schedStrategy.name.toCharArray'
2575 sn.sched(i) = SchedStrategy.INF;
2577 sn.sched(i) = SchedStrategy.FCFS;
2579 sn.sched(i) = SchedStrategy.LCFS;
2581 sn.sched(i) = SchedStrategy.LCFSPR;
2583 sn.sched(i) = SchedStrategy.SIRO;
2585 sn.sched(i) = SchedStrategy.SJF;
2587 sn.sched(i) = SchedStrategy.LJF;
2589 sn.sched(i) = SchedStrategy.PS;
2591 sn.sched(i) = SchedStrategy.DPS;
2593 sn.sched(i) = SchedStrategy.GPS;
2595 sn.sched(i) = SchedStrategy.PSPRIO;
2597 sn.sched(i) = SchedStrategy.DPSPRIO;
2599 sn.sched(i) = SchedStrategy.GPSPRIO;
2601 sn.sched(i) = SchedStrategy.SEPT;
2603 sn.sched(i) = SchedStrategy.LEPT;
2604 case {
'HOL',
'FCFSPRIO'}
2605 sn.sched(i) = SchedStrategy.FCFSPRIO;
2607 sn.sched(i) = SchedStrategy.FORK;
2609 sn.sched(i) = SchedStrategy.EXT;
2611 sn.sched(i) = SchedStrategy.REF;
2618 if ~isempty(jsn.inchain)
2619 sn.inchain = cell(1, sn.nchains);
2620 for i = 1:sn.nchains
2621 sn.inchain{1,i} = JLINE.from_jline_matrix(jsn.inchain.get(uint32(i-1)))+1;
2627 if ~isempty(jsn.visits)
2628 sn.
visits = cell(sn.nchains, 1);
2629 for i = 1:sn.nchains
2630 sn.
visits{i,1} = JLINE.from_jline_matrix(jsn.visits.get(uint32(i-1)));
2636 if ~isempty(jsn.nodevisits)
2638 for i = 1:sn.nchains
2639 sn.
nodevisits{1,i} = JLINE.from_jline_matrix(jsn.nodevisits.get(uint32(i-1)));
2645 if ~isempty(jsn.droprule)
2646 sn.droprule = zeros(sn.nstations, sn.nclasses);
2647 for i = 1:sn.nstations
2648 for j = 1:sn.nclasses
2649 dropStrategy = jsn.droprule.get(jstations.get(i-1)).get(jclasses.get(j-1));
2650 switch dropStrategy.name.toCharArray'
2652 sn.droprule(i,j) = DropStrategy.WAITQ;
2654 sn.droprule(i,j) = DropStrategy.DROP;
2655 case 'BlockingAfterService'
2656 sn.droprule(i,j) = DropStrategy.BAS;
2664 if ~isempty(jsn.nodeparam)
2665 sn.nodeparam = cell(sn.nnodes, 1);
2668 jnode = jnodes.get(i-1);
2669 jparam = jsn.nodeparam.get(jnode);
2672 % sn.nodeparam{i} = [];
2677 if isa(jparam,
'jline.lang.nodeparam.StationNodeParam')
2678 if ~isempty(jparam.fileName)
2679 sn.nodeparam{i}.fileName = cell(1, sn.nclasses);
2680 for r = 1:sn.nclasses
2681 fname = jparam.fileName.get(r-1);
2683 sn.nodeparam{i}.fileName{r} = char(fname);
2689 % TransitionNodeParam
2690 if isa(jparam,
'jline.lang.nodeparam.TransitionNodeParam')
2691 if ~isempty(jparam.firingprocid)
2692 sn.nodeparam{i}.firingprocid = containers.Map(
'KeyType',
'char',
'ValueType',
'any');
2693 keys = jparam.firingprocid.keySet.iterator;
2696 proc = jparam.firingprocid.get(key);
2697 sn.nodeparam{i}.firingprocid(
char(key.toString)) = char(proc.toString);
2700 if ~isempty(jparam.firingphases)
2701 sn.nodeparam{i}.firingphases = JLINE.from_jline_matrix(jparam.firingphases);
2703 if ~isempty(jparam.fireweight)
2704 sn.nodeparam{i}.fireweight = JLINE.from_jline_matrix(jparam.fireweight);
2709 if isa(jparam,
'jline.lang.nodeparam.JoinNodeParam')
2710 if ~isempty(jparam.joinStrategy)
2711 sn.nodeparam{i}.joinStrategy = cell(1, sn.nclasses);
2712 sn.nodeparam{i}.fanIn = cell(1, sn.nclasses);
2713 for r = 1:sn.nclasses
2714 jclass = jclasses.get(r-1);
2715 joinStrategy = jparam.joinStrategy.get(jclass);
2716 if ~isempty(joinStrategy)
2717 strategyStr = char(joinStrategy.name.toString);
2720 sn.nodeparam{i}.joinStrategy{r} = JoinStrategy.STD;
2722 sn.nodeparam{i}.joinStrategy{r} = JoinStrategy.PARTIAL;
2724 sn.nodeparam{i}.joinStrategy{r} = strategyStr;
2726 sn.nodeparam{i}.fanIn{r} = jparam.fanIn.get(jclass);
2733 if isa(jparam,
'jline.lang.nodeparam.RoutingNodeParam')
2734 for r = 1:sn.nclasses
2735 jclass = jclasses.get(r-1);
2737 if ~isempty(jparam.weights) && jparam.weights.containsKey(jclass)
2738 sn.nodeparam{i}.weights{r} = JLINE.from_jline_matrix(jparam.weights.get(jclass));
2741 if ~isempty(jparam.outlinks) && jparam.outlinks.containsKey(jclass)
2742 sn.nodeparam{i}.outlinks{r} = JLINE.from_jline_matrix(jparam.outlinks.get(jclass));
2748 if isa(jparam,
'jline.lang.nodeparam.ForkNodeParam')
2749 if ~isnan(jparam.fanOut)
2750 sn.nodeparam{i}.fanOut = jparam.fanOut;
2755 if isa(jparam,
'jline.lang.nodeparam.CacheNodeParam')
2757 if ~isnan(jparam.nitems)
2758 sn.nodeparam{i}.nitems = jparam.nitems;
2762 if ~isempty(jparam.accost)
2763 % For Java 2D arrays (Matrix[][]), size(arr,2) returns 1 in MATLAB
2764 % We need to get length of first row to get actual second dimension
2765 K1 = size(jparam.accost, 1);
2767 firstRow = jparam.accost(1); % Get first row (Java
array)
2768 K2 = length(firstRow);
2772 sn.nodeparam{i}.accost = cell(K1, K2);
2775 mat = jparam.accost(k1, k2); % MATLAB handles Java
array indexing
2777 sn.nodeparam{i}.accost{k1, k2} = JLINE.from_jline_matrix(mat);
2784 if ~isempty(jparam.itemcap)
2785 sn.nodeparam{i}.itemcap = JLINE.from_jline_matrix(jparam.itemcap);
2788 % pread - convert from Java Map<Integer, List<Double>> to MATLAB cell
array {R}
2789 if ~isempty(jparam.pread)
2790 nclasses = sn.nclasses;
2791 sn.nodeparam{i}.pread = cell(1, nclasses);
2793 list = jparam.pread.get(int32(r-1)); % Java 0-based indexing
2795 values = zeros(1, list.size);
2797 values(j) = list.get(j-1);
2799 sn.nodeparam{i}.pread{r} = values;
2801 sn.nodeparam{i}.pread{r} = NaN;
2807 if ~isempty(jparam.replacestrat)
2808 switch
char(jparam.replacestrat)
2810 sn.nodeparam{i}.replacestrat = ReplacementStrategy.RR;
2812 sn.nodeparam{i}.replacestrat = ReplacementStrategy.FIFO;
2814 sn.nodeparam{i}.replacestrat = ReplacementStrategy.SFIFO;
2816 sn.nodeparam{i}.replacestrat = ReplacementStrategy.LRU;
2821 if ~isempty(jparam.hitclass)
2822 sn.nodeparam{i}.hitclass = 1+JLINE.from_jline_matrix(jparam.hitclass);
2826 if ~isempty(jparam.missclass)
2827 sn.nodeparam{i}.missclass =1+ JLINE.from_jline_matrix(jparam.missclass);
2830 % actual hit/miss probabilities
2831 if ~isempty(jparam.actualhitprob)
2832 sn.nodeparam{i}.actualhitprob = JLINE.from_jline_matrix(jparam.actualhitprob);
2834 if ~isempty(jparam.actualmissprob)
2835 sn.nodeparam{i}.actualmissprob = JLINE.from_jline_matrix(jparam.actualmissprob);
2843 %
if ~isempty(jsn.nodeparam)
2844 % sn.nodeparam = cell(sn.nnodes, 1);
2845 % % Note that JLINE only support node parameters related to
2846 % % Fork, Join, WWROBIN and RROBIN
2847 %
for i = 1:sn.nnodes
2848 %
if jsn.nodeparam.get(jnodes.get(i-1)).isEmpty
2849 % sn.nodeparam{i} = [];
2851 %
if ~isnan(jsn.nodeparam.get(jnodes.get(i-1)).nitems)
2852 % sn.nodeparam{i}.nitems = jsn.nodeparam.get(jnodes.get(i-1)).nitems;
2854 %
if ~isnan(jsn.nodeparam.get(jnodes.get(i-1)).fanOut)
2855 % sn.nodeparam{i}.fanOut = jsn.nodeparam.get(jnodes.get(i-1)).fanOut;
2857 %
if ~isempty(jsn.nodeparam.get(jnodes.get(i-1)).joinStrategy)
2858 %
if ~jsn.nodeparam.get(jnodes.get(i-1)).joinStrategy.isEmpty
2859 % sn.nodeparam{i}.joinStrategy = cell(1, sn.nclasses);
2860 % sn.nodeparam{i}.fanIn = cell(1, sn.nclasses);
2861 %
for r = 1:sn.nclasses
2862 % joinStrategy = jsn.nodeparam.get(jnodes.get(i-1)).joinStrategy.get(jclasses.get(r-1));
2863 %
switch joinStrategy.name.toCharArray
'
2865 % sn.nodeparam{i}.joinStrategy{r} = JoinStrategy.STD;
2867 % sn.nodeparam{i}.joinStrategy{r} = JoinStrategy.PARTIAL;
2869 % sn.nodeparam{i}.fanIn{r} = jsn.nodeparam.get(jnodes.get(i-1)).fanIn.get(jclasses.get(r-1));
2874 % if ~isempty(jsn.nodeparam.get(jnodes.get(i-1)).weights)
2875 % for r = 1:sn.nclasses
2876 % sn.nodeparam{i}{r}.weights = JLINE.from_jline_matrix(jsn.nodeparam.get(jnodes.get(i-1)).weights.get(jclasses.get(r-1)));
2880 % if ~isempty(jsn.nodeparam.get(jnodes.get(i-1)).outlinks)
2881 % for r = 1:sn.nclasses
2882 % sn.nodeparam{i}{r}.outlinks = JLINE.from_jline_matrix(jsn.nodeparam.get(jnodes.get(i-1)).outlinks.get(jclasses.get(r-1)));
2888 % sn.nodeparam = {};
2891 if ~isempty(jsn.sync)
2893 sn.sync = cell(jsync.size, 1);
2894 for i = 1:jsync.size
2895 jsync_i = jsync.get(uint32(i-1));
2896 sn.sync{i,1} = struct('active
',cell(1),'passive
',cell(1));
2898 jactive = jsync_i.active.get(uint32(0));
2899 jpassive = jsync_i.passive.get(uint32(0));
2901 %Currently assume that prob would always be a value
2902 %instead of lambda function (No idea of how to convert
2903 %Java lambda function to matlab lambda function)
2904 switch jactive.getEvent.name.toCharArray'
2906 sn.sync{i,1}.active{1} = Event(EventType.INIT, jactive.getNode+1, jactive.getJobClass+1, ...
2907 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2908 jactive.getT, jactive.getJob);
2910 sn.sync{i,1}.active{1} = Event(EventType.LOCAL, jactive.getNode+1, jactive.getJobClass+1, ...
2911 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2912 jactive.getT, jactive.getJob);
2914 sn.sync{i,1}.active{1} = Event(EventType.ARV, jactive.getNode+1, jactive.getJobClass+1, ...
2915 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2916 jactive.getT, jactive.getJob);
2918 sn.sync{i,1}.active{1} = Event(EventType.DEP, jactive.getNode+1, jactive.getJobClass+1, ...
2919 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2920 jactive.getT, jactive.getJob);
2922 sn.sync{i,1}.active{1} = Event(EventType.PHASE, jactive.getNode+1, jactive.getJobClass+1, ...
2923 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2924 jactive.getT, jactive.getJob);
2926 sn.sync{i,1}.active{1} = Event(EventType.READ, jactive.getNode+1, jactive.getJobClass+1, ...
2927 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2928 jactive.getT, jactive.getJob);
2930 sn.sync{i,1}.active{1} = Event(EventType.STAGE, jactive.getNode+1, jactive.getJobClass+1, ...
2931 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2932 jactive.getT, jactive.getJob);
2935 switch jpassive.getEvent.name.toCharArray
'
2937 sn.sync{i,1}.passive{1} = Event(EventType.INIT, jpassive.getNode+1, jpassive.getJobClass+1, ...
2938 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2939 jpassive.getT, jpassive.getJob);
2941 sn.sync{i,1}.passive{1} = Event(EventType.LOCAL, jpassive.getNode+1, jpassive.getJobClass+1, ...
2942 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2943 jpassive.getT, jpassive.getJob);
2945 sn.sync{i,1}.passive{1} = Event(EventType.ARV, jpassive.getNode+1, jpassive.getJobClass+1, ...
2946 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2947 jpassive.getT, jpassive.getJob);
2949 sn.sync{i,1}.passive{1} = Event(EventType.DEP, jpassive.getNode+1, jpassive.getJobClass+1, ...
2950 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2951 jpassive.getT, jpassive.getJob);
2953 sn.sync{i,1}.passive{1} = Event(EventType.PHASE, jpassive.getNode+1, jpassive.getJobClass+1, ...
2954 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2955 jpassive.getT, jpassive.getJob);
2957 sn.sync{i,1}.passive{1} = Event(EventType.READ, jpassive.getNode+1, jpassive.getJobClass+1, ...
2958 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2959 jpassive.getT, jpassive.getJob);
2961 sn.sync{i,1}.passive{1} = Event(EventType.STAGE, jpassive.getNode+1, jpassive.getJobClass+1, ...
2962 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2963 jpassive.getT, jpassive.getJob);
2971 function [QN,UN,RN,WN,AN,TN] = arrayListToResults(alist)
2973 case 'jline.solvers.LayeredNetworkAvgTable
'
2974 QN = JLINE.arraylist_to_matrix(alist.getQLen());
2975 UN = JLINE.arraylist_to_matrix(alist.getUtil());
2976 RN = JLINE.arraylist_to_matrix(alist.getRespT());
2977 WN = JLINE.arraylist_to_matrix(alist.getResidT());
2978 AN = NaN*JLINE.arraylist_to_matrix(alist.getTput()); % getArvR not yet available in JLINE
2979 TN = JLINE.arraylist_to_matrix(alist.getTput());
2981 QN = JLINE.arraylist_to_matrix(alist.getQLen());
2982 UN = JLINE.arraylist_to_matrix(alist.getUtil());
2983 RN = JLINE.arraylist_to_matrix(alist.getRespT());
2984 WN = JLINE.arraylist_to_matrix(alist.getResidT());
2985 AN = JLINE.arraylist_to_matrix(alist.getArvR());
2986 TN = JLINE.arraylist_to_matrix(alist.getTput());
2990 function featSupported = getFeatureSet()
2991 % FEATSUPPORTED = GETFEATURESET()
2993 featSupported = SolverFeatureSet;
2994 featSupported.setTrue({'Sink
','Source
',...
2995 'ClassSwitch
','Delay
','DelayStation
','Queue
',...
2996 'APH
','Coxian
','Erlang
','Exp
','HyperExp
',...
2997 'StatelessClassSwitcher
','InfiniteServer
','SharedServer
','Buffer
','Dispatcher
',...
2998 'Server
','JobSink
','RandomSource
','ServiceTunnel
',...
2999 'SchedStrategy_INF
','SchedStrategy_PS
',...
3000 'RoutingStrategy_PROB
','RoutingStrategy_RAND
',...
3001 'ClosedClass
','OpenClass
'});
3004 function [bool, featSupported] = supports(model)
3005 % [BOOL, FEATSUPPORTED] = SUPPORTS(MODEL)
3007 featUsed = model.getUsedLangFeatures();
3008 featSupported = JLINE.getFeatureSet();
3009 bool = SolverFeatureSet.supports(featSupported, featUsed);
3013 function solverOptions = parseSolverOptions(solverOptions, options)
3014 fn = fieldnames(options);
3015 fn2 = fieldnames(solverOptions);
3016 for f = 1:length(fn)
3018 for j = 1:length(fn2)
3019 if strcmp(fn{f}, fn2{j})
3023 solverOptions.seed = options.seed;
3025 solverOptions.samples = options.samples;
3027 % Parse confint - can be a level (0.95) or 0 to disable
3028 [confintEnabled, confintLevel] = Solver.parseConfInt(options.confint);
3030 solverOptions.confint = confintLevel;
3032 solverOptions.confint = 0;
3035 solverOptions.method = options.method;
3037 if isfield(options.config,'eventcache
')
3038 solverOptions.config.eventcache = options.config.eventcache;
3040 if isfield(options.config,'fork_join
')
3041 solverOptions.config.fork_join = options.config.fork_join;
3043 if isfield(options.config,'highvar
')
3044 solverOptions.config.highvar = options.config.highvar;
3046 if isfield(options.config,'multiserver
')
3047 solverOptions.config.multiserver = options.config.multiserver;
3049 if isfield(options.config,'np_priority
')
3050 solverOptions.config.np_priority = options.config.np_priority;
3053 switch options.(fn{f})
3054 case {VerboseLevel.SILENT}
3055 solverOptions.verbose = solverOptions.verbose.SILENT;
3056 case {VerboseLevel.STD}
3057 solverOptions.verbose = solverOptions.verbose.STD;
3058 case {VerboseLevel.DEBUG}
3059 solverOptions.verbose = solverOptions.verbose.DEBUG;
3062 solverOptions.(fn{f}) = JLINE.from_line_matrix(options.init_sol);
3064 if isscalar(options.cutoff)
3065 solverOptions.(fn{f}) = jline.util.matrix.Matrix.singleton(options.cutoff);
3067 solverOptions.(fn{f}) = JLINE.from_line_matrix(options.cutoff);
3070 case 'rewardIterations
'
3071 solverOptions.rewardIterations = java.lang.Integer(options.rewardIterations);
3073 solverOptions.(fn{f}) = options.(fn{f});
3080 line_printf('Could not find option %s in the JLINE options.\n
', fn{f});
3085 function [ssa] = SolverSSA(network_object, options)
3086 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.SSA);
3088 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3090 jline.util.Maths.setRandomNumbersMatlab(true);
3091 ssa = jline.solvers.ssa.SolverSSA(network_object, solverOptions);
3094 function [qns] = SolverQNS(network_object, options)
3095 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.QNS);
3097 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3099 qns = jline.solvers.qns.SolverQNS(network_object, solverOptions);
3102 function [mam] = SolverMAM(network_object, options)
3103 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.MAM);
3105 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3107 mam = jline.solvers.mam.SolverMAM(network_object, solverOptions);
3110 function [jmt] = SolverJMT(network_object, options)
3111 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.JMT);
3113 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3115 jmt = jline.solvers.jmt.SolverJMT(network_object, solverOptions);
3118 function [ctmc] = SolverCTMC(network_object, options)
3119 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.CTMC);
3121 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3123 ctmc = jline.solvers.ctmc.SolverCTMC(network_object,solverOptions);
3126 function [fluid] = SolverFluid(network_object, options)
3127 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.FLUID);
3129 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3131 fluid = jline.solvers.fluid.SolverFluid(network_object, solverOptions);
3134 function [QN, UN, RN, TN, CN, XN, t, QNt, UNt, TNt, xvec] = runFluidAnalyzer(network, options)
3135 % RUNFLUIDANALYZER Run JLINE fluid analyzer and return results
3137 % [QN, UN, RN, TN, CN, XN, T, QNT, UNT, TNT, XVEC] = JLINE.runFluidAnalyzer(NETWORK, OPTIONS)
3139 % Runs the JLINE fluid solver on the given network and converts
3140 % results back to MATLAB data structures.
3143 % network - LINE Network model
3144 % options - Solver options structure with fields:
3145 % .method - solver method
3146 % .stiff - use stiff ODE solver
3149 % QN, UN, RN, TN - Steady-state metrics [M x K]
3150 % CN, XN - System metrics [1 x K]
3151 % t - Time vector [Tmax x 1]
3152 % QNt, UNt, TNt - Transient metrics {M x K} cells
3153 % xvec - State vector structure
3155 jmodel = LINE2JLINE(network);
3156 jsolver = JLINE.SolverFluid(jmodel);
3157 import jline.solvers.fluid.*;
3159 jsolver.options.method = options.method;
3160 jsolver.options.stiff = options.stiff;
3161 result = jsolver.runMethodSpecificAnalyzerViaLINE();
3163 % Convert JLINE result to MATLAB data structures
3164 M = jmodel.getNumberOfStatefulNodes();
3165 K = jmodel.getNumberOfClasses();
3167 QN = NaN * zeros(M, K);
3168 UN = NaN * zeros(M, K);
3169 RN = NaN * zeros(M, K);
3170 TN = NaN * zeros(M, K);
3171 CN = NaN * zeros(1, K);
3172 XN = NaN * zeros(1, K);
3178 Tmax = result.t.length();
3179 t = NaN * zeros(Tmax, 1);
3183 QN(ist, jst) = result.QN.get(ist-1, jst-1);
3184 UN(ist, jst) = result.UN.get(ist-1, jst-1);
3185 RN(ist, jst) = result.RN.get(ist-1, jst-1);
3186 TN(ist, jst) = result.TN.get(ist-1, jst-1);
3191 CN(1, jst) = result.CN.get(0, jst-1);
3192 XN(1, jst) = result.XN.get(0, jst-1);
3198 QNt{ist, jst}(p, 1) = result.QNt(ist, jst).get(p-1, 0);
3199 UNt{ist, jst}(p, 1) = result.UNt(ist, jst).get(p-1, 0);
3200 TNt{ist, jst}(p, 1) = result.TNt(ist, jst).get(p-1, 0);
3206 t(p, 1) = result.t.get(p-1, 0);
3209 % JLINE does not return odeStateVec
3210 xvec.odeStateVec = [];
3214 function [ldes] = SolverLDES(network_object, options)
3215 % Create LDES-specific options object
3216 ldesOptions = jline.solvers.ldes.LDESOptions();
3218 % Copy standard options
3219 ldesOptions.samples = options.samples;
3220 ldesOptions.seed = options.seed;
3222 [confintEnabled, confintLevel] = Solver.parseConfInt(options.confint);
3224 ldesOptions.confint = confintLevel;
3226 ldesOptions.confint = 0;
3228 % Pass timespan for transient analysis
3229 if isfield(options, 'timespan
') && length(options.timespan) >= 2
3230 ldesOptions.timespan = options.timespan;
3232 % Pass LDES-specific options if configured
3233 if isfield(options, 'config
')
3234 % Transient detection options
3235 if isfield(options.config, 'tranfilter
')
3236 ldesOptions.tranfilter = options.config.tranfilter;
3238 if isfield(options.config, 'mserbatch
')
3239 ldesOptions.mserbatch = options.config.mserbatch;
3241 if isfield(options.config, 'warmupfrac
')
3242 ldesOptions.warmupfrac = options.config.warmupfrac;
3244 % Confidence interval options
3245 if isfield(options.config, 'cimethod
')
3246 ldesOptions.cimethod = options.config.cimethod;
3248 if isfield(options.config, 'obmoverlap
')
3249 ldesOptions.obmoverlap = options.config.obmoverlap;
3251 if isfield(options.config, 'ciminbatch
')
3252 ldesOptions.ciminbatch = options.config.ciminbatch;
3254 if isfield(options.config, 'ciminobs
')
3255 ldesOptions.ciminobs = options.config.ciminobs;
3257 if isfield(options.config, 'spectralLowFreqFrac
')
3258 ldesOptions.spectralLowFreqFrac = options.config.spectralLowFreqFrac;
3260 % Convergence options
3261 if isfield(options.config, 'cnvgon
')
3262 ldesOptions.cnvgon = options.config.cnvgon;
3264 if isfield(options.config, 'cnvgtol
')
3265 ldesOptions.cnvgtol = options.config.cnvgtol;
3267 if isfield(options.config, 'cnvgbatch
')
3268 ldesOptions.cnvgbatch = options.config.cnvgbatch;
3270 if isfield(options.config, 'cnvgchk
')
3271 ldesOptions.cnvgchk = options.config.cnvgchk;
3275 ldes = jline.solvers.ldes.SolverLDES(network_object, ldesOptions);
3278 function [mva] = SolverMVA(network_object, options)
3279 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.MVA);
3281 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3283 mva = jline.solvers.mva.SolverMVA(network_object, solverOptions);
3286 function [nc] = SolverNC(network_object, options)
3287 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.NC);
3289 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3291 nc = jline.solvers.nc.SolverNC(network_object, solverOptions);
3294 function [auto] = SolverAuto(network_object, options)
3295 solverOptions = jline.solvers.auto.AUTOptions();
3297 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3299 auto = jline.solvers.auto.SolverAUTO(network_object, solverOptions);
3302 function streamOpts = StreamingOptions(varargin)
3303 % STREAMINGOPTIONS Create Java StreamingOptions for SSA/LDES stream() method
3305 % @brief Creates StreamingOptions for streaming simulation metrics
3307 % @param varargin Name-value pairs for options:
3308 % 'transport
' - 'http
' (recommended) or 'grpc
' (default: 'http
')
3309 % 'endpoint
' - Receiver endpoint (default: 'localhost:8080/metrics
' for HTTP)
3310 % 'mode
' - 'sampled
' or 'time_window
' (default: 'sampled
')
3311 % 'sampleFrequency
' - Push every N events in sampled mode (default: 100)
3312 % 'timeWindowSeconds
' - Window duration in time_window mode (default: 1.0)
3313 % 'serviceName
' - Service identifier (default: 'line-stream')
3314 % 'includeQueueLength' - Include queue length metrics (default: true)
3315 % 'includeUtilization' - Include utilization metrics (default: true)
3316 % 'includeThroughput' - Include throughput metrics (default: true)
3317 % 'includeResponseTime' - Include response time metrics (default: true)
3318 % 'includeArrivalRate' - Include arrival rate metrics (default: true)
3320 % @return streamOpts Java StreamingOptions object
3324 % streamOpts = JLINE.StreamingOptions('transport', 'http', 'sampleFrequency', 50);
3327 streamOpts = jline.streaming.StreamingOptions();
3329 % Parse optional arguments
3331 addParameter(p,
'transport',
'http', @ischar);
3332 addParameter(p,
'endpoint',
'', @ischar); % Empty means use
default for transport
3333 addParameter(p,
'mode',
'sampled', @ischar);
3334 addParameter(p,
'sampleFrequency', 100, @isnumeric);
3335 addParameter(p,
'timeWindowSeconds', 1.0, @isnumeric);
3336 addParameter(p,
'serviceName',
'line-stream', @ischar);
3337 addParameter(p,
'includeQueueLength',
true, @islogical);
3338 addParameter(p,
'includeUtilization',
true, @islogical);
3339 addParameter(p,
'includeThroughput',
true, @islogical);
3340 addParameter(p,
'includeResponseTime',
true, @islogical);
3341 addParameter(p,
'includeArrivalRate',
true, @islogical);
3342 parse(p, varargin{:});
3344 % Set transport type
3345 transportTypes = javaMethod(
'values',
'jline.streaming.StreamingOptions$TransportType');
3346 switch lower(p.Results.transport)
3348 streamOpts.transport = transportTypes(1); % HTTP
3350 streamOpts.transport = transportTypes(2); % GRPC
3352 streamOpts.transport = transportTypes(1); % Default to HTTP
3355 % Set endpoint (use provided or default based on transport)
3356 if ~isempty(p.Results.endpoint)
3357 streamOpts.endpoint = p.Results.endpoint;
3359 % If empty, StreamingOptions uses its default for the transport type
3362 streamModes = javaMethod('values', 'jline.streaming.StreamingOptions$StreamMode');
3363 switch lower(p.Results.mode)
3365 streamOpts.mode = streamModes(1); % SAMPLED
3367 streamOpts.mode = streamModes(2); % TIME_WINDOW
3369 streamOpts.mode = streamModes(1); % Default to SAMPLED
3373 streamOpts.sampleFrequency = p.Results.sampleFrequency;
3374 streamOpts.timeWindowSeconds = p.Results.timeWindowSeconds;
3375 streamOpts.serviceName = p.Results.serviceName;
3376 streamOpts.includeQueueLength = p.Results.includeQueueLength;
3377 streamOpts.includeUtilization = p.Results.includeUtilization;
3378 streamOpts.includeThroughput = p.Results.includeThroughput;
3379 streamOpts.includeResponseTime = p.Results.includeResponseTime;
3380 streamOpts.includeArrivalRate = p.Results.includeArrivalRate;
3383 function result = convertSampleResult(jresult)
3384 % CONVERTSAMPLERESULT Convert Java sample result to MATLAB struct
3386 % @brief Converts Java SampleNodeState to MATLAB structure
3388 % @param jresult Java SampleNodeState
object
3389 % @return result MATLAB struct with fields: t, state, isaggregate
3393 % Convert time matrix
3394 if ~isempty(jresult.t)
3395 result.t = JLINE.from_jline_matrix(jresult.t);
3400 % Convert state matrix
3401 if ~isempty(jresult.state) && isa(jresult.state, 'jline.util.matrix.Matrix')
3402 result.state = JLINE.from_jline_matrix(jresult.state);
3407 result.isaggregate = jresult.isaggregate;
3410 function [ln] = SolverLN(layered_network_object, options)
3411 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.LN);
3413 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3415 ln = jline.solvers.ln.SolverLN(layered_network_object, solverOptions);
3418 function serfun = handle_to_serializablefun(handle, sn)
3419 % HANDLE_TO_SERIALIZABLEFUN Convert MATLAB function handle to Java SerializableFunction
3421 % This function pre-computes the function values for all possible state
3422 % combinations and creates a Java PrecomputedCDFunction
object.
3424 % @param handle MATLAB function handle that takes a vector ni and returns a scalar
3425 % @param sn Network struct containing njobs (population per class)
3426 % @return serfun Java PrecomputedCDFunction
object
3428 % Get number of
classes and maximum populations
3429 nclasses = sn.nclasses;
3430 njobs = sn.njobs; % Population per class
3432 % For open
classes (njobs=0), use a reasonable bound
3435 if maxPop(r) == 0 || isinf(maxPop(r))
3436 % For open
classes, use sum of closed class populations or 100 as bound
3437 maxPop(r) = max(100, sum(njobs(isfinite(njobs) & njobs > 0)));
3441 % Create Java PrecomputedCDFunction
object
3442 serfun = jline.util.PrecomputedCDFunction(nclasses);
3444 % Enumerate all possible state combinations and pre-compute function values
3445 % Use recursive enumeration to handle arbitrary number of
classes
3446 JLINE.enumerate_states(handle, serfun, maxPop, zeros(1, nclasses), 1);
3449 function enumerate_states(handle, serfun, maxPop, currentState, classIdx)
3450 % ENUMERATE_STATES Recursively enumerate all state combinations
3452 % @param handle MATLAB function handle
3453 % @param serfun Java PrecomputedCDFunction
object to populate
3454 % @param maxPop Maximum population per class
3455 % @param currentState Current state being built
3456 % @param classIdx Current class index being enumerated
3458 nclasses = length(maxPop);
3460 if classIdx > nclasses
3461 % We have a complete state, compute and store the function value
3463 value = handle(currentState);
3464 % Convert to Java
int array and add to serfun
3465 jstate = jline.util.matrix.Matrix(1, nclasses);
3467 jstate.set(0, r-1, currentState(r));
3469 serfun.addValue(jstate, value);
3471 % If function evaluation fails, skip this state
3476 % Enumerate all populations for current class
3477 for n = 0:maxPop(classIdx)
3478 currentState(classIdx) = n;
3479 JLINE.enumerate_states(handle, serfun, maxPop, currentState, classIdx + 1);
3483 function result = call_java_cdscaling(jfun, ni)
3484 % CALL_JAVA_CDSCALING Call a Java SerializableFunction for class dependence
3486 % This function converts a MATLAB vector to a Java Matrix and calls
3487 % the Java function's apply() method.
3489 % @param jfun Java SerializableFunction<Matrix, Double>
object
3490 % @param ni MATLAB vector representing the state (jobs per class)
3491 % @return result The scaling factor returned by the Java function
3493 % Convert MATLAB vector to Java Matrix
3495 jmatrix = jline.util.matrix.Matrix(1, length(ni));
3496 for r = 1:length(ni)
3497 jmatrix.set(0, r-1, ni(r));
3500 jmatrix = jline.util.matrix.Matrix(length(ni), 1);
3501 for r = 1:length(ni)
3502 jmatrix.set(r-1, 0, ni(r));
3506 % Call the Java function and convert result to MATLAB
double
3507 jresult = jfun.apply(jmatrix);
3508 result =
double(jresult);
3511 function jSched = to_jline_sched_strategy(schedId)
3512 % Convert MATLAB SchedStrategy
id to jline SchedStrategy enum
3514 case SchedStrategy.REF
3515 jSched = jline.lang.constant.SchedStrategy.REF;
3516 case SchedStrategy.INF
3517 jSched = jline.lang.constant.SchedStrategy.INF;
3518 case SchedStrategy.FCFS
3519 jSched = jline.lang.constant.SchedStrategy.FCFS;
3520 case SchedStrategy.LCFS
3521 jSched = jline.lang.constant.SchedStrategy.LCFS;
3522 case SchedStrategy.SIRO
3523 jSched = jline.lang.constant.SchedStrategy.SIRO;
3524 case SchedStrategy.SJF
3525 jSched = jline.lang.constant.SchedStrategy.SJF;
3526 case SchedStrategy.LJF
3527 jSched = jline.lang.constant.SchedStrategy.LJF;
3528 case SchedStrategy.PS
3529 jSched = jline.lang.constant.SchedStrategy.PS;
3530 case SchedStrategy.DPS
3531 jSched = jline.lang.constant.SchedStrategy.DPS;
3532 case SchedStrategy.GPS
3533 jSched = jline.lang.constant.SchedStrategy.GPS;
3534 case SchedStrategy.SEPT
3535 jSched = jline.lang.constant.SchedStrategy.SEPT;
3536 case SchedStrategy.LEPT
3537 jSched = jline.lang.constant.SchedStrategy.LEPT;
3538 case {SchedStrategy.HOL, SchedStrategy.FCFSPRIO}
3539 jSched = jline.lang.constant.SchedStrategy.FCFSPRIO;
3540 case SchedStrategy.FORK
3541 jSched = jline.lang.constant.SchedStrategy.FORK;
3542 case SchedStrategy.EXT
3543 jSched = jline.lang.constant.SchedStrategy.EXT;
3544 case SchedStrategy.LCFSPR
3545 jSched = jline.lang.constant.SchedStrategy.LCFSPR;
3546 case SchedStrategy.PSPRIO
3547 jSched = jline.lang.constant.SchedStrategy.PSPRIO;
3548 case SchedStrategy.DPSPRIO
3549 jSched = jline.lang.constant.SchedStrategy.DPSPRIO;
3550 case SchedStrategy.GPSPRIO
3551 jSched = jline.lang.constant.SchedStrategy.GPSPRIO;
3553 jSched = jline.lang.constant.SchedStrategy.FCFS;
3557 function jwf = from_line_workflow(line_wf)
3558 % Convert a MATLAB Workflow to a JAR Workflow.
3559 jwf = javaObject(
'jline.lang.workflow.Workflow', java.lang.String(line_wf.getName()));
3560 acts = line_wf.activities;
3561 for a = 1:length(acts)
3563 actName = java.lang.String(act.name);
3564 if ~isempty(act.hostDemand) && isa(act.hostDemand,
'Distribution')
3565 jdist = JLINE.from_line_distribution(act.hostDemand);
3566 jwf.addActivity(actName, jdist);
3568 jwf.addActivity(actName, 1.0);
3571 precs = line_wf.precedences;
3572 for p = 1:length(precs)
3574 preActs = java.util.ArrayList();
3575 for k = 1:length(prec.preActs)
3576 preActs.add(java.lang.String(prec.preActs{k}));
3578 postActs = java.util.ArrayList();
3579 for k = 1:length(prec.postActs)
3580 postActs.add(java.lang.String(prec.postActs{k}));
3582 preTypeStr = java.lang.String(ActivityPrecedenceType.toText(prec.preType));
3583 postTypeStr = java.lang.String(ActivityPrecedenceType.toText(prec.postType));
3584 if ~isempty(prec.preParams)
3585 preParamsMat = JLINE.from_line_matrix(prec.preParams(:)');
3587 preParamsMat = javaObject('jline.util.matrix.Matrix', 0, 0);
3589 if ~isempty(prec.postParams)
3590 postParamsMat = JLINE.from_line_matrix(prec.postParams(:)');
3592 postParamsMat = javaObject('jline.util.matrix.Matrix', 0, 0);
3594 jprec = javaObject('jline.lang.layered.ActivityPrecedence', ...
3595 preActs, postActs, preTypeStr, postTypeStr, preParamsMat, postParamsMat);
3596 jwf.addPrecedence(jprec);
3600 function jenv = from_line_environment(line_env)
3601 % Convert a MATLAB Environment to a JAR Environment.
3602 E = height(line_env.envGraph.Nodes);
3603 jenv = javaObject('jline.lang.Environment', java.lang.String(line_env.getName()), int32(E));
3605 stageName =
char(line_env.envGraph.Nodes.Name{e});
3606 stageType = char(line_env.envGraph.Nodes.Type{e});
3607 stageModel = line_env.ensemble{e};
3608 jmodel = JLINE.from_line_network(stageModel);
3609 jenv.addStage(int32(e-1), java.lang.String(stageName), java.lang.String(stageType), jmodel);
3611 if ~isempty(line_env.env)
3612 [Erows, Ecols] = size(line_env.env);
3615 d = line_env.env{e,h};
3616 if isempty(d) || isa(d,
'Disabled')
3619 jdist = JLINE.from_line_distribution(d);
3620 jenv.addTransition(int32(e-1), int32(h-1), jdist);