LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
MAPFromTrace.m
1% [D0, D1, logli] = MAPFromTrace(trace, orders, maxIter, stopCond, initial, result)
2%
3% Performs MAP fitting using the EM algorithm (ErCHMM,
4% [1]_, [2]_).
5%
6% Parameters
7% ----------
8% trace : column vector, length K
9% The samples of the trace
10% orders : list of int, length(N), or int
11% The length of the list determines the number of
12% Erlang branches to use in the fitting method.
13% The entries of the list are the orders of the
14% Erlang distributions. If this parameter is a
15% single integer, all possible branch number - order
16% combinations are tested where the total number of
17% states is "orders".
18% maxIter : int, optional
19% Maximum number of iterations. The default value is
20% 200
21% stopCond : double, optional
22% The algorithm stops if the relative improvement of
23% the log likelihood falls below stopCond. The
24% default value is 1e-7
25% initial : tuple of a vector and a matrix, shape(N,N), optional
26% The rate parameters of the Erlang distributions
27% and the branch transition probability matrix to be
28% used initially. If not given, a default initial
29% guess is determined and the algorithm starts from
30% there.
31% result : {"vecmat", "matmat"}, optional
32% The result can be returned two ways. If "matmat" is
33% selected, the result is returned in the classical
34% representation of MAPs, thus the D0 and D1 matrices.
35% If "vecmat" is selected, the rate parameters of the
36% Erlang branches and the branch transition probability
37% matrix are returned. The default value is "matmat"
38%
39% Returns
40% -------
41% (D0, D1) : tuple of matrix, shape (M,M) and matrix, shape (M,M)
42% If the "matmat" result format is chosen, the function
43% returns the D0 and D1 matrices of the MAP
44% (lambda, P) : tuple of vector, length N and matrix, shape (M,M)
45% If the "vecmat" result format is chosen, the function
46% returns the vector of the Erlang rate parameters of
47% the branches and the branch transition probability
48% matrix
49% logli : double
50% The log-likelihood divided by the trace length
51%
52% Notes
53% -----
54% This procedure is quite slow in the supported
55% mathematical frameworks. If the maximum speed is
56% needed, please use the multi-core optimized c++
57% implementation called SPEM-FIT_.
58%
59% .. _SPEM-FIT: https://bitbucket.org/ghorvath78/spemfit
60%
61% References
62% ----------
63% .. [1] Okamura, Hiroyuki, and Tadashi Dohi. Faster
64% maximum likelihood estimation algorithms for
65% Markovian arrival processes. Quantitative
66% Evaluation of Systems, 2009. QEST'09. Sixth
67% International Conference on the. IEEE, 2009.
68%
69% .. [2] Horváth, Gábor, and Hiroyuki Okamura. A Fast EM
70% Algorithm for Fitting Marked Markovian Arrival
71% Processes with a New Special Structure. Computer
72% Performance Engineering. Springer Berlin
73% Heidelberg, 2013. 119-133.
74
75function [D0, D1, logli] = MAPFromTrace (trace, orders, maxIter, stopCond, initial, result)
76
77 if ~exist('maxIter','var') || isempty(maxIter)
78 maxIter = 200;
79 end
80 if ~exist('stopCond','var') || isempty(stopCond)
81 stopCond = 1e-7;
82 end
83 if ~exist('initial','var')
84 initial = {};
85 end
86 if ~exist('result','var') || isempty(result)
87 result = 'matmat';
88 end
89 global BuToolsVerbose;
90
91 function o = allorders (branches, sumorders)
92 if branches==1
93 o={sumorders};
94 else
95 o = {};
96 for ii=1:sumorders-branches+1
97 x = allorders (branches-1, sumorders-ii);
98 for j=1:length(x)
99 xt = sort([x{j} ii]);
100 % check if we have it already
101 found=false;
102 for ok=1:length(o)
103 if o{ok}==xt
104 found=true;
105 break;
106 end
107 end
108 if ~found
109 o{length(o)+1}=xt;
110 end
111 end
112 end
113 end
114 end
115 function printOrders (ord)
116 for oi=1:length(ord)
117 fprintf('%g',ord(oi));
118 if oi<length(ord)
119 fprintf(',');
120 end
121 end
122 end
123
124 if length(orders)==1
125 bestX = [];
126 bestY = [];
127 bestLogli = -inf;
128 bestOrders= [];
129 for br=2:orders
130 allord = allorders (br, orders);
131 for ox=1:length(allord)
132 if BuToolsVerbose
133 fprintf('Trying orders ');
134 printOrders(allord{ox});
135 fprintf('...\n');
136 end
137 [oX,oY,l] = MAPFromTrace (trace, allord{ox}, maxIter, stopCond, initial, result);
138 if l > bestLogli
139 bestX = oX;
140 bestY = oY;
141 bestLogli = l;
142 bestOrders = allord{ox};
143 end
144 end
145 end
146 D0 = bestX;
147 D1 = bestY;
148 logli = bestLogli;
149 if BuToolsVerbose
150 fprintf('Best solution: logli=%g, orders=', bestLogli);
151 printOrders(bestOrders);
152 fprintf('\n');
153 end
154 return;
155 end
156
157 function X = generatorFromErlangs (erll, erlo)
158 X = zeros (sum(erlo));
159 xx = 1;
160 for ii=1:length(erll)
161 X(xx:xx+erlo(ii)-1, xx:xx+erlo(ii)-1) = erll(ii)*(diag(ones(1,erlo(ii)-1),1)-diag(ones(1,erlo(ii))));
162 xx = xx + erlo(ii);
163 end
164 end
165
166 M = length(orders);
167 K = length(trace);
168
169 % initial alpha and lambda is such that the mean is matched
170 if isempty(initial)
171 alphav = ones(1,M) / M;
172 lambda = diag(orders) * (1:M)';
173 trm = sum(trace)/length(trace);
174 inim = sum(alphav ./ (1:M));
175 lambda = lambda * inim / trm;
176 P = ones(M,1)*alphav;
177 elseif length(initial)==2
178 lambda = initial{1};
179 P = initial{2};
180 alphav = DTMCSolve(P);
181 else
182 error('Invalid initial branch probability and rate vectors!');
183 end
184
185 Q = zeros(M, K);
186 A = zeros(K, M);
187 B = zeros(M, K);
188 Ascale = zeros(1,K);
189 Bscale = zeros(1,K);
190 ologli = 1;
191 logli = 0;
192 steps = 1;
193 t1 = clock();
194 while abs((ologli-logli)/logli)>stopCond && steps<=maxIter
195 ologli = logli;
196 % E-step:
197 % branch densities:
198 for i=1:M
199 Q(i,:) = ((lambda(i)*trace).^(orders(i)-1) / factorial(orders(i)-1) * lambda(i)) .* exp(-lambda(i)*trace);
200 end
201 % forward likelihood vectors:
202 prev = alphav;
203 scprev = 0;
204 for k=1:K
205 prev = prev*diag(Q(:,k))*P;
206 scale = log2(sum(prev));
207 prev = prev * 2^-scale;
208 Ascale(k) = scprev + scale;
209 A(k,:) = prev;
210 scprev = Ascale(k);
211 end
212 Av = [alphav; A(1:end-1,:)];
213 Ascalev = [0, Ascale(1:end-1)];
214 % backward likelihood vectors:
215 next = ones(M,1);
216 scprev = 0;
217 for k=K:-1:1
218 next = diag(Q(:,k))*P*next;
219 scale = log2(sum(next));
220 next = next * 2^-scale;
221 Bscale(k) = scprev + scale;
222 B(:,k) = next;
223 scprev = Bscale(k);
224 end
225 Bv = [B(:,2:end), ones(M,1)];
226 Bscalev = [Bscale(2:end), 0];
227
228 llh = alphav*B(:,1);
229 logli = (log(llh) + Bscale(1) * log(2)) / K;
230 illh = 1.0 / llh;
231
232 % M-step:
233 % Calculate new estimates for the parameters
234 AB = Av.*B';
235 nor = sum(AB,2);
236 for m=1:M
237 AB(:,m) = AB(:,m)./nor;
238 end
239 v1 = sum(AB,1);
240 v2 = trace'*AB;
241 alphav = v1/K;
242 lambda = (orders.*v1 ./ v2)';
243
244 Avv = Av.*Q';
245 nor = illh*2.^(Ascalev+Bscalev-Bscale(1))';
246 for m=1:M
247 Avv(:,m) = Avv(:,m) .* nor;
248 end
249 P = (Avv'*Bv').*P;
250 for m=1:M
251 P(m,:) = P(m,:) / sum(P(m,:));
252 end
253
254 steps = steps+1;
255 if BuToolsVerbose && etime(clock(),t1)>2
256 fprintf('Num of iterations: %d, logli: %g\n', steps, logli);
257 t1 = clock();
258 end
259 end
260
261 if BuToolsVerbose
262 fprintf('Num of iterations: %d, logli: %g\n', steps, logli);
263 fprintf('EM algorithm terminated. (orders=');
264 for i=1:M
265 fprintf('%g',orders(i));
266 if i<M
267 fprintf(',');
268 else
269 fprintf(')\n');
270 end
271 end
272 end
273
274 if strcmp(result,'vecmat')
275 D0 = lambda;
276 D1 = P;
277 elseif strcmp(result,'matmat')
278 D0 = generatorFromErlangs(lambda, orders);
279 D1 = zeros(size(D0));
280 indicesTo = [1 cumsum(orders(1:end-1))+1];
281 indicesFrom = cumsum(orders);
282 D1(indicesFrom,indicesTo) = diag(lambda)*P;
283 end
284end
285