1function [p,p_1,Qperm,eps,epsMAX,pcourt]=ctmc_kms(Q,MS,numSteps)
2% CTMC_KMS - Koury-McAllister-Stewart aggregation-disaggregation method
3% [p,p_1,Qperm,eps,epsMAX,pcourt] = CTMC_KMS(Q,MS,numSteps)
5% Q : infinitesimal generator matrix
6% MS : cell array where MS{i}
is the set of rows of Q in macrostate i
7% numSteps: number of iterative steps
9% p : estimated steady-state probability vector
11% Qperm : permuted Q matrix w.r.t MS as returned by ctmc_courtois
12% eps : NCD index as returned by ctmc_courtois
13% epsMAX : max acceptable value
for eps (otherwise Q
is not NCD)
14% pcourt : steady-state probability vector estimated by ctmc_courtois
16% * The initial approximate solutions
is obtained by calling CTMC_COURTOIS(Q,MS)
17% * No convergence stop criterion
is currently implented
20nMacroStates = size(MS,1); % Number of macro-states
22%% START FROM COURTOIS DECOMPOSITION SOLUTION
23[pcourt,Qperm,Qdec,eps,epsMAX,
P,B,C]=ctmc_courtois(Q,MS);
25%
P and
the macro-block offsets used below are in PERMUTED (macrostate-major)
26% ordering, whereas ctmc_courtois returns pcourt already mapped back to
the
27% ORIGINAL state ordering. Permute
the initial vector into block order so that
28% it lives in
the same index space as
P, and undo
the permutation on output.
34p_1=pn(:); % defined even when numSteps==0
37 pn_1=pn(:); % canonical
column orientation regardless of iteration
41 procRows=0; %processed rows
42 for I = 1:nMacroStates %
for each macro-state
43 if sum(pn_1((procRows + 1):(procRows + length(MS{I}))))>0
44 pcondn_1((procRows + 1):(procRows + length(MS{I})))=pn_1((procRows + 1):(procRows + length(MS{I})))/sum(pn_1((procRows + 1):(procRows + length(MS{I}))));
46 procRows = procRows + length(MS{I});
49 G=zeros(nMacroStates,nMacroStates);
50 procCols=0; %processed rows
51 for I = 1:nMacroStates %
for each source macro-state
52 procRows=0; %processed rows
53 for J = 1:nMacroStates %
for each dest macro-state
55 %size(pcondn_1((procRows + 1):(procRows + length(MS{J})))
')
56 %size(P((procRows + 1):(procRows + length(MS{J})),(procCols + 1):(procCols + length(MS{I}))))
57 %size(ones(length(MS{I}),1))
58 G(I,J)=pcondn_1((procRows + 1):(procRows + length(MS{J})))'*
P((procRows + 1):(procRows + length(MS{J})),(procCols + 1):(procCols + length(MS{I})))*ones(length(MS{I}),1);
59 procRows = procRows + length(MS{J});
61 procCols = procCols + length(MS{I});
65 %% DISAGGREGATION STEP
67 zn=zeros(1,nStates); % row: zn*L below requires row orientation
68 L=zeros(nStates,nStates);
69 D=zeros(nStates,nStates);
70 U=zeros(nStates,nStates);
71 procRows=0; %processed rows
72 for I = 1:nMacroStates % for each macro-state
73 zn((procRows + 1):(procRows + length(MS{I})))=w(I)*z((procRows + 1):(procRows + length(MS{I})))';
74 procCols=0; %processed rows
75 for J = 1:nMacroStates
77 L((procRows + 1):(procRows + length(MS{I})),(procCols + 1):(procCols + length(MS{J})))=
P((procRows + 1):(procRows + length(MS{I})),(procCols + 1):(procCols + length(MS{J})));
80 D((procRows + 1):(procRows + length(MS{I})),(procCols + 1):(procCols + length(MS{J})))=eye(length(MS{I}))-
P((procRows + 1):(procRows + length(MS{I})),(procCols + 1):(procCols + length(MS{J})));
83 U((procRows + 1):(procRows + length(MS{I})),(procCols + 1):(procCols + length(MS{J})))=
P((procRows + 1):(procRows + length(MS{I})),(procCols + 1):(procCols + length(MS{J})));
85 procCols = procCols + length(MS{J});
87 procRows = procRows + length(MS{I});
90 % Block Gauss-Seidel sweep: solve pn*(D-U) = zn*L directly. The former
91 % 2-block inverse [invA,-invA*B*invC;0,invC] split M at an arbitrary
92 % midpoint rather than a macro-block boundary, which
is invalid.
96 [xg,gflag]=ctmc_gmres(M',rhs);
107% Map back from permuted (macrostate-major) to original state ordering.
110pback=zeros(nStates,1);