LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
sampleSysAggr.m
1function sysStateAggr = sampleSysAggr(self, numEvents, markActivePassive)
2% SYSSTATEAGGR = SAMPLESYSAGGR(NUMEVENTS)
3
4if GlobalConstants.DummyMode
5 sysStateAggr = NaN;
6 return
7end
8
9if strcmp(self.getOptions.lang,'java')
10 % Log-based sampling relies on per-node CSV logs written and parsed by the
11 % native JMT path; the JLINE (lang=java) delegation does not produce them.
12 line_error(mfilename,'SolverJMT log-based sampling (sampleSysAggr/getProbSysAggr) is not supported with lang=''java''. Use lang=''matlab'' or SolverCTMC.');
13end
14
15if nargin<2 %~exist('numEvents','var')
16 numEvents = self.options.samples;
17end
18
19if nargin<3
20 markActivePassive = false;
21end
22
23sn = self.getStruct;
24numEvents = numEvents - 1; % we include the initialization as an event
25Q = getAvgQLenHandles(self);
26statStateAggr = cell(sn.nstations,1);
27
28% create a temp model
29modelCopy = self.model.copy;
30modelCopy.resetNetwork;
31
32% determine the nodes to logs
33isNodeClassLogged = false(modelCopy.getNumberOfNodes, modelCopy.getNumberOfClasses);
34for i= 1:modelCopy.getNumberOfStations
35 ind = self.model.getNodeIndex(modelCopy.getStationNames{i});
36 if sn.nodetype(ind) ~= NodeType.Source
37 for r=1:modelCopy.getNumberOfClasses
38 if ~Q{i,r}.disabled || nargin == 1
39 isNodeClassLogged(ind,r) = true;
40 else
41 isNodeClassLogged(node,r) = true;
42 end
43 end
44 end
45end
46
47% apply logging to the copied model
48Plinked = sn.rtorig;
49isNodeLogged = max(isNodeClassLogged,[],2);
50logpath = lineTempDir;
51modelCopy.linkAndLog(Plinked, isNodeLogged, logpath);
52
53% simulate the model copy and retrieve log data
54options = self.getOptions;
55options.method = 'jsim'; % Force jsim method to avoid recursion with 'replication'
56solverjmt = SolverJMT(modelCopy, options);
57solverjmt.maxEvents = numEvents*sn.nnodes*sn.nclasses;
58solverjmt.runAnalyzer(); % log data
59logData = SolverJMT.parseLogs(modelCopy, isNodeLogged, MetricType.toText(MetricType.QLen));
60
61% from here convert from nodes in logData to stations
62event = {};
63sn = modelCopy.getStruct;
64for ist= 1:sn.nstations
65 isf = sn.stationToStateful(ist);
66 ind = sn.stationToNode(ist);
67 t = [];
68 nir = cell(1,sn.nclasses);
69 event{isf,r} = {};
70 if sn.nodetype(ind) == NodeType.Source
71 nir{r} = [];
72 else
73 for r=1:sn.nclasses
74 if ~isempty(logData{isf,r})
75 [~,uniqTSi] = unique(logData{isf,r}.t);
76 if isNodeClassLogged(isf,r)
77 if ~isempty(logData{isf,r})
78 t = logData{isf,r}.t(uniqTSi);
79 event{isf,r} = logData{isf,r}.event;
80 %t = [t(2:end);t(end)];
81 nir{r} = logData{isf,r}.QLen(uniqTSi);
82 end
83 end
84 else
85 nir{r} = [];
86 event{isf,r} = {};
87 end
88 end
89 end
90 if isfinite(self.options.timespan(2))
91 stopAt = find(t>self.options.timespan(2),1,'first');
92 if ~isempty(stopAt) && stopAt>1
93 t = t(1:(stopAt-1));
94 for r=1:length(nir)
95 nir{r} = nir{r}(1:(stopAt-1));
96 end
97 end
98 end
99 statStateAggr{ist} = struct();
100 statStateAggr{ist}.handle = self.model.stations{ist};
101 statStateAggr{ist}.t = t;
102 statStateAggr{ist}.state = cell2mat(nir);
103 statStateAggr{ist}.event = {event{isf,:}};
104 statStateAggr{ist}.isaggregate = true;
105 %sysStateAggr.arv_job_id = logData{2}.arvID;
106 %sysStateAggr.dep_job_id = logData{2}.depID;
107end
108
109tranSysStateAggr = cell(1,1+sn.nstations);
110
111tranSysStateAggr{1} = []; % timestamps
112for i=1:sn.nstations % stations
113 if isempty(tranSysStateAggr{1})
114 tranSysStateAggr{1} = statStateAggr{i}.t;
115 else
116 tumax = min(max(tranSysStateAggr{1}),max(statStateAggr{i}.t));
117 tranSysStateAggr{1} = union(tranSysStateAggr{1}, statStateAggr{i}.t);
118 tranSysStateAggr{1} = tranSysStateAggr{1}(tranSysStateAggr{1}<=tumax);
119 tranSysStateAggr{1} = union(tranSysStateAggr{1}, statStateAggr{i}.t);
120 end
121end
122
123for i=1:sn.nstations % stations
124 ind = sn.stationToNode(i);
125 tranSysStateAggr{1+i} = [];
126 [~,uniqTSi] = unique(statStateAggr{i}.t);
127 if sn.nodetype(ind) ~= NodeType.Source
128 for j=1:sn.nclasses % classes
129 % we floor the interpolation as we hold the last state
130 if ~isempty(uniqTSi)
131 Qijt = interp1(statStateAggr{i}.t(uniqTSi), statStateAggr{i}.state(uniqTSi,j), tranSysStateAggr{1},'previous');
132 if isnan(Qijt(end))
133 Qijt(end)=Qijt(end-1);
134 end
135 tranSysStateAggr{1+i} = [tranSysStateAggr{1+i}, Qijt];
136 else
137 Qijt = NaN*ones(length(tranSysStateAggr{1}),1);
138 tranSysStateAggr{1+i} = [tranSysStateAggr{1+i}, Qijt];
139 end
140 end
141 else
142 tranSysStateAggr{1+i} = [Inf];
143 end
144end
145
146sysStateAggr = struct();
147sysStateAggr.handle = self.model.stations';
148sysStateAggr.t = tranSysStateAggr{1};
149sysStateAggr.state = {tranSysStateAggr{2:end}};
150
151% % % now put the events in the .event cell
152% eventSysStateAggr = cell(sn.nstations, sn.nclasses); % timestamps
153% for i=1:sn.nstations % stations
154% for r=1:sn.nclasses
155% if isempty(statStateAggr{i}.event)
156% eventSysStateAggr{i,r} = struct();
157% else
158% eventSysStateAggr{i,r} = struct();
159% for e=1:size(statStateAggr{i}.event{r},1)
160% if ~isempty(statStateAggr{i}.event{r}{e})
161% %statStateAggr{i}.event{r}{e}.t
162% %etpos = find(sysStateAggr.t == statStateAggr{i}.event{r}{e}.t);
163% %if ~isempty(etpos)
164% evtype = statStateAggr{i}.event{r}{e}.event;
165% evfield = EventType.toText(evtype);
166% if ~isfield(eventSysStateAggr{i,r},evfield)
167% eventSysStateAggr{i,r}.(EventType.toText(evtype)) = {};
168% end
169% eventSysStateAggr{i,r}.(EventType.toText(evtype)){end+1,1} = statStateAggr{i}.event{r}{e};
170% %end
171% end
172% end
173% %eventSysStateAggr{i,r} = statStateAggr{i}.event{r};
174% end
175% end
176% end
177% %sysStateAggr.t = [0; sysStateAggr.t(1:end-1)];
178% sysStateAggr.event = eventSysStateAggr;
179
180% Flatten the 2D `event` cell into a column cell of Event objects, sorted by
181% time. Robust to the fact that some `event{i,j}` slots may be `[]` (numeric)
182% rather than `{}` (cell) when nclasses>1, due to implicit cell-array growth.
183flatEvents = {};
184for ii=1:size(event,1)
185 for jj=1:size(event,2)
186 cellij = event{ii,jj};
187 if iscell(cellij) && ~isempty(cellij)
188 for kk=1:numel(cellij)
189 if isa(cellij{kk}, 'Event')
190 flatEvents{end+1,1} = cellij{kk};
191 end
192 end
193 end
194 end
195end
196if isempty(flatEvents)
197 sysStateAggr.event = cell(0,1);
198else
199 event_t = cellfun(@(c) c.t, flatEvents);
200 [~,I] = sort(event_t);
201 sysStateAggr.event = flatEvents(I);
202end
203sysStateAggr.isaggregate = true;
204%sysStateAggr.arv_job_id = logData{2}.arvID;
205%sysStateAggr.dep_job_id = logData{2}.depID;
206
207if markActivePassive
208 apevent = cell(1,length(sysStateAggr.t)-1);
209 for ti = 1:length(apevent)
210 apevent{ti} = struct('active',[],'passive',[]);
211 end
212 for e=1:length(sysStateAggr.event)
213 ti = find(sysStateAggr.event{e}.t == sysStateAggr.t);
214 if ~isempty(ti)
215 switch sysStateAggr.event{e}.event
216 case EventType.ARV
217 apevent{ti-1}.passive = sysStateAggr.event{e};
218 otherwise
219 apevent{ti-1}.active = sysStateAggr.event{e};
220 end
221 end
222 end
223 sysStateAggr.event = apevent';
224end
225end
Definition mmt.m:124