LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
solver_mam_traffic_mmap.m
1function ARV = solver_mam_traffic_mmap(sn, DEP, config, fjSyncMap)
2% ARV = SOLVER_MAM_TRAFFIC_MMAP(SN, DEP, CONFIG, FJSYNCMAP)
3% FJ-aware traffic solver extending solver_mam_traffic with mmap_max
4% synchronization at join points.
5%
6% DEP{i,r} is the departure process of class r from i in (D0,D1) format
7% fjSyncMap is built by sn_build_fj_sync_map
8%
9% Copyright (c) 2012-2026, Imperial College London
10% All rights reserved.
11
12I = sn.nnodes;
13R = sn.nclasses;
14
15if ~isfield(config, 'fj_sync_q_len')
16 config.fj_sync_q_len = 2;
17end
18
19% In this function we use indexing over all non-ClassSwitch nodes
20non_cs_classes = [];
21isNCS = zeros(1,I);
22nodeToNCS = zeros(1,I);
23NCStoNode = [];
24for ind=1:I
25 if sn.nodetype(ind) ~= NodeType.ClassSwitch
26 non_cs_classes(end+1:end+R)= ((ind-1)*R+1):(ind*R);
27 isNCS(ind) = true;
28 nodeToNCS(ind) = sum(isNCS);
29 NCStoNode(end+1) = ind;
30 else
31 isNCS(ind) = false;
32 end
33end
34
35% Hide the nodes that are class switches
36rtncs = dtmc_stochcomp(sn.rtnodes, non_cs_classes);
37Inc = I - sum(sn.nodetype == NodeType.ClassSwitch);
38
39% DEP is indexed by node (ind, r) - convert to MMAP format
40MMAP = cell(I, R);
41for ind=1:I
42 for r=1:R
43 MMAP{ind,r} = DEP{ind,r};
44 if isempty(MMAP{ind,r}) || any(any(isnan(MMAP{ind,r}{1})))
45 MMAP{ind,r} = {[0],[0],[0]}; % no arrivals from this class
46 else
47 MMAP{ind,r}{3} = MMAP{ind,r}{2};
48 end
49 end
50end
51
52ARV = cell(Inc,1);
53DEP_NCS = cell(Inc,R);
54LINKS = cell(Inc,Inc);
55
56% Build the nodeSync matrix in NCS indexing
57nodeSyncNCS = zeros(Inc, Inc);
58for ind=1:I
59 if isNCS(ind)
60 inc = nodeToNCS(ind);
61 for jnd=1:I
62 if isNCS(jnd)
63 jnc = nodeToNCS(jnd);
64 if fjSyncMap.nodeSync(ind, jnd) > 0
65 nodeSyncNCS(inc, jnc) = fjSyncMap.nodeSync(ind, jnd);
66 end
67 end
68 end
69 end
70end
71
72% First determine all outgoing flows from all nodes
73for ind=1:I
74 if isNCS(ind)
75 inc = nodeToNCS(ind);
76 switch sn.nodetype(ind)
77 case {NodeType.Source, NodeType.Delay, NodeType.Queue, NodeType.Fork, NodeType.Join}
78 % obtain departure maps (MMAP is now node-indexed)
79 if R>1
80 % Order-preserving bounded superposition of the per-class
81 % departure flows. The raw mmap_super({MMAP{ind,1:R}}) builds
82 % the full Kronecker product at once (order = product of the
83 % per-class orders); across the departure-refinement iterations
84 % this compounds geometrically and exhausts memory. Superpose
85 % class-by-class in class order instead, compressing the phase
86 % dimension back to config.space_max whenever it is exceeded.
87 % This keeps the marked-class order (1..R) that the downstream
88 % class-switch split relies on, is identical to the original
89 % whenever the product stays within config.space_max, and avoids
90 % the SCV-based reordering of mmap_super_safe (which also raised
91 % singular-matrix warnings by computing SCV on zero-rate flows).
92 DEP_NCS{inc} = MMAP{ind,1};
93 for rr=2:R
94 DEP_NCS{inc} = mmap_super(DEP_NCS{inc}, MMAP{ind,rr});
95 if length(DEP_NCS{inc}{1}) > config.space_max
96 DEP_NCS{inc} = mmap_compress(DEP_NCS{inc}, config);
97 end
98 end
99 else
100 DEP_NCS{inc} = MMAP{ind,1};
101 end
102 Psplit = zeros(R,Inc*R);
103 for r=1:R
104 for jnd = 1:I
105 if isNCS(jnd)
106 jnc = nodeToNCS(jnd);
107 for s=1:R
108 Psplit(r,(jnc-1)*R+s) = rtncs((inc-1)*R+r, (jnc-1)*R+s);
109 end
110 end
111 end
112 end
113
114 [Fsplit{1:Inc}] = npfqn_traffic_split_cs(DEP_NCS{inc}, Psplit, config);
115 for jnc=1:Inc
116 LINKS{inc,jnc} = Fsplit{jnc};
117 LINKS{inc,jnc} = mmap_normalize(LINKS{inc,jnc});
118 end
119 end
120 end
121end
122
123% Then determine all incoming flows, with FJ synchronization
124for ind=1:I
125 if isNCS(ind) && sn.nodetype(ind) ~= NodeType.Source
126 inc = nodeToNCS(ind);
127
128 % Partition incoming links into sync groups and independent flows
129 syncGroupsAtNode = unique(nodeSyncNCS(inc, :));
130 syncGroupsAtNode = syncGroupsAtNode(syncGroupsAtNode > 0);
131
132 independentFlows = {};
133 syncFlows = struct();
134
135 for jnc=1:Inc
136 if isempty(LINKS{jnc,inc}) || sum(mmap_lambda(LINKS{jnc,inc})) <= GlobalConstants.FineTol
137 continue;
138 end
139 gid = nodeSyncNCS(inc, jnc);
140 if gid == 0
141 % Independent flow
142 independentFlows{end+1} = LINKS{jnc,inc};
143 else
144 % Synchronized flow — group by sync group ID
145 fname = ['g' num2str(gid)];
146 if ~isfield(syncFlows, fname)
147 syncFlows.(fname) = {};
148 end
149 syncFlows.(fname){end+1} = LINKS{jnc,inc};
150 end
151 end
152
153 % Process synchronized flows: apply mmap_max iteratively within each group
154 syncResults = {};
155 for g = 1:length(syncGroupsAtNode)
156 gid = syncGroupsAtNode(g);
157 fname = ['g' num2str(gid)];
158 if ~isfield(syncFlows, fname)
159 continue;
160 end
161 groupFlows = syncFlows.(fname);
162 if isempty(groupFlows)
163 continue;
164 end
165
166 % Start with first flow, iteratively apply mmap_max with remaining
167 syncedFlow = groupFlows{1};
168 for f = 2:length(groupFlows)
169 syncedFlow = mmap_max(syncedFlow, groupFlows{f}, config.fj_sync_q_len);
170 % mmap_max builds the synchronization state space but does
171 % not enforce MMAP feasibility. Normalize before using the
172 % result in compression or lambda calculations.
173 syncedFlow = mmap_normalize(syncedFlow);
174
175 % Compress after each mmap_max step if state space is too large
176 if length(syncedFlow{1}) > config.space_max
177 syncedFlow = mmap_compress(syncedFlow, struct('method', config.compress));
178 end
179 end
180 syncResults{end+1} = syncedFlow;
181 end
182
183 % Merge synced flows with independent flows
184 allFlows = [syncResults, independentFlows];
185
186 if length(allFlows) > 1
187 ARV{ind} = npfqn_traffic_merge(allFlows, config);
188 elseif length(allFlows) == 1
189 ARV{ind} = allFlows{1};
190 else
191 % No flows — take a zero-rate link
192 for jnc=1:Inc
193 if ~isempty(LINKS{jnc,inc})
194 ARV{ind} = LINKS{jnc,inc};
195 break;
196 end
197 end
198 if isempty(ARV{ind})
199 ARV{ind} = {[0],[0],[0]};
200 end
201 end
202 else
203 ARV{ind} = [];
204 end
205end
206end
Definition mmt.m:124