1% M = FluidFundamentalMatrices(Fpp, Fpm, Fmp, Fmm, matrices, precision, maxNumIt, method)
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).
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
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
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".
47% The list of calculated matrices in the order as
48% requested in the
'matrices' parameter.
52% Thanks to Benny Van Houdt for the implementation of the
55function varargout = FluidFundamentalMatrices (Fpp, Fpm, Fmp, Fmm, matrices, precision, maxNumIt, method)
57 if ~exist(
'precision',
'var')
60 if ~exist(
'maxNumIt',
'var')
63 if ~exist('method','var')
69 Psi = zeros(0,size(Fmm,1));
70 elseif strcmp(method,'CR')
71 F = [Fpp,Fpm;Fmp,Fmm];
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
80 N = [Pf(1:sp,sp+1:end)/2.0; Pf(sp+1:sp+sm,sp+1:sp+sm)];
82 while min(norm(R1,inf),norm(N,inf))> precision && numit<maxNumIt
85 S1 = Xmat(sp+1:end,1:sp)*R1;
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;
93 Ghat = inv(I-A1hat) * [Pf(1:sp,sp+1:end)/2.0; Pf(sp+1:end,sp+1:end)];
95 elseif strcmp(method,'ADDA') || strcmp(method,'SDA')
96 % via ADDA algorithm (Wang, Wang, Li 2011)
101 gamma1 = max(diag(A));
102 gamma2 = max(diag(D));
103 if strcmp(method,'SDA')
104 gamma1 = max(gamma1,gamma2);
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;
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;
131 if strcmp(method,'ADDA')
144 global BuToolsVerbose;
145 if numit == maxNumIt && BuToolsVerbose==true
146 fprintf('Maximum Number of Iterations reached');
149 if BuToolsVerbose==true
150 res_norm = norm (Fpm+Fpp*Psi+Psi*Fmm+Psi*Fmp*Psi, inf);
151 fprintf('Final Residual Error for Psi: ');
155 ret = cell(1,length(matrices));
156 for i=1:length(matrices)
159 elseif matrices(i)==
'K'
160 ret{i} = Fpp+Psi*Fmp;
161 elseif matrices(i)==
'U'
162 ret{i} = Fmm+Fmp*Psi;