LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
FluidFundamentalMatrices.m
1% M = FluidFundamentalMatrices(Fpp, Fpm, Fmp, Fmm, matrices, precision, maxNumIt, method)
2%
3% Returns the fundamental matrices corresponding to the
4% given canonical Markov fluid model. Matrices Psi, K and
5% U are returned depending on the "matrices" parameter.
6% The canonical Markov fluid model is defined by the
7% matrix blocks of the generator of the background Markov
8% chain partitioned according to the sign of the
9% associated fluid rates (i.e., there are "+" and "-" states).
10%
11% Parameters
12% ----------
13% Fpp : matrix, shape (Np,Np)
14% The matrix of transition rates between states
15% having positive fluid rates
16% Fpm : matrix, shape (Np,Nm)
17% The matrix of transition rates where the source
18% state has a positive, the destination has a
19% negative fluid rate associated.
20% Fpm : matrix, shape (Nm,Np)
21% The matrix of transition rates where the source
22% state has a negative, the destination has a
23% positive fluid rate associated.
24% Fpp : matrix, shape (Nm,Nm)
25% The matrix of transition rates between states
26% having negative fluid rates
27% matrices : string
28% Specifies which matrices are required. 'P' means
29% that only matrix Psi is needed. 'UK' means that
30% matrices U and K are needed. Any combinations of
31% 'P', 'K' and 'U' are allowed, in any order.
32% precision : double, optional
33% The matrices are computed iteratively up to this
34% precision. The default value is 1e-14
35% maxNumIt : int, optional
36% The maximal number of iterations. The default value
37% is 50.
38% method : {"CR", "ADDA", "SDA"}, optional
39% The method used to solve the algebraic Riccati
40% equation (CR: cyclic reduction, ADDA: alternating-
41% directional doubling algorithm, SDA: structured
42% doubling algorithm). The default is "CR".
43%
44% Returns
45% -------
46% M : list of matrices
47% The list of calculated matrices in the order as
48% requested in the 'matrices' parameter.
49%
50% Notes
51% -----
52% Thanks to Benny Van Houdt for the implementation of the
53% Riccati solvers.
54
55function varargout = FluidFundamentalMatrices (Fpp, Fpm, Fmp, Fmm, matrices, precision, maxNumIt, method)
56
57 if ~exist('precision','var')
58 precision = 1e-14;
59 end
60 if ~exist('maxNumIt','var')
61 maxNumIt = 150;
62 end
63 if ~exist('method','var')
64 method = 'ADDA';
65 end
66
67 if size(Fpp,1)==0
68 numit = 0;
69 Psi = zeros(0,size(Fmm,1));
70 elseif strcmp(method,'CR')
71 F = [Fpp,Fpm;Fmp,Fmm];
72 sp = size(Fpp,1);
73 sm = size(Fmm,1);
74 I = eye(sm+sp);
75 Pf = I + F / max(-diag(F));
76 A1 = [Pf(1:sp,1:sp)/2.0, zeros(sp,sm); Pf(sp+1:end,1:sp), zeros(sm,sm)];
77 % Optimized cyclic reduction
78 A1hat=A1;
79 R1 = eye(sp) / 2.0;
80 N = [Pf(1:sp,sp+1:end)/2.0; Pf(sp+1:sp+sm,sp+1:sp+sm)];
81 numit = 0;
82 while min(norm(R1,inf),norm(N,inf))> precision && numit<maxNumIt
83 Xmat = inv(I-A1);
84 B = Xmat*N;
85 S1 = Xmat(sp+1:end,1:sp)*R1;
86 U = R1*B(1:sp,:);
87 A1 = A1 + [N*S1, [U; zeros(sm,sm)]];
88 A1hat(1:sp,sp+1:end) = A1hat(1:sp,sp+1:end) + U;
89 N = N * B(sp+1:end,:);
90 R1 = R1 * Xmat(1:sp,1:sp) * R1;
91 numit = numit + 1;
92 end
93 Ghat = inv(I-A1hat) * [Pf(1:sp,sp+1:end)/2.0; Pf(sp+1:end,sp+1:end)];
94 Psi = Ghat(1:sp,:);
95 elseif strcmp(method,'ADDA') || strcmp(method,'SDA')
96 % via ADDA algorithm (Wang, Wang, Li 2011)
97 A = -Fpp;
98 B = Fpm;
99 C = Fmp;
100 D = -Fmm;
101 gamma1 = max(diag(A));
102 gamma2 = max(diag(D));
103 if strcmp(method,'SDA')
104 gamma1 = max(gamma1,gamma2);
105 gamma2 = gamma1;
106 end
107 sA = size(A,1);
108 sD = size(D,1);
109 IA = eye(sA);
110 ID = eye(sD);
111 A = A + gamma2*IA;
112 D = D + gamma1*ID;
113 Dginv = inv(D);
114 Vginv = inv(D-C*inv(A)*B);
115 Wginv = inv(A-B*Dginv*C);
116 Eg = ID - (gamma1+gamma2)*Vginv;
117 Fg = IA - (gamma1+gamma2)*Wginv;
118 Gg = (gamma1+gamma2)*Dginv*C*Wginv;
119 Hg = (gamma1+gamma2)*Wginv*B*Dginv;
120 diff = 1.0;
121 numit = 0;
122 while diff > precision && numit < maxNumIt
123 Vginv = Eg*inv(ID-Gg*Hg);
124 Wginv = Fg*inv(IA-Hg*Gg);
125 Gg = Gg + Vginv*Gg*Fg;
126 Hg = Hg + Wginv*Hg*Eg;
127 Eg = Vginv*Eg;
128 Fg = Wginv*Fg;
129 neg = norm(Eg,1);
130 nfg = norm(Fg,1);
131 if strcmp(method,'ADDA')
132 eta = sqrt(nfg/neg);
133 Eg = Eg*eta;
134 Fg = Fg/eta;
135 diff = neg*nfg;
136 else
137 diff = min(neg,nfg);
138 end
139 numit = numit + 1;
140 end
141 Psi = Hg;
142 end
143
144 global BuToolsVerbose;
145 if numit == maxNumIt && BuToolsVerbose==true
146 fprintf('Maximum Number of Iterations reached');
147 end
148
149 if BuToolsVerbose==true
150 res_norm = norm (Fpm+Fpp*Psi+Psi*Fmm+Psi*Fmp*Psi, inf);
151 fprintf('Final Residual Error for Psi: ');
152 disp(res_norm);
153 end
154
155 ret = cell(1,length(matrices));
156 for i=1:length(matrices)
157 if matrices(i)=='P'
158 ret{i} = Psi;
159 elseif matrices(i)=='K'
160 ret{i} = Fpp+Psi*Fmp;
161 elseif matrices(i)=='U'
162 ret{i} = Fmm+Fmp*Psi;
163 end
164 end
165 varargout=ret;
166end
167