LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
LikelihoodFromTrace.m
1% logli = LikelihoodFromTrace(trace, X, Y, prec)
2%
3% Evaluates the log-likelihood of a trace with the given PH
4% distribution or MAP. The result is divided by the length
5% of the trace.
6%
7% If X is a row vector, than (X,Y) is interpreted as a PH
8% distribution, otherwise (X,Y) is considered to be a MAP.
9%
10% Parameters
11% ----------
12% trace : column vector, length K
13% The samples of the trace
14% X : matrix, shape (1,M) or (M,M)
15% If X is a row vector, it is the initial probability
16% vector of the PH distribution. If X is a square
17% matrix, it is interpreted as the D0 matrix of a MAP
18% Y : matrix, (M,M)
19% If X is a row vector, Y is the transient generator
20% of the PH distribution. If X is a square matrix, Y
21% is interpreted as the D1 matrix of a MAP
22% prec : double, optional
23% Numerical precision used by the randomization. The
24% default value is 1e-14.
25%
26% Returns
27% -------
28% logli : double
29% The log likelihood divided by the size of the trace
30%
31% Notes
32% -----
33% The procedure is much faster with PH distributions.
34
35function logli = LikelihoodFromTrace (trace, X, Y, prec)
36
37 if ~exist('prec','var')
38 prec = 1e-14;
39 end
40
41 if size(X,1)==1
42
43 % We have a PH distribution. We can sort it to make the computation
44 % faster
45 alpha = X;
46 A = Y;
47 trace = sort(trace);
48 lambda = max(abs(diag(A)));
49 P = A/lambda + eye(size(A));
50 a = sum(-A,2);
51 eps = max(prec, 10^(log10(prec) + log10(lambda)));
52 lpoi = -lambda*trace;
53 trace = log(trace);
54 poi = exp(lpoi);
55 spoi = poi;
56 fx = poi*(alpha*a);
57 k = 1;
58 first = 1;
59 coeffv = alpha;
60 maxIter = 10000;
61 while ~isempty(first) && k<maxIter
62 coeffv = coeffv * P;
63 lpoi(first:end) = lpoi(first:end) + log(lambda) + trace(first:end) - log(k);
64 poi(first:end) = exp(lpoi(first:end));
65 spoi(first:end) = spoi(first:end) + poi(first:end);
66 fx(first:end) = fx(first:end) + poi(first:end) * (coeffv * a);
67 k = k + 1;
68 first = first + find(spoi(first:end)<1-eps,1,'first') - 1;
69 end
70 logli = sum(log(fx))/length(trace);
71 else
72 D0 = X;
73 D1 = Y;
74 N = size(D0,1);
75 L = length(trace);
76
77 % first we calculate matrix e^(D0*x(i))*D1 for each sample
78 [trace,ix] = sort(reshape(trace,[],1));
79 lambda = max(abs(diag(D0)));
80 P = D0/lambda + eye(size(D0));
81 eps = max(prec, 10^(log10(prec) + log10(lambda)));
82 lpoi = -lambda*trace;
83 trace = log(trace);
84 poi = exp(lpoi);
85 spoi = poi;
86 coeffv = D1;
87 fx = kron(poi,coeffv);
88 k = 1;
89 first = 1;
90 maxIter = 10000;
91 while ~isempty(first) && k<maxIter
92 coeffv = P * coeffv;
93 lpoi(first:end) = lpoi(first:end) + log(lambda) + trace(first:end) - log(k);
94 poi(first:end) = exp(lpoi(first:end));
95 spoi(first:end) = spoi(first:end) + poi(first:end);
96 fx((first-1)*N+1:end,:) = fx((first-1)*N+1:end,:) + kron(poi(first:end),coeffv);
97 k = k + 1;
98 first = first + find(spoi(first:end)<1-eps,1,'first') - 1;
99 end
100 alpha = DTMCSolve (inv(-D0)*D1);
101 l = alpha;
102 sc = 0;
103 [~,ixrev]=sort(ix);
104 for i=1:L
105 l = l*fx((ixrev(i)-1)*N+1:ixrev(i)*N,:);
106 if rem(i,10)==0
107 % sometimes we need to rescale the results to avoid "nan"s
108 scale = ceil(log2(sum(l)));
109 if scale>1
110 l = l/2^scale;
111 sc = sc+scale;
112 end
113 if scale<-10
114 scale = scale+10;
115 l = l/2^scale;
116 sc = sc+scale;
117 end
118 end
119 end
120 logli = (log(sum(l))+sc*log(2)) / length(trace);
121 end
122end