1function [p,Qperm,Qdec,eps,epsMAX,
P,B,C,q]=ctmc_courtois(Q,MS,q)
2% CTMC_COURTOIS - Courtois decomposition
3% [p,Qperm,Qdec,eps,epsMAX,
P,B,C,q] = CTMC_COURTOIS(Q,MS)
5% Q : infinitesimal generator matrix
6% MS : cell array where MS{i}
is the set of rows of Q in macrostate i
7% q : (optional) randomization coefficient
9% p : approximate steady-state probability vector
10% Qperm : Q reordered according to macrostates
11% Qdec : infinitesimal generator for the macrostates
12%
P : probability matrix obtained from Qperm with randomization
13% B : part of
P not modelled by decomposition
14% eps : nearly-complete decomposability (NCD) index
15% epsMAX : max acceptable value for eps (otherwise Q
is not NCD)
16% q : randomization coefficient
23nMacroStates = size(MS,1); % Number of macro-states
24%% REARRANGE INFINITESIMAL GENERATOR ACCORDING TO THE MACROSTATES
29Qperm=Q(v,v); % reorder according to the
new macro-states
31procRows=0; %processed rows
32for i = 1:size(MS,1) %
for each macro-state
34 Qdec((procRows + 1):(procRows + length(MS{i})),1:procRows)=0;
36 Qdec((procRows + 1):(procRows + length(MS{i})),(procRows + length(MS{i})+1):end)=0;
37 procRows = procRows + length(MS{i});
39% now make each substochastic diagonal block a stochastic matrix
40Qdec=ctmc_makeinfgen(Qdec);
42%% COMPUTE NCD ERROR INDEX
50 q=(1.05*max(max(abs(Qperm))));
53P=ctmc_randomization(Qperm,q);
55procRows=0; %processed rows
56for i = 1:nMacroStates %
for each macro-state
58 A((procRows + 1):(procRows + length(MS{i})),1:procRows)=0;
60 A((procRows + 1):(procRows + length(MS{i})),(procRows + length(MS{i})+1):end)=0;
61 procRows = procRows + length(MS{i});
66% the following subprocedure makes each diagonal block stochastic by
67% placing a normalization condition in the diagonal position
69procRows=0; %processed rows
70for i = 1:size(MS,1) %
for each macro-state
73 A(procRows+j,procRows+pos)=1-(sum(A(procRows+j,setdiff((procRows+1):(procRows+length(MS{i})),(procRows+pos)))));
75 procRows = procRows + length(MS{i});
77eigMS = zeros(1,size(MS,1));
78procRows=0; %processed rows
79for i=1:size(MS,1) %
for each macro-state
80 e=sort(abs(eig(A((procRows + 1):(procRows + length(MS{i})),(procRows + 1):(procRows + length(MS{i}))))));
82 eigMS(i)=e(end-1); % take the second largest eigvalues of the block
84 eigMS(i)=0; % skip
if there
is no second eigenvalue
86 procRows = procRows + length(MS{i});
88epsMAX=(1-max(eigMS))/2;
93%% COMPUTE MICROPROBABILITIES
94procRows=0; %processed rows
95pmicro=zeros(size(Q,1),1);
96for i = 1:nMacroStates %
for each macro-state
97 Qmicrostate=Qdec((procRows + 1):(procRows + length(MS{i})),(procRows + 1):(procRows + length(MS{i})));
98 pmicro((procRows + 1):(procRows + length(MS{i})),1)=ctmc_solve_reducible(Qmicrostate);
99 procRows = procRows + length(MS{i});
102%% COMPUTE MACROPROBABILITIES
103G=zeros(nMacroStates,nMacroStates);
104procRows=0; %processed rows
105for i = 1:nMacroStates %
for each source macro-state
106 procCols=0; %processed cols
107 for j = 1:nMacroStates %
for dest macro-state
109 for iState=1:length(MS{i})
110 G(i,j)=G(i,j)+pmicro(procRows+iState)*sum(
P(procRows+iState,(procCols+1):(procCols+length(MS{j}))));
113 procCols = procCols + length(MS{j});
115 procRows = procRows + length(MS{i});
117for i = 1:nMacroStates %
for each source macro-state
118 G(i,i)=1-sum(G(i,:));
121procRows=0; %processed rows
122for i = 1:nMacroStates %
for each source macro-state
123 p((procRows+1):(procRows+length(MS{i})))=pMacro(i)*pmicro((procRows+1):(procRows+length(MS{i})));
124 procRows = procRows + length(MS{i});