LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
MarkedMAP.m
1classdef MarkedMAP < MarkovModulated
2 % Markov Modulated Arrival Process
3 %
4 % Copyright (c) 2012-2026, Imperial College London
5 % All rights reserved.
6
7 methods
8 %Constructor
9 function self = MarkedMAP(D,K)
10 % SELF = MarkedMAP(D,K)
11 %
12 % LINE uses the M3A representation format
13 % D={D0, D1, D11, D12, D13, ..., D1K}
14 % K is the number of marking types
15
16 self@MarkovModulated('MarkedMAP',K+2);
17
18 if K == length(D)-1
19 setParam(self, 1, 'D0', D{1});
20 setParam(self, 2, 'D1', cellsum({D{2:end}}));
21 for k=1:K
22 setParam(self, 2+k, sprintf('D1%d',k), D{1+k});
23 end
24 elseif K == length(D)-2
25 setParam(self, 1, 'D0', D{1});
26 setParam(self, 2, 'D1', D{2});
27 for k=1:K
28 setParam(self, 2+k, sprintf('D1%d',k), D{2+k});
29 end
30 else
31 line_error(mfilename,'Inconsistency between the number of classes and the number of supplied D matrices.')
32 end
33 MarkedMAP = cell(1,K-1);
34 for k=1:K
35 MarkedMAP{k} = self.getParam(k).paramValue;
36 end
37 self.process = MarkedMAP;
38 end
39
40 function Di = D(self, i, j, wantSparse)
41 % Di = D(i)
42 if nargin == 1
43 Di = self.getProcess;
44 return
45 end
46 if nargin<4
47 wantSparse = false;
48 end
49 if nargin<3
50 if i<=1
51 j = 0;
52 else
53 line_error(mfilename,'Invalid D matrix indexes');
54 end
55 end
56
57 % Return representation matrix, e.g., D0=MAP.D(0)
58 if wantSparse
59 if nargin<2
60 Di=self.getProcess;
61 else
62 Di=self.getProcess{1+i+j};
63 end
64 else
65 if nargin<2
66 Di=self.getProcess;
67 for i=1:length(Di)
68 Di(i)=full(Di(i));
69 end
70 else
71 Di=full(self.getProcess{1+i+j});
72 end
73 end
74 end
75
76 function meant = evalMeanT(self, t)
77 % MEANT = EVALMEANT(SELF,T)
78
79 meant = self.toMAP.evalMeanT(t);
80 end
81
82 function vart = evalVarT(self, t)
83 % VART = EVALVART(SELF,T)
84
85 % Evaluate the variance-time curve at timescale t
86 vart = self.toMAP.evalVarT(t);
87 end
88
89 function acf = evalACFT(self, lags, timescale)
90 % ACF = EVALACFT(self, lags)
91 %
92 % Evaluate the autocorrelation in counts at timescale t
93
94 acf = self.toMAP.evalACFT(lags, timescale);
95 end
96
97 % inter-arrival time properties
98 function mean = getMean(self)
99 % MEAN = GETMEAN()
100
101 mean = self.toMAP.getMean;
102 end
103
104 function scv = getSCV(self)
105 % SCV = GETSCV()
106
107 scv = self.toMAP.scv;
108 end
109
110 % inter-arrival time properties for each marking type
111 function mean = getMarkedMeans(self)
112 % MEAN = GETMARKEDMEANS()
113
114 mean = 1 ./ mmap_lambda(self.D);
115 end
116
117 function acf = getACF(self, lags)
118 % ACF = GETACF(self, lags)
119
120 acf = self.toMAP.getACF(lags);
121 end
122
123 function map = toMAP(self)
124 map = MAP(self.D(0), self.D(1));
125 end
126
127 function maps = toMAPs(self, types)
128 if nargin<2
129 types = 1:self.getNumberOfTypes;
130 end
131 maps = {};
132 for k=types
133 Df = self.D(0);
134 Df = Df + (self.D(1) - self.D(1,k));
135 maps{end+1} = MAP(Df, self.D(1,k));
136 end
137 end
138
139 function [gamma2, gamma] = getACFDecay(self)
140 % [gamma2, gamma] = GETACFDECAY(self)
141 %
142 % gamma2: asymptotic decay rate of acf
143 % gamma: interpolated decay rate of acf
144
145 [gamma2, gamma] = self.toMAP.getACFDecay();
146 end
147
148 function id = getIDC(self, t) % index of dispersion for counts
149 % ID = GETIDC() % INDEX OF DISPERSION
150 if nargin < 2
151 id = self.toMAP.getIDC;
152 else
153 id = self.toMAP.getIDC(t);
154 end
155 end
156
157 function id = getMarkedIDC(self, t) % asymptotic index of dispersion for counts for each type
158 % ID = GETMARKEDIDC() % ASYMPTOTIC INDEX OF DISPERSION
159 if nargin < 2
160 id = mmap_count_idc(self.getProcess, GlobalConstants.Immediate);
161 else
162 id = mmap_count_idc(self.getProcess, t);
163 end
164 end
165
166 function lam = getRate(self)
167 % LAMBDA = GETRATE()
168
169 lam = self.toMAP.getRate;
170 end
171
172 function n = getNumberOfPhases(self)
173 % N = GETNUMBEROFMAPASES()
174 D0 = self.getParam(1).paramValue;
175 n = length(D0);
176 end
177
178 function mu = getMu(self)
179 % MU = GETMU()
180 % Aggregate departure rate from each state
181 mu = sum(self.D(1),2); % sum D1 rows / diag -D0
182 end
183
184 function phi = getPhi(self)
185 % MAPI = GETMAPI()
186 % Return the exit vector of the underlying MAP
187 phi = sum(self.D(1),2) ./ diag(-self.D(0)); % sum D1 rows / diag -D0
188 end
189
190 function K = getNumberOfTypes(self)
191 % K = GETNUMBEROFTYPES()
192 % Number of marking types
193
194 K = length(self.D)-2;
195 end
196
197 function MMAPr = toTimeReversed(self)
198 MMAPr = MarkedMAP(mmap_timereverse(self.D), self.getNumberOfTypes);
199 end
200
201 function [X,C] = sample(self, n)
202 % [X,C] = SAMPLE(N)
203 if nargin<2 %~exist('n','var'),
204 n = 1;
205 end
206 MarkedMAP = self.getProcess;
207 if mmap_isfeasible(MarkedMAP)
208 [X,C] = mmap_sample(MarkedMAP,n);
209 else
210 line_error(mfilename,'This process is infeasible (negative rates).');
211 end
212 end
213
214 end
215
216 methods (Static)
217
218 function mmap = fit(trace, markings, order)
219 % M3PP = FIT(TRACE, ORDER)
220 T = m3afit_init(trace,markings);
221 mmap = m3afit_auto(T,'NumStates',order);
222 end
223
224
225 function mmap = rand(order, nclasses)
226 % MarkedMAP = RAND(ORDER,NCLASSES)
227 %
228 % Generate random MarkedMAP using uniform random numbers
229 if nargin < 1
230 order = 2;
231 end
232 mmap = MarkedMAP(mmap_rand(order,nclasses),nclasses);
233 end
234 end
235end