1classdef JNetwork < Model
2 % JLINE extended queueing network model.
4 % Copyright (c) 2012-2026, Imperial College London
7 properties (Access=
public)
12 methods (Access=public)
15 function self = JNetwork(name)
16 % SELF = NETWORK(MODELNAME)
17 self@Model(name); % model
is the model's name
18 self.obj = jline.lang.Network(name);
21 function sn = getStruct(self, wantInitialState) % get abritrary representation
23 wantInitialState = false;
25 sn = JLINE.from_jline_struct(self.obj, self.obj.getStruct(wantInitialState));
28 function R = getNumberOfClasses(self)
29 % R = GETNUMBEROFCLASSES()
31 R = self.obj.getNumberOfClasses();
34 function M = getNumberOfStations(self)
35 % M = GETNUMBEROFSTATIONS()
37 M = self.obj.getNumberOfStations();
41 function I = getNumberOfNodes(self)
42 % I = GETNUMBEROFNODES()
44 I = self.obj.getNumberOfNodes();
47 function
bool = hasFork(self)
52 function ind = getNodeIndex(self, name)
54 ind = self.obj.getNodeByName(name);
56 ind = self.obj.getNodeIndex(name.obj);
60 function node = getNodeByName(self, name)
61 % NODE = GETNODEBYNAME(NAME)
63 javaNode = self.obj.getNodeByName(name);
67 % Create a wrapper MATLAB
object for the Java node
68 % We need to determine the node type and create appropriate wrapper
69 nodeClassName =
char(javaNode.getClass().getSimpleName());
71 % Create the MATLAB wrapper
object, then override the Java
object
74 node = Queue(self,
char(javaNode.getName()), SchedStrategy.FCFS); % Default schedule strategy
76 node = Source(self,
char(javaNode.getName()));
78 node = Sink(self,
char(javaNode.getName()));
80 node = Router(self,
char(javaNode.getName()));
82 node = Fork(self,
char(javaNode.getName()));
84 node = Join(self,
char(javaNode.getName()));
86 % Cache requires additional parameters, using defaults
87 node = Cache(self,
char(javaNode.getName()), 1, [1], ReplacementStrategy.LRU);
89 node = Logger(self,
char(javaNode.getName()), 'default.log');
91 node = ClassSwitch(self,
char(javaNode.getName()));
93 node = Place(self,
char(javaNode.getName()));
95 node = Transition(self,
char(javaNode.getName()));
97 % Fallback - create generic Node wrapper
98 node = Node(
char(javaNode.getName()));
102 % Override the Java
object with the existing one from the network
104 node.index = self.obj.getNodeIndex(javaNode);
108 function self = link(self,
P)
109 if isa(
P,'jline.lang.RoutingMatrix')
112 nodes = self.obj.getNodes();
113 classes = self.obj.getClasses();
114 routing_matrix = jline.lang.RoutingMatrix(self.obj,
classes,
nodes);
115 I = self.obj.getNumberOfNodes;
116 R = self.obj.getNumberOfClasses;
130 else %
if a single matrix
139 self.obj.link(routing_matrix);
143 function
P = initRoutingMatrix(self)
144 M = self.getNumberOfNodes();
145 R = self.getNumberOfClasses();
146 P = cellzeros(R,R,M,M);
147 P = RoutingMatrix(
P);
150 function self = setChecks(self,
bool)
151 self.obj.setChecks(
bool);
154 function addLinks(self, nodesList)
155 % ADDLINKS(NODESLIST)
157 % Copyright (c) 2012-2026, Imperial College London
158 % All rights reserved.
159 for i=1:size(nodesList,1)
160 self.obj.addLink(self.obj.getNodeByIndex(nodesList(i,1)-1), self.obj.getNodeByIndex(nodesList(i,2)-1));
164 function addLink(self, node1, node2)
167 % Copyright (c) 2012-2026, Imperial College London
168 % All rights reserved.
169 self.obj.addLink(node1.obj, node2.obj);
176 function jsimgView(self)
177 self.obj.jsimgView();
180 % Additional methods for coherence with MNetwork
182 function
nodes = getNodes(self)
184 javaNodes = self.obj.getNodes();
186 for i = 0:javaNodes.size()-1
187 jNode = javaNodes.get(i);
188 nodes{end+1} = self.getNodeByName(
char(jNode.getName()));
192 function
classes = getClasses(self)
193 % CLASSES = GETCLASSES()
194 javaClasses = self.obj.getClasses();
196 for i = 0:javaClasses.size()-1
197 jClass = javaClasses.get(i);
198 % Note: Java
object wrapping
for classes not implemented
203 function classNames = getClassNames(self)
204 % CLASSNAMES = GETCLASSNAMES()
205 javaClasses = self.obj.getClasses();
207 for i = 0:javaClasses.size()-1
208 classNames{end+1} = char(javaClasses.get(i).getName());
212 function nodeNames = getNodeNames(self)
213 % NODENAMES = GETNODENAMES()
214 javaNodes = self.obj.getNodes();
216 for i = 0:javaNodes.size()-1
217 nodeNames{end+1} = char(javaNodes.get(i).getName());
221 function nodeTypes = getNodeTypes(self)
222 % NODETYPES = GETNODETYPES()
223 javaNodeTypes = self.obj.getNodeTypes();
225 for i = 0:javaNodeTypes.size()-1
226 nodeTypes{end+1} = char(javaNodeTypes.get(i).toString());
230 function stationNames = getStationNames(self)
231 % STATIONNAMES = GETSTATIONNAMES()
232 % Note: Java
object does not support getStationNames method directly
233 nodes = self.getNodes();
235 for i = 1:length(
nodes)
236 if isa(
nodes{i},
'Station')
237 stationNames{end+1} =
nodes{i}.getName();
242 function stationIndex = getStationIndex(self, name)
243 % STATIONINDEX = GETSTATIONINDEX(NAME)
246 name = node.getName();
248 stationIndex = find(cellfun(@(c) strcmp(c,name),self.getStationNames));
251 function classIndex = getClassIndex(self, name)
252 % CLASSINDEX = GETCLASSINDEX(NAME)
253 if isa(name,'JobClass')
257 classIndex = find(cellfun(@(c) strcmp(c,name),self.getClassNames));
260 function station = getStationByName(self, name)
261 % STATION = GETSTATIONBYNAME(NAME)
262 node = self.getNodeByName(name);
263 if isa(node, 'Station')
270 function class = getClassByName(self, name)
271 % CLASS = GETCLASSBYNAME(NAME)
272 javaClass = self.obj.getClassByName(name);
273 if isempty(javaClass)
276 % Note: Java
object wrapping for
classes not implemented
281 function node = getNodeByIndex(self, idx)
282 % NODE = GETNODEBYINDEX(IDX)
283 javaNode = self.obj.getNodeByIndex(idx-1); % Java uses 0-based indexing
287 node = self.getNodeByName(
char(javaNode.getName()));
291 function station = getStationByIndex(self, idx)
292 % STATION = GETSTATIONBYINDEX(IDX)
293 stations = self.getStationNames();
294 if idx > 0 && idx <= length(stations)
295 station = self.getStationByName(stations{idx});
301 function
class = getClassByIndex(self, idx)
302 % CLASS = GETCLASSBYINDEX(IDX)
303 javaClass = self.obj.getClassByIndex(idx-1); % Java uses 0-based indexing
304 if isempty(javaClass)
307 % Note: Java
object wrapping
for classes not implemented
312 function C = getNumberOfChains(self)
313 % C = GETNUMBEROFCHAINS()
314 sn = self.getStruct();
318 function S = getNumberOfStatefulNodes(self)
319 % S = GETNUMBEROFSTATEFULNODES()
320 % Note: Java
object does not support this method directly
321 nodes = self.getNodes();
322 S = sum(cellfun(@(n) isa(n, 'StatefulNode'),
nodes));
325 function list = getStationIndexes(self)
326 % LIST = GETSTATIONINDEXES()
327 nodes = self.getNodes();
328 list = find(cellfun(@(n) isa(n, 'Station'),
nodes))';
331 function list = getIndexStatefulNodes(self)
332 % LIST = GETINDEXSTATEFULNODES()
333 nodes = self.getNodes();
334 list = find(cellfun(@(n) isa(n, 'StatefulNode'),
nodes))';
337 function index = getIndexSourceStation(self)
338 % INDEX = GETINDEXSOURCESTATION()
339 % Note: Java
object does not support this method directly
340 nodes = self.getNodes();
341 for i = 1:length(
nodes)
342 if isa(
nodes{i},
'Source')
350 function index = getIndexSourceNode(self)
351 % INDEX = GETINDEXSOURCENODE()
352 % Note: Java
object does not support
this method directly
353 nodes = self.getNodes();
354 for i = 1:length(
nodes)
355 if isa(
nodes{i},
'Source')
363 function index = getIndexSinkNode(self)
364 % INDEX = GETINDEXSINKNODE()
365 % Note: Java
object does not support
this method directly
366 nodes = self.getNodes();
367 for i = 1:length(
nodes)
368 if isa(
nodes{i},
'Sink')
376 function node = getSource(self)
378 idx = self.getIndexSourceNode();
380 node = self.getNodeByIndex(idx);
386 function node = getSink(self)
388 idx = self.getIndexSinkNode();
390 node = self.getNodeByIndex(idx);
396 function N = getNumberOfJobs(self)
397 % N = GETNUMBEROFJOBS()
398 javaClasses = self.obj.getClasses();
399 N = zeros(1, javaClasses.size());
400 for i = 0:javaClasses.size()-1
401 jClass = javaClasses.get(i);
402 if strcmp(
char(jClass.getClass().getSimpleName()), 'ClosedClass')
403 N(i+1) = jClass.getPopulation();
410 function
bool = hasOpenClasses(self)
411 % BOOL = HASOPENCLASSES()
412 N = self.getNumberOfJobs();
413 bool = any(isinf(N));
416 function
bool = hasClosedClasses(self)
417 % BOOL = HASCLOSEDCLASSES()
418 N = self.getNumberOfJobs();
419 bool = any(isfinite(N));
422 function
bool = isMatlabNative(self)
423 % BOOL = ISMATLABNATIVE()
425 % Returns false for Java (JNetwork) implementation
430 function
bool = isJavaNative(self)
431 % BOOL = ISJAVANATIVE()
433 % Returns true for Java (JNetwork) implementation
438 function index = getIndexOpenClasses(self)
439 % INDEX = GETINDEXOPENCLASSES()
440 N = self.getNumberOfJobs();
441 index = find(isinf(N))';
444 function index = getIndexClosedClasses(self)
445 % INDEX = GETINDEXCLOSEDCLASSES()
446 N = self.getNumberOfJobs();
447 index = find(isfinite(N))';
450 function
bool = hasClassSwitching(self)
451 % BOOL = HASCLASSSWITCHING()
452 nodes = self.getNodes();
453 bool = any(cellfun(@(n) isa(n,'ClassSwitch'),
nodes));
456 function
bool = hasJoin(self)
458 nodes = self.getNodes();
459 bool = any(cellfun(@(n) isa(n,'Join'),
nodes));
462 function [M,R] = getSize(self)
464 M = self.getNumberOfNodes();
465 R = self.getNumberOfClasses();
468 function used = getUsedLangFeatures(self)
469 % USED = GETUSEDLANGFEATURES()
470 javaFeatureSet = self.obj.getUsedLangFeatures();
472 % Convert Java FeatureSet to MATLAB struct
473 % Note: This
is a simplified conversion - may need refinement
474 % based on the actual FeatureSet structure
477 % If the Java FeatureSet has accessible fields/methods,
478 % we would convert them here. For now, return the Java
object
479 % This may need custom conversion logic depending on FeatureSet implementation
481 % Attempt to get feature names if FeatureSet has such methods
482 % This
is a placeholder - actual implementation depends on FeatureSet API
483 used = javaFeatureSet;
485 % Fallback - create empty struct
490 function summary(self)
495 function [D,Z] = getDemands(self)
496 % [D,Z] = GETDEMANDS()
497 ret = self.obj.getDemands();
498 D = JLINE.from_jline_matrix(ret.D);
499 Z = JLINE.from_jline_matrix(ret.Z);
502 function [lambda,D,N,Z,mu,S] = getProductFormParameters(self)
503 % [LAMBDA,D,N,Z,MU,S] = GETPRODUCTFORMPARAMETERS()
504 ret = self.obj.getProductFormParameters();
505 lambda = JLINE.from_jline_matrix(ret.lambda);
506 D = JLINE.from_jline_matrix(ret.D);
507 N = JLINE.from_jline_matrix(ret.N);
508 Z = JLINE.from_jline_matrix(ret.Z);
509 mu = JLINE.from_jline_matrix(ret.mu);
510 S = JLINE.from_jline_matrix(ret.S);
513 function printRoutingMatrix(self, onlyclass)
514 % PRINTROUTINGMATRIX(ONLYCLASS)
515 self.obj.printRoutingMatrix();
518 function [rt,rtNodes,connections,chains,rtNodesByClass,rtNodesByStation] = getRoutingMatrix(self, arvRates)
519 % [
RT,RTNODES,CONNECTIONS,CHAINS,RTNODEBYCLASS,RTNODEBYSTATION] = GETROUTINGMATRIX(ARVRATES)
520 % Note: Java
object does not support this method directly
521 error('getRoutingMatrix method not supported by Java
object');
524 function
P = getLinkedRoutingMatrix(self)
525 %
P = GETLINKEDROUTINGMATRIX()
526 javaP = self.obj.getLinkedRoutingMatrix();
527 % Convert Java Map<JobClass, Map<JobClass, Matrix>> to MATLAB cell array
529 % Note: This
is a complex conversion - simplified implementation
530 % May need custom conversion logic based on how MATLAB expects
this data
531 P = javaP; % Direct
return for now - may need refinement
534 function connections = getConnectionMatrix(self)
535 % CONNECTIONS = GETCONNECTIONMATRIX()
536 javaConnections = self.obj.getConnectionMatrix();
537 connections = JLINE.from_jline_matrix(javaConnections);
540 function mask = getClassSwitchingMask(self)
541 % MASK = GETCLASSSWITCHINGMASK()
542 javaMask = self.obj.getClassSwitchingMask();
543 mask = JLINE.from_jline_matrix(javaMask);
546 function
bool = hasProductFormSolution(self)
547 % BOOL = HASPRODUCTFORMSOLUTION()
548 bool = self.obj.hasProductFormSolution();
553 % Note: Java
object does not support plot method
554 error('plot method not supported by Java
object');
557 function jsimwView(self)
559 self.obj.jsimwView();
567 % Save methods (for consistency with MNetwork/SolverJMT)
568 function saveAsJSIM(self, filename)
569 % SAVEASJSIM(FILENAME)
570 % Note: Java
object does not support direct JSIM export
571 error('saveAsJSIM method not supported by Java
object. Use SolverJMT for JSIM export.');
574 function saveAsJMVA(self, filename)
575 % SAVEASJMVA(FILENAME)
576 % Note: Java
object does not support direct JMVA export
577 error('saveAsJMVA method not supported by Java
object. Use SolverJMT for JMVA export.');
585 function model = tandemPs(lambda, D, S)
586 lambda = JLINE.from_line_matrix(lambda);
587 D = JLINE.from_line_matrix(D);
588 S = JLINE.from_line_matrix(S);
589 model = jline.lang.Network.tandemPs(lambda, D, S);
590 model = JNetwork(model);
593 function model = tandemPsInf(varargin)
594 lambda = JLINE.from_line_matrix(varargin{1});
595 D = JLINE.from_line_matrix(varargin{2});
597 model = jline.lang.Network.tandemPsInf(lambda, D);
599 Z = JLINE.from_line_matrix(varargin{3});
600 model = jline.lang.Network.tandemPsInf(lambda, D, Z);
602 Z = JLINE.from_line_matrix(varargin{3});
603 S = JLINE.from_line_matrix(varargin{4});
604 model = jline.lang.Network.tandemPsInf(lambda, D, Z, S);
606 error(
'Invalid number of arguments for tandemPsInf.');
608 model = JNetwork(model);
611 function model = tandemFcfs(varargin)
612 lambda = JLINE.from_line_matrix(varargin{1});
613 D = JLINE.from_line_matrix(varargin{2});
614 S = JLINE.from_line_matrix(varargin{3});
615 model = jline.lang.Network.tandemFcfs(lambda, D, S);
616 model = JNetwork(model);
619 function model = tandemFcfsInf(varargin)
620 lambda = JLINE.from_line_matrix(varargin{1});
621 D = JLINE.from_line_matrix(varargin{2});
623 model = jline.lang.Network.tandemFcfsInf(lambda, D);
625 Z = JLINE.from_line_matrix(varargin{3});
626 model = jline.lang.Network.tandemFcfsInf(lambda, D, Z);
628 Z = JLINE.from_line_matrix(varargin{3});
629 S = JLINE.from_line_matrix(varargin{4});
630 model = jline.lang.Network.tandemFcfsInf(lambda, D, Z, S);
632 error(
'Invalid number of arguments for tandemFcfsInf.');
634 model = JNetwork(model);
637 function model = tandem(lambda, D, strategy, S)
638 lambda = JLINE.from_line_matrix(lambda);
639 D = JLINE.from_line_matrix(D);
640 S = JLINE.from_line_matrix(S);
641 model = jline.lang.Network.tandem(lambda, D, strategy, S);
642 model = JNetwork(model);
645 function model = cyclicPs(varargin)
646 N = JLINE.from_line_matrix(varargin{1});
647 D = JLINE.from_line_matrix(varargin{2});
649 model = jline.lang.Network.cyclicPs(N, D);
651 S = JLINE.from_line_matrix(varargin{3});
652 model = jline.lang.Network.cyclicPs(N, D, S);
654 error(
'Invalid number of arguments for cyclicPs.');
656 model = JNetwork(model);
659 function model = cyclicFcfs(varargin)
660 N = JLINE.from_line_matrix(varargin{1});
661 D = JLINE.from_line_matrix(varargin{2});
663 model = jline.lang.Network.cyclicFcfs(N, D);
665 S = JLINE.from_line_matrix(varargin{3});
666 model = jline.lang.Network.cyclicFcfs(N, D, S);
668 error(
'Invalid number of arguments for cyclicFcfs.');
670 model = JNetwork(model);
673 function model = cyclicPsInf(varargin)
674 N = JLINE.from_line_matrix(varargin{1});
675 D = JLINE.from_line_matrix(varargin{2});
676 Z = JLINE.from_line_matrix(varargin{3});
678 model = jline.lang.Network.cyclicPsInf(N, D, Z);
680 S = JLINE.from_line_matrix(varargin{4});
681 model = jline.lang.Network.cyclicPsInf(N, D, Z, S);
683 error(
'Invalid number of arguments for cyclicPsInf.');
685 model = JNetwork(model);
688 function model = cyclicFcfsInf(varargin)
689 N = JLINE.from_line_matrix(varargin{1});
690 D = JLINE.from_line_matrix(varargin{2});
691 Z = JLINE.from_line_matrix(varargin{3});
693 model = jline.lang.Network.cyclicFcfsInf(N, D, Z);
695 S = JLINE.from_line_matrix(varargin{4});
696 model = jline.lang.Network.cyclicFcfsInf(N, D, Z, S);
698 error(
'Invalid number of arguments for cyclicFcfsInf.');
700 model = JNetwork(model);
703 function model = cyclic(N, D, strategy, S)
704 N = JLINE.from_line_matrix(N);
705 D = JLINE.from_line_matrix(D);
706 S = JLINE.from_line_matrix(S);
707 model = jline.lang.Network.cyclic(N, D, strategy, S);
708 model = JNetwork(model);
711 function
P = serialRouting(varargin)
712 if nargin == 1 && iscell(varargin{1})
713 % Case: serialRouting(List<Node>)
715 P = jline.lang.Network.serialRouting(
nodes);
717 elseif nargin == 1 && isa(varargin{1},
'Node')
718 % Case: serialRouting(Node...)
719 nodeObjs = cellfun(@(n) n.obj, varargin,
'UniformOutput', false);
720 P = jline.lang.Network.serialRouting(nodeObjs);
725 if isa(a,
'JobClass') && iscell(b)
726 % Case: serialRouting(JobClass, List<Node>)
727 P = jline.lang.Network.serialRouting(a.obj, b);
729 elseif isa(a,
'JobClass') && all(cellfun(@(x) isa(x,
'Node'), b))
730 % Case: serialRouting(JobClass, Node...)
731 nodeObjs = cellfun(@(n) n.obj, b, 'UniformOutput', false);
732 P = jline.lang.Network.serialRouting(a.obj, nodeObjs);
734 elseif iscell(a) && iscell(b)
735 % Case: serialRouting(List<JobClass>, List<Node>)
736 P = jline.lang.Network.serialRouting(a, b);
739 error('Unsupported serialRouting input pattern.');
742 elseif nargin >= 2 && isa(varargin{1},
'JobClass')
743 jobClass = varargin{1};
744 nodes = varargin(2:end);
745 nodeObjs = cellfun(@(n) n.obj,
nodes,
'UniformOutput',
false);
746 P = jline.lang.Network.serialRouting(jobClass.obj, nodeObjs);
748 elseif nargin >= 2 && all(cellfun(@(x) isa(x,
'Node'), varargin))
749 % Generic
case: serialRouting(Node1, Node2, ..., NodeN)
750 nodeObjs = cellfun(@(n) n.obj, varargin,
'UniformOutput',
false);
751 P = jline.lang.Network.serialRouting([nodeObjs{:}]);
753 elseif nargin == 2 && iscell(varargin{1}) && iscell(varargin{2})
754 % Possibly a fallback
for serialRouting(jobClasses,
nodes)
755 P = jline.lang.Network.serialRouting(varargin{1}, varargin{2});
758 error(
'Invalid arguments to serialRouting.');