1classdef MarkedMMPP < MarkovModulated
2 % Marked Markov-Modulated Poisson Process
3 % Also referred to as a M3PP model
5 % Copyright (c) 2012-2026, Imperial College London
10 function self = MarkedMMPP(D,K)
11 % SELF = MarkedMMPP(D,K)
13 % LINE uses the M3A representation format
14 % D={D0, D1, D11, D12, D13, ..., D1K}
15 % K
is the number of marking types
17 self@MarkovModulated(
'MarkedMMPP',K+2);
20 setParam(self, 1,
'D0', D{1});
21 D1 = cellsum({D{2:end}});
22 if any(D1-diag(diag(D1)))
23 line_error(mfilename,
'Non-diagonal elements in the D1k matrices, not a Marked MMPP.');
25 setParam(self, 2,
'D1', D1);
27 setParam(self, 2+k, sprintf(
'D1%d',k), D{1+k});
29 elseif K == length(D)-2
30 setParam(self, 1,
'D0', D{1});
32 if any(D1-diag(diag(D1)))
33 line_error(mfilename,
'Non-diagonal elements in the D1k matrices, not a Marked MMPP.');
35 setParam(self, 2,
'D1', D1);
37 setParam(self, 2+k, sprintf(
'D1%d',k), D{2+k});
40 line_error(mfilename,
'Inconsistency between the number of classes and the number of supplied D matrices.')
44 function Di = D(self, i, j, wantSparse)
57 line_error(mfilename,'Invalid D matrix indexes');
61 % Return representation matrix, e.g., D0=MAP.D(0)
66 Di=self.getProcess{1+i+j};
75 Di=full(self.getProcess{1+i+j});
80 function meant = evalMeanT(self, t)
81 % MEANT = EVALMEANT(SELF,T)
83 meant = self.toMAP.evalMeanT(t);
86 function vart = evalVarT(self, t)
87 % VART = EVALVART(SELF,T)
89 % Evaluate the variance-time curve at timescale t
90 vart = self.toMAP.evalVarT(t);
93 function acf = evalACFT(self, lags, timescale)
94 % ACF = EVALACFT(self, lags)
96 % Evaluate the autocorrelation in counts at timescale t
98 acf = self.toMAP.evalACFT(lags, timescale);
101 % inter-arrival time properties
102 function mean = getMean(self)
105 mean = self.toMAP.getMean;
108 function scv = getSCV(self)
111 scv = self.toMAP.scv;
114 % inter-arrival time properties for each marking type
115 function mean = getMarkedMeans(self)
116 % MEAN = GETMARKEDMEAN()
118 mean = 1 ./ mmap_lambda(self.D);
121 function acf = getACF(self, lags)
122 % ACF = GETACF(self, lags)
124 acf = self.toMAP.getACF(lags);
127 function
map = toMAP(self)
128 map = MAP(self.D(0), self.D(1));
131 function maps = toMAPs(self, types)
133 types = 1:self.getNumberOfTypes;
138 Df = Df + (self.D(1) - self.D(1,k));
139 maps{end+1} = MAP(Df, self.D(1,k));
143 function [gamma2, gamma] = getACFDecay(self)
144 % [gamma2, gamma] = GETACFDECAY(self)
146 % gamma2: asymptotic decay rate of acf
147 % gamma: interpolated decay rate of acf
149 [gamma2, gamma] = self.toMAP.getACFDecay();
152 function
id = getIDC(self, t) % index of dispersion
for counts
153 % ID = GETIDC() % INDEX OF DISPERSION
155 id = self.toMAP.getIDC;
157 id = self.toMAP.getIDC(t);
161 function
id = getMarkedIDC(self, t) % asymptotic index of dispersion
for counts
for each type
162 % ID = GETMARKEDIDC() % ASYMPTOTIC INDEX OF DISPERSION
164 id = mmpp_count_idc(self.getProcess, GlobalConstants.Immediate);
166 id = mmpp_count_idc(self.getProcess, t);
170 function lam = getRate(self)
173 lam = self.toMAP.getRate;
176 function MarkedMMPP = getProcess(self)
177 % MarkedMMPP = GETPROCESS()
178 K = self.getNumParams;
179 MarkedMMPP = cell(1,K-1);
181 MarkedMMPP{k} = self.getParam(k).paramValue;
185 function n = getNumberOfPhases(self)
186 % N = GETNUMBEROFMAPASES()
187 D0 = self.getParam(1).paramValue;
191 function mu = getMu(self)
193 % Aggregate departure rate from each state
194 mu = sum(self.D(1),2); % sum D1 rows / diag -D0
197 function phi = getPhi(self)
199 % Return the exit vector of the underlying MAP
200 phi = sum(self.D(1),2) ./ diag(-self.D(0)); % sum D1 rows / diag -D0
203 function K = getNumberOfTypes(self)
204 % K = GETNUMBEROFTYPES()
205 % Number of marking types
207 K = length(self.D)-2;
210 function MMAPr = toTimeReversed(self)
211 MMAPr = MarkedMMPP(mmap_timereverse(self.D), self.getNumberOfTypes);
214 function [X,C] = sample(self, n)
216 if nargin<2 %~exist('n','var'),
219 MarkedMMPP = self.getProcess;
220 if mmpp_isfeasible(MarkedMMPP)
221 [X,C] = mmpp_sample(MarkedMMPP,n);
223 line_error(mfilename,'This process
is infeasible (negative rates).');
231 function m3pp = fit(trace, markings, order)
232 % M3PP = FIT(TRACE, ORDER)
233 T = m3afit_init(trace,markings);
234 m3pp = m3afit_auto(T,'NumStates',order,'Method',1);
237 function m3pp = rand(order, nclasses)
238 % M3PP = RAND(ORDER,NCLASSES)
240 % Generate random MarkedMMPP using uniform random numbers
244 m3pp = MarkedMMPP(m3pp_rand(order,nclasses),nclasses);