1classdef MarkovChain < Process
2 % An abstract
class for a discrete time Markov chain
4 % Copyright (c) 2012-2026, Imperial College London
14 function self = MarkovChain(transMat, isFinite)
15 % SELF = MARKOVCHAIN(transMat, isInfinite)
16 self@Process(
'MarkovChain', 1);
18 self.transMat = dtmc_makestochastic(transMat);
23 self.isfinite = isFinite;
27 function A = toMarkovProcess(self)
28 Q= self.transMat - eye(size(self.transMat));
30 A.setStateSpace(self.stateSpace);
33 function A = toCTMC(self)
34 % TOCTMC - Alias
for toMarkovProcess
for backwards compatibility
35 A = self.toMarkovProcess();
38 function Ap = toTimeReversed(self)
39 Ap = MarkovChain(dtmc_timereverse(self.transMat));
42 function transMat = getTransMat(self)
43 transMat = self.transMat;
46 function sts = sample(self, n)
47 % STS = SAMPLE(N) - Simulate n steps of
the DTMC from a random initial state
51 pi0 = rand(1, size(self.transMat,1)); pi0 = pi0/sum(pi0);
52 sts = dtmc_simulate(self.transMat, pi0, n);
55 function setStateSpace(self,stateSpace)
56 self.stateSpace = stateSpace;
61 if ~isempty(self.stateSpace)
62 for s=1:size(self.stateSpace,1)
63 if size(self.stateSpace,2)>1
64 nodeLbl{s} = sprintf(
'%s%d', sprintf(
'%d,', self.stateSpace(s,1:end-1)), self.stateSpace(s,end));
66 nodeLbl{s} = sprintf(
'%d', self.stateSpace(s,end));
73 if ~isempty(self.stateSpace)
75 edgeLbl{end+1,1} = nodeLbl{I(t)};
76 edgeLbl{end,2} = nodeLbl{J(t)};
77 edgeLbl{end,3} = sprintf(
'%.2f',(q(t)));
81 edgeLbl{end+1,1} = num2str(I(t));
82 edgeLbl{end,2} = num2str(J(t));
83 edgeLbl{end,3} = sprintf(
'%.2f',(q(t)));
86 if length(nodeLbl) <= 6
87 colors = cell(1,length(nodeLbl));
for i=1:length(nodeLbl), colors{i}=
'w'; end
88 graphViz4Matlab(
'-adjMat',P0,
'-nodeColors',colors,
'-nodeLabels',nodeLbl,
'-edgeLabels',edgeLbl,
'-layout',Circularlayout);
90 graphViz4Matlab(
'-adjMat',P0,
'-nodeLabels',nodeLbl,
'-edgeLabels',edgeLbl,
'-layout',Springlayout);
97 function dtmcObj=rand(nStates) % creates a random DTMC
98 dtmcObj = MarkovChain(dtmc_rand(nStates));
101 function dtmcObj=fromSampleSysAggr(sa)
103 sampleState = sa.state{1};
104 for r=2:length(sa.state)
105 % per-node trajectories are time-aligned: join
column-wise
106 sampleState = [sampleState, sa.state{r}];
108 [stateSpace,~,stateHash] = unique(sampleState,
'rows');
109 dtmc = spalloc(length(stateSpace),length(stateSpace),length(stateSpace)); % assume O(n) elements with n states
110 holdTime = zeros(length(stateSpace),1);
111 for i=2:length(stateHash)
112 if isempty(dtmc(stateHash(i-1),stateHash(i)))
113 dtmc(stateHash(i-1),stateHash(i)) = 0;
115 dtmc(stateHash(i-1),stateHash(i)) = dtmc(stateHash(i-1),stateHash(i)) + 1;
116 holdTime(stateHash(i-1)) = holdTime(stateHash(i-1)) + sa.t(i) - sa.t(i-1);
118 % at
this point, dtmc has absolute counts so not yet normalized
119 dtmc = dtmc_makestochastic(dtmc);
120 dtmcObj = MarkovChain(dtmc, isFinite);
121 dtmcObj.setStateSpace(stateSpace);