LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
Markovian.m
1classdef Markovian < ContinuousDistribution
2 % An astract class for Markovian distributions
3 %
4 % Copyright (c) 2012-2026, Imperial College London
5 % All rights reserved.
6
7 methods (Hidden)
8 function self = Markovian(name, numParam)
9 % SELF = MARKOVIANDISTRIBUTION(NAME, NUMPARAM)
10
11 % Abstract class constructor
12 self@ContinuousDistribution(name, numParam, [0,Inf]);
13 nPhases = 0;
14 end
15 end
16
17 properties (Hidden)
18 process;
19 nPhases;
20 end
21
22 methods
23
24 % alpha,T process of a PH distribution
25 % function alpha_vec = alpha(self)
26 % alpha_vec = self.getInitProb;
27 % end
28
29 % function T_mat = T(self)
30 % T_mat = self.getProcess{0};
31 % end
32
33 % D matrices process as in MAPs
34 function Di = D(self, i, wantSparse)
35 % Di = D(i)
36 if nargin<3
37 wantSparse = false;
38 end
39
40 % Return process matrix, e.g., D0=MAP.D(0)
41 if wantSparse
42 if nargin<2
43 Di=self.getProcess;
44 else
45 Di=self.getProcess{i+1};
46 end
47 else
48 if nargin<2
49 Di=self.getProcess;
50 for i=1:length(Di)
51 Di(i)=full(Di(i));
52 end
53 else
54 Di=full(self.getProcess{i+1});
55 end
56 end
57 end
58
59 function X = sample(self, n)
60 % X = SAMPLE(N)
61
62 % Get n samples from the distribution
63 if nargin<2 %~exist('n','var'),
64 n = 1;
65 end
66 X = map_sample(self.getProcess,n);
67 end
68
69 function EXn = getMoments(self, n)
70 % EXN = GETMOMENTS(N)
71
72 if nargin<2 %~exist('n','var'),
73 n = 3;
74 end
75 PH = self.getProcess;
76 EXn = map_moment(PH,1:n);
77 end
78
79 function MEAN = getMean(self)
80 % MEAN = GETMEAN()
81 if ~isempty(self.mean)
82 MEAN = self.mean;
83 else
84 if isnan(self.getProcess{1})
85 MEAN = NaN;
86 else
87 MEAN = map_mean(self.getProcess);
88 end
89 self.mean = MEAN;
90 end
91 if isnan(self.immediate)
92 self.immediate = MEAN < GlobalConstants.FineTol;
93 end
94 end
95
96 function SCV = getSCV(self)
97 % SCV = GETSCV()
98 % Get the squared coefficient of variation of the distribution (SCV = variance / mean^2)
99 if any(isnan(self.getProcess{1}))
100 SCV = NaN;
101 else
102 SCV = map_scv(self.getProcess);
103 end
104 end
105
106 function SKEW = getSkewness(self)
107 % SKEW = GETSKEWNESS()
108 if any(isnan(self.getProcess{1}))
109 SKEW = NaN;
110 else
111 SKEW = map_skew(self.getProcess);
112 end
113 end
114
115 function Ft = evalCDF(self,t)
116 % FT = EVALCDF(SELF,T)
117
118 % Evaluate the cumulative distribution function at t
119 % AT T
120
121 Ft = map_cdf(self.getProcess,t);
122 end
123
124 function alpha = getInitProb(self)
125 % ALPHA = GETINITPROB()
126 aph = self.getProcess;
127 alpha = map_pie(aph);
128 end
129
130 function T = getSubgenerator(self)
131 % T = GETSUBGENERATOR()
132
133 % Get generator
134 aph = self.getProcess;
135 T = aph{1};
136 end
137
138 function mu = getMu(self)
139 % MU = GETMU()
140
141 % Return total outgoing rate from each state
142 aph = self.getProcess;
143 mu = - diag(aph{1});
144 end
145
146 function phi = getPhi(self)
147 % PHI = GETPHI()
148
149 % Return the probability that a transition out of a state is
150 % absorbing
151 aph = self.getProcess;
152 if aph{1}(1,1)==0
153 phi = 1;
154 else
155 phi = - aph{2}*ones(size(aph{1},1),1) ./ diag(aph{1});
156 end
157 end
158
159 end
160
161 methods
162
163 % overload isImmediate for higher perofrmance
164 function bool = isImmediate(self)
165 % BOOL = ISIMMEDIATE()
166 % Check if the distribution is equivalent to an Immediate
167 % distribution
168 if isnan(self.immediate)
169 self.immediate = self.getMean < GlobalConstants.FineTol;
170 end
171 bool = self.immediate;
172 end
173
174 function setRate(self,RATE)
175 % SETRATE(SELF,RATE)
176
177 % Update rate
178 self.setMean(1/RATE);
179 end
180
181 function self = setMean(self, MEAN)
182 % SELF = UPDATEMEAN(MEAN)
183
184 % Update distribution with given mean and variance
185 md = self.fitMeanAndSCV(MEAN,self.getSCV);
186 self.process = md.process;
187 self.mean = MEAN;
188 self.immediate = MEAN < GlobalConstants.FineTol;
189 self.params = md.params;
190 self.support = md.support;
191 end
192
193 function phases = getNumberOfPhases(self)
194 % PHASES = GETNUMBEROFPHASES()
195
196 % Return number of phases in the distribution
197 PH = self.getProcess;
198 phases = length(PH{1});
199 end
200
201 function D = getProcess(self)
202 % D = GETREPRESENTATION()
203 D = self.process;
204 end
205
206 function setProcess(self, D)
207 self.process = D;
208 end
209
210 function L = evalLST(self, s)
211 % L = EVALLAPLACETRANSFORM(S)
212
213 % Evaluate the Laplace transform of the distribution function at t
214 % AT T
215
216 PH = self.getProcess;
217 pie = map_pie(PH);
218 A = PH{1};
219 e = ones(length(pie),1);
220 L = pie*inv(s*eye(size(A))-A)*(-A)*e;
221 end
222
223 function plot(self)
224 % PLOT()
225
226 PH = self.getProcess;
227 s = []; % source node
228 t = []; % dest node
229 w = []; % edge weight
230 c = []; % edge color
231 l = {}; % edge label
232 for i=1:self.getNumberOfPhases
233 for j=1:self.getNumberOfPhases
234 if i~=j
235 if PH{1}(i,j) > 0
236 s(end+1) = i;
237 t(end+1) = j;
238 w(end+1) = PH{1}(i,j);
239 c(end+1) = 0;
240 l{end+1} = num2str(w(end));
241 end
242 end
243 if PH{2}(i,j) > 0
244 s(end+1) = i;
245 t(end+1) = j;
246 w(end+1) = PH{2}(i,j);
247 c(end+1) = 1;
248 l{end+1} = num2str(w(end));
249 end
250 end
251 end
252 G = digraph(s,t,w);
253 p = plot(G,'EdgeColor','k','NodeColor','k','LineStyle','-','Marker','o','MarkerSize',4,'Layout','layered','EdgeLabel',l,'Direction','right');
254 % highlight observable transitions in red
255 highlight(p,s(c==1),t(c==1),'LineStyle','-','EdgeColor','r');
256 end
257 end
258
259end
260