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 = GETPROCESS()
203 D = self.process;
204 end
205
206 function D = getRepresentation(self)
207 % D = GETREPRESENTATION()
208 % Return the (D0,D1,...) matrix representation of the process.
209 % Alias of getProcess, mirroring the Java/Kotlin/Python API.
210 D = self.getProcess;
211 end
212
213 function setProcess(self, D)
214 self.process = D;
215 end
216
217 function L = evalLST(self, s)
218 % L = EVALLAPLACETRANSFORM(S)
219
220 % Evaluate the Laplace transform of the distribution function at t
221 % AT T
222
223 PH = self.getProcess;
224 pie = map_pie(PH);
225 A = PH{1};
226 e = ones(length(pie),1);
227 L = pie*inv(s*eye(size(A))-A)*(-A)*e;
228 end
229
230 function plot(self)
231 % PLOT()
232
233 PH = self.getProcess;
234 s = []; % source node
235 t = []; % dest node
236 w = []; % edge weight
237 c = []; % edge color
238 l = {}; % edge label
239 for i=1:self.getNumberOfPhases
240 for j=1:self.getNumberOfPhases
241 if i~=j
242 if PH{1}(i,j) > 0
243 s(end+1) = i;
244 t(end+1) = j;
245 w(end+1) = PH{1}(i,j);
246 c(end+1) = 0;
247 l{end+1} = num2str(w(end));
248 end
249 end
250 if PH{2}(i,j) > 0
251 s(end+1) = i;
252 t(end+1) = j;
253 w(end+1) = PH{2}(i,j);
254 c(end+1) = 1;
255 l{end+1} = num2str(w(end));
256 end
257 end
258 end
259 G = digraph(s,t,w);
260 p = plot(G,'EdgeColor','k','NodeColor','k','LineStyle','-','Marker','o','MarkerSize',4,'Layout','layered','EdgeLabel',l,'Direction','right');
261 % highlight observable transitions in red
262 highlight(p,s(c==1),t(c==1),'LineStyle','-','EdgeColor','r');
263 end
264 end
265
266end
267