1classdef HyperExp < Markovian
2 % HyperExp Hyper-exponential distribution
for high-variability processes
4 % HyperExp represents a mixture of exponential distributions, where jobs
5 % select one of multiple exponential phases with given probabilities.
6 % This distribution has high variability (SCV > 1) and
is commonly used
7 % for modeling service times with large variation or mixed workload types.
9 % @brief Hyper-exponential mixture distribution with multiple phases
11 % Key characteristics:
12 % - Mixture of multiple exponential distributions
13 % - Probabilistic selection of exponential phases
14 % - High variability (SCV ≥ 1)
15 % - Supports both 2-phase and n-phase variants
16 % - Parallel phase structure (choose one of n phases)
18 % The hyper-exponential distribution
is used for:
19 % - Service times with high variability
20 % - Mixed workload modeling (fast/slow jobs)
21 % - Modeling systems with multiple service
classes
22 % - Approximating heavy-tailed distributions
23 % - Building phase-type distributions with SCV > 1
27 % % Two-phase: 70% fast (rate=5), 30% slow (rate=0.5)
28 % mixed_service = HyperExp(0.7, 5.0, 0.5);
29 % % n-phase: equal probability, different rates
30 % multi_service = HyperExp([0.3, 0.4, 0.3], [3.0, 1.0, 0.2]);
33 % Copyright (c) 2012-2026, Imperial College London
34 % All rights reserved.
37 function self = HyperExp(varargin)
38 % HYPEREXP Create a hyper-exponential distribution instance
40 % @brief Creates a hyper-exponential distribution with specified phases
41 % @param varargin Variable arguments: (p, lambda1, lambda2) or (prob_vec, rate_vec)
42 % @return self HyperExp distribution instance
44 % Usage: HyperExp(p1, lambda1, lambda2) for 2-phase
45 % HyperExp(prob_vector, rate_vector) for n-phase
46 self@Markovian('HyperExp',nargin);
47 if length(varargin)==2
50 setParam(self, 1,
'p', p);
51 setParam(self, 2,
'lambda1', lambda);
52 setParam(self, 3,
'lambda2', lambda);
53 self.obj = jline.lang.processes.HyperExp(p, lambda, lambda);
54 elseif length(varargin)==3
56 lambda1 = varargin{2};
57 lambda2 = varargin{3};
58 setParam(self, 1,
'p', p1);
59 setParam(self, 2,
'lambda1', lambda1);
60 setParam(self, 3,
'lambda2', lambda2);
61 self.obj = jline.lang.processes.HyperExp(p1, lambda1, lambda2);
63 p = self.getParam(1).paramValue;
66 mu1 = self.getParam(2).paramValue;
67 mu2 = self.getParam(3).paramValue;
68 PH={[-mu1,0;0,-mu2],[mu1*p,mu1*(1-p);mu2*p,mu2*(1-p)]};
70 mu = self.getParam(2).paramValue;
72 D1 = -D0*p(:)*ones(1,n);
76 self.nPhases = length(self.process{1});
79 function ex = getMean(self)
81 % Get distribution mean
82 if self.getNumberOfPhases == 2
83 p = self.getParam(1).paramValue;
84 mu1 = self.getParam(2).paramValue;
85 mu2 = self.getParam(3).paramValue;
86 ex = p/mu1 + (1-p)/mu2;
88 Markovian.getMean(self);
92 function SCV = getSCV(self)
94 % Get the squared coefficient of variation of the distribution (SCV = variance / mean^2)
95 if self.getNumberOfPhases == 2
96 p = self.getParam(1).paramValue;
97 mu1 = self.getParam(2).paramValue;
98 mu2 = self.getParam(3).paramValue;
99 SCV = (2*(p/mu1^2 + (1-p)/mu2^2) - (p/mu1 + (1-p)/mu2)^2)/(p/mu1 + (1-p)/mu2)^2;
101 Markovian.getSCV(self);
105 function Ft = evalCDF(self,t)
106 % FT = EVALCDF(SELF,T)
107 % Evaluate the cumulative distribution function at t
110 if self.getNumberOfPhases == 2
111 p = self.getParam(1).paramValue;
112 mu1 = self.getParam(2).paramValue;
113 mu2 = self.getParam(3).paramValue;
114 Ft = p*(1-exp(-mu1*t))+(1-p)*(1-exp(-mu2*t));
116 Markovian.evalCDF(self,t);
122 function he = fit(MEAN, SCV, SKEW)
123 % HE = FIT(MEAN, SCV, SKEW)
124 % Fit distribution from first three standard moments
127 e3 = -(2*e1^3-3*e1*e2-SKEW*(e2-e1^2)^(3/2));
128 for n=[2] % larger ph
requires more moments
129 PH = kpcfit_ph_prony([e1,e2,e3],n);
130 if map_isfeasible(PH)
132 lambda = -diag(PH{1});
133 he = HyperExp(p,lambda);
137 he = HyperExp.fitMeanAndSCV(MEAN,SCV);
138 he.immediate = MEAN < GlobalConstants.CoarseTol;
141 function he = fitRate(RATE)
143 % Fit distribution with given rate
144 he = HyperExp(p, RATE, RATE);
145 he.immediate = 1/RATE < GlobalConstants.CoarseTol;
148 function he = fitMean(MEAN)
150 % Fit distribution with given mean
151 he = HyperExp(p, 1/MEAN, 1/MEAN);
152 he.immediate = MEAN < GlobalConstants.CoarseTol;
155 function he = fitMeanAndSCV(MEAN, SCV)
156 % HE = FITMEANANDSCV(MEAN, SCV)
157 % Fit distribution with given mean and squared coefficient of variation (SCV=variance/mean^2)
158 [~,mu1,mu2,p] = map_hyperexp(MEAN,SCV);
159 he = HyperExp(p, mu1, mu2);
160 he.immediate = MEAN < GlobalConstants.CoarseTol;
163 function he = fitMeanAndSCVBalanced(MEAN, SCV)
164 % HE = FITMEANANDSCV(MEAN, SCV)
165 % Fit distribution with given mean and squared coefficient of
166 % variation (SCV=variance/mean^2) and balanced means, i.e.,
168 mu1 = -(2*(((SCV - 1)/(SCV + 1))^(1/2)/2 - 1/2))/MEAN;
169 p= 1/2 - ((SCV - 1)/(SCV + 1))^(1/2)/2;
170 if mu1<0 || p<0 || p>1
171 p = ((SCV - 1)/(SCV + 1))^(1/2)/2 + 1/2;
172 mu1 = (2*(((SCV - 1)/(SCV + 1))^(1/2)/2 + 1/2))/MEAN;
178 he = HyperExp(p, mu1, mu2);
179 he.immediate = MEAN < GlobalConstants.CoarseTol;