1classdef MMDP < Markovian
2 % Markov-Modulated Deterministic Process
for fluid queue modeling
4 % Models fluid flow with deterministic rates modulated by a background
5 % Markov chain. Suitable
for arrival and service processes in
6 % Markovian fluid queues analyzed by the mfq method of SolverFLD.
8 % The (Q, R) parameterization follows BUTools conventions:
9 % - Q: Generator matrix of the modulating CTMC
10 % - R: Diagonal matrix of deterministic rates per state
12 % MMDP
is the deterministic analogue of MMPP:
13 % - MMPP: Poisson arrival rates modulated by a Markov chain
14 % - MMDP: Deterministic rates modulated by a Markov chain
16 % Copyright (c) 2012-2026, Imperial College London
17 % All rights reserved.
20 function self = MMDP(Q, R)
21 % MMDP Create a Markov-Modulated Deterministic Process
23 % @brief Creates an MMDP with specified generator Q and rate matrix R
24 % @param Q n×n generator matrix (row sums = 0)
25 % @param R n×n diagonal matrix of rates, OR n-vector
26 % @
return self MMDP instance with specified matrices
28 self@Markovian(
'MMDP', 2);
30 % Convert vector to diagonal matrix
if needed
35 setParam(self, 1,
'Q', Q);
36 setParam(self, 2,
'R', R);
38 % Store in process format: {Q, R}
39 self.process = {Q, R};
42 if ~mmdp_isfeasible(Q, R)
43 line_warning(mfilename,
'MMDP is infeasible.\n');
47 function Q_mat = Q(self)
48 % Q Return the generator matrix
50 % @
return Q_mat n×n generator matrix of the modulating CTMC
52 Q_mat = self.getParam(1).paramValue;
55 function R_mat = R(self)
56 % R Return the rate matrix (diagonal)
58 % @
return R_mat n×n diagonal matrix of deterministic rates
60 R_mat = self.getParam(2).paramValue;
63 function r_vec = r(self)
64 % r Return the rate vector (diagonal of R)
66 % @
return r_vec n-vector of deterministic rates per phase
68 r_vec = diag(self.R());
71 function n = getNumberOfPhases(self)
72 % GETNUMBEROFPHASES Return the number of phases
74 % @
return n Number of phases in the modulating CTMC
76 n = size(self.Q(), 1);
79 function rate = getMeanRate(self)
80 % GETMEANRATE Compute stationary mean rate
82 % Computes E[r] = π * r, where π
is the stationary distribution
83 % of the modulating CTMC with generator Q.
85 % @
return rate Stationary mean deterministic rate
89 pi = ctmc_solve(Q_mat);
93 function rate = getRate(self)
94 % GETRATE Alias
for getMeanRate
96 % @
return rate Stationary mean deterministic rate
98 rate = self.getMeanRate();
101 function mean = getMean(self)
102 % GETMEAN Return mean inter-arrival time (inverse of mean rate)
104 % @
return mean Mean inter-arrival time (1/rate), or Inf
if rate=0
106 rate = self.getMeanRate();
114 function scv = getSCV(self)
115 % GETSCV Return squared coefficient of variation of rates
117 % Computes Var[r]/E[r]^2 where expectation
is over the
118 % stationary distribution of the modulating CTMC.
120 % @
return scv Squared coefficient of variation
124 pi = ctmc_solve(Q_mat);
125 mean_rate = pi * r_vec;
126 var_rate = pi * (r_vec.^2) - mean_rate^2;
128 scv = var_rate / (mean_rate^2);
134 function
bool = isImmediate(self)
135 % ISIMMEDIATE Check
if the process has infinite rate
137 % @
return bool True
if mean rate
is effectively infinite
139 bool = self.getMean < GlobalConstants.FineTol;
144 function mmdp = fromMAP(map_obj)
145 % FROMMAP Convert a MAP to MMDP (deterministic representation)
147 % Converts a Markovian Arrival Process to a Markov-Modulated
148 % Deterministic Process by extracting the full generator and
149 %
using row sums of D1 as the deterministic rates.
151 % @param map_obj MAP
object to convert
152 % @
return mmdp MMDP representation of the MAP
157 R = diag(sum(D1, 2)); % Row sums of D1 as diagonal
161 function mmdp = fromMMPP2(lambda0, lambda1, sigma0, sigma1)
162 % FROMMMPP2 Create MMDP from MMPP2 parameters
164 % Creates a 2-state MMDP
using the same parameterization as MMPP2.
166 % @param lambda0 Rate in state 0
167 % @param lambda1 Rate in state 1
168 % @param sigma0 Transition rate from state 0 to state 1
169 % @param sigma1 Transition rate from state 1 to state 0
170 % @
return mmdp 2-state MMDP
172 Q = [-sigma0, sigma0; sigma1, -sigma1];
173 R = diag([lambda0; lambda1]);