LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
ctmc_courtois.m
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)
4% -- Input
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
8% -- Output
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
17
18%% INIT
19if nargin==2
20 q=1;
21end
22v=[];
23nMacroStates = size(MS,1); % Number of macro-states
24%% REARRANGE INFINITESIMAL GENERATOR ACCORDING TO THE MACROSTATES
25
26for n=1:nMacroStates
27 v=[v,MS{n}];
28end
29Qperm=Q(v,v); % reorder according to the new macro-states
30Qdec=Qperm;
31procRows=0; %processed rows
32for i = 1:size(MS,1) % for each macro-state
33 if procRows >0
34 Qdec((procRows + 1):(procRows + length(MS{i})),1:procRows)=0;
35 end
36 Qdec((procRows + 1):(procRows + length(MS{i})),(procRows + length(MS{i})+1):end)=0;
37 procRows = procRows + length(MS{i});
38end
39% now make each substochastic diagonal block a stochastic matrix
40Qdec=ctmc_makeinfgen(Qdec);
41
42%% COMPUTE NCD ERROR INDEX
43epsC=Qperm-Qdec;
44epsC=0;
45C=epsC;
46eps=1;
47
48% apply randomization
49if nargin==2
50 q=(1.05*max(max(abs(Qperm))));
51end
52
53P=ctmc_randomization(Qperm,q);
54A=P;
55procRows=0; %processed rows
56for i = 1:nMacroStates % for each macro-state
57 if procRows >0
58 A((procRows + 1):(procRows + length(MS{i})),1:procRows)=0;
59 end
60 A((procRows + 1):(procRows + length(MS{i})),(procRows + length(MS{i})+1):end)=0;
61 procRows = procRows + length(MS{i});
62end
63B=P-A;
64eps=max(sum(B));
65%% COMPUTE epsMAX
66% the following subprocedure makes each diagonal block stochastic by
67% placing a normalization condition in the diagonal position
68if nargout>3
69procRows=0; %processed rows
70for i = 1:size(MS,1) % for each macro-state
71 for j=1:length(MS{i})
72 pos=j;
73 A(procRows+j,procRows+pos)=1-(sum(A(procRows+j,setdiff((procRows+1):(procRows+length(MS{i})),(procRows+pos)))));
74 end
75 procRows = procRows + length(MS{i});
76end
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}))))));
81 if length(e)>1
82 eigMS(i)=e(end-1); % take the second largest eigvalues of the block
83 else
84 eigMS(i)=0; % skip if there is no second eigenvalue
85 end
86 procRows = procRows + length(MS{i});
87end
88epsMAX=(1-max(eigMS))/2;
89else
90 eps=0;
91 epsMax=0;
92end
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});
100end
101
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
108 if i~=j
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}))));
111 end
112 end
113 procCols = procCols + length(MS{j});
114 end
115 procRows = procRows + length(MS{i});
116end
117for i = 1:nMacroStates % for each source macro-state
118 G(i,i)=1-sum(G(i,:));
119end
120pMacro=dtmc_solve(G);
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});
125end
126%% OUTPUT
127for i=1:length(v)
128pout(v(i))=p(i);
129end
130p=pout;
131