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
19% The randomization coefficient q
is derived below, once Qperm
is available,
20% because it depends on Qperm. It must be a valid uniformization rate
21% (q >= max|q_ii|) or
P=I+Qperm/q
is not stochastic; 1.05*max|Qperm| exceeds
22% max|q_ii| strictly, which also keeps
P aperiodic. An
explicit q (nargin==3)
23% overrides
the derived value.
25nMacroStates = size(MS,1); % Number of macro-states
26%% REARRANGE INFINITESIMAL GENERATOR ACCORDING TO THE MACROSTATES
31Qperm=Q(v,v); % reorder according to
the new macro-states
33procRows=0; %processed rows
34for i = 1:size(MS,1) %
for each macro-state
36 Qdec((procRows + 1):(procRows + length(MS{i})),1:procRows)=0;
38 Qdec((procRows + 1):(procRows + length(MS{i})),(procRows + length(MS{i})+1):end)=0;
39 procRows = procRows + length(MS{i});
41% now make each substochastic diagonal block a stochastic matrix
42Qdec=ctmc_makeinfgen(Qdec);
44%% COMPUTE NCD ERROR INDEX
52 q=(1.05*max(max(abs(Qperm))));
55P=ctmc_randomization(Qperm,q);
57procRows=0; %processed rows
58for i = 1:nMacroStates %
for each macro-state
60 A((procRows + 1):(procRows + length(MS{i})),1:procRows)=0;
62 A((procRows + 1):(procRows + length(MS{i})),(procRows + length(MS{i})+1):end)=0;
63 procRows = procRows + length(MS{i});
68%
the following subprocedure makes each diagonal block stochastic by
69% placing a normalization condition in
the diagonal position
71procRows=0; %processed rows
72for i = 1:size(MS,1) %
for each macro-state
75 A(procRows+j,procRows+pos)=1-(sum(A(procRows+j,setdiff((procRows+1):(procRows+length(MS{i})),(procRows+pos)))));
77 procRows = procRows + length(MS{i});
79eigMS = zeros(1,size(MS,1));
80procRows=0; %processed rows
81for i=1:size(MS,1) %
for each macro-state
82 e=sort(abs(eig(A((procRows + 1):(procRows + length(MS{i})),(procRows + 1):(procRows + length(MS{i}))))));
84 eigMS(i)=e(end-1); % take
the second largest eigvalues of
the block
86 eigMS(i)=0; % skip
if there
is no second eigenvalue
88 procRows = procRows + length(MS{i});
90epsMAX=(1-max(eigMS))/2;
95%% COMPUTE MICROPROBABILITIES
96procRows=0; %processed rows
97pmicro=zeros(size(Q,1),1);
98for i = 1:nMacroStates %
for each macro-state
99 Qmicrostate=Qdec((procRows + 1):(procRows + length(MS{i})),(procRows + 1):(procRows + length(MS{i})));
100 pmicro((procRows + 1):(procRows + length(MS{i})),1)=ctmc_solve_reducible(Qmicrostate);
101 procRows = procRows + length(MS{i});
104%% COMPUTE MACROPROBABILITIES
105G=zeros(nMacroStates,nMacroStates);
106procRows=0; %processed rows
107for i = 1:nMacroStates %
for each source macro-state
108 procCols=0; %processed cols
109 for j = 1:nMacroStates %
for dest macro-state
111 for iState=1:length(MS{i})
112 G(i,j)=G(i,j)+pmicro(procRows+iState)*sum(
P(procRows+iState,(procCols+1):(procCols+length(MS{j}))));
115 procCols = procCols + length(MS{j});
117 procRows = procRows + length(MS{i});
119for i = 1:nMacroStates %
for each source macro-state
120 G(i,i)=1-sum(G(i,:));
123procRows=0; %processed rows
124for i = 1:nMacroStates %
for each source macro-state
125 p((procRows+1):(procRows+length(MS{i})))=pMacro(i)*pmicro((procRows+1):(procRows+length(MS{i})));
126 procRows = procRows + length(MS{i});