LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
ExtendToMarkovian.m
1% [beta, B] = ExtendToMarkovian(alpha, A, maxSize, precision)
2%
3% Assume we have an existing monocyclic (or acyclic)
4% representation of a matrix-exponential distribution
5% described by matrix A and vector alpha such that A is
6% Markovian but alpha is not. This procedure appends an
7% appropriate Erlang tail to the representation that makes
8% the result Markovian (both the generator matrix and the
9% initial vector parameter), while keeping the distribution
10% the same. In [1]_ it is proven that this is always
11% possible if the initial (alpha,A) defines a distribuion
12% (non-negative density).
13%
14% Parameters
15% ----------
16% alpha : vector, shape (1,M)
17% The (non-Markovian) initial vector
18% A : matrix, shape (M,M)
19% The (Markovian) transient generator.
20% maxSize : int, optional
21% The procedure stops if more than maxSize new phases
22% are required. The default value is 100
23% precision : double, optional
24% The initial vector is considered to be valid if the
25% smallest entry is greater than -precision. The
26% default value is 1e-14
27%
28% Returns
29% -------
30% beta : vector, shape (1,N)
31% The Markovian initial vector (N>=M)
32% B : matrix, shape (N,N)
33% The Markovian transient generator (N>=M).
34%
35% References
36% ----------
37% .. [1] Mocanu, S., Commault, C.: "Sparse representations
38% of phase-type distributions," Stoch. Models 15,
39% 759-778 (1999)
40
41function [beta, B] = ExtendToMarkovian (alpha, A, maxSize, precision)
42
43 if ~exist('precision','var')
44 precision = 1e-14;
45 end
46
47 if ~exist('maxSize','var')
48 maxSize = 100;
49 end
50
51 function E = addErlangTail (D, len, mu)
52 DN = size(D,1);
53 E = zeros(DN+len);
54 E(1:DN,1:DN) = D;
55 E(DN,DN+1) = -sum(D(DN,:));
56 for ei=1:len
57 E(DN+ei,DN+ei) = -mu;
58 if ei<len
59 E(DN+ei,DN+ei+1) = mu;
60 end
61 end
62 end
63
64 function beta = inivecwithtail (gamma, G, tailLengthx, mux)
65 vlen = size(G,1)+tailLengthx;
66 beta = zeros(1, vlen);
67 WG = eye(size(G))+G/mux;
68 opv = gamma;
69 clv = -sum(G/mux,2);
70 for k=vlen:-1:size(G,1)+1
71 beta(k) = opv*clv;
72 opv = opv * WG;
73 end
74 beta(1:size(G,1)) = opv;
75 end
76
77 % initial value of t0upper
78 t0lower = 0;
79 t0upper = 1;
80 beta = alpha * expm(A*t0upper);
81 while min(beta)<-precision
82 t0upper = t0upper * 2;
83 beta = alpha * expm(A*t0upper);
84 end
85
86 % interval bisectioning
87 while (t0upper - t0lower)/(t0upper + t0lower) > precision
88 t0 = (t0upper + t0lower) / 2;
89 beta = alpha * expm(A*t0);
90 if min(beta)<-precision
91 t0lower = t0;
92 else
93 t0upper = t0;
94 end
95 end
96 t0 = t0upper;
97
98 % find optimal length and rate parameters of the Erlang tail
99
100 % points towards t0 sometimes give fewer states
101 % thus we try to increase t0 gradually till the number of states
102 % decreases
103
104 increment = 1.1;
105 bestT0 = -1;
106 bestLupper = -1;
107 for i=1:100
108 % initial value of Lupper
109 Llower = 1;
110 Lupper = 1;
111 beta = inivecwithtail (alpha, A, Lupper, Lupper/t0);
112 while min(beta)<-precision && Lupper<maxSize
113 Lupper = Lupper * 2;
114 beta = inivecwithtail (alpha, A, Lupper, Lupper/t0);
115 end
116
117 success = min(beta)>=-precision;
118 if success
119 % interval bisectioning
120 while Lupper - Llower > 1
121 L = round((Lupper + Llower) / 2);
122 beta = inivecwithtail (alpha, A, L, L/t0);
123 if min(beta)<-precision
124 Llower = L;
125 else
126 Lupper = L;
127 end
128 end
129 end
130
131 if success
132 if bestLupper>=0 && Lupper>bestLupper % there was a successfull attempt before, and this one is worse
133 break; % stop and keep what we have
134 else % otherwise go on and increment t0
135 bestLupper = Lupper;
136 bestT0 = t0;
137 t0 = t0 * increment;
138 end
139 else
140 if bestLupper>=0
141 break;
142 else
143 t0 = t0 * increment;
144 end
145 end
146 end
147 t0 = bestT0;
148 Lupper = bestLupper;
149
150 if Lupper<0
151 error ('No positive representation found up to the given size!');
152 end
153
154 % final result
155 beta = inivecwithtail (alpha, A, Lupper, Lupper/t0);
156 B = addErlangTail (A, Lupper, Lupper/t0);
157end