LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
HyperExp.m
1classdef HyperExp < Markovian
2 % HyperExp Hyper-exponential distribution for high-variability processes
3 %
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.
8 %
9 % @brief Hyper-exponential mixture distribution with multiple phases
10 %
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)
17 %
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
24 %
25 % Example:
26 % @code
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]);
31 % @endcode
32 %
33 % Copyright (c) 2012-2026, Imperial College London
34 % All rights reserved.
35
36 methods
37 function self = HyperExp(varargin)
38 % HYPEREXP Create a hyper-exponential distribution instance
39 %
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
43 %
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
48 p = varargin{1};
49 lambda = 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
55 p1 = varargin{1};
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);
62 end
63 p = self.getParam(1).paramValue;
64 n = length(p);
65 if n == 1
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)]};
69 else
70 mu = self.getParam(2).paramValue;
71 D0 = -diag(mu);
72 D1 = -D0*p(:)*ones(1,n);
73 PH = {D0,D1};
74 end
75 self.process = PH;
76 self.nPhases = length(self.process{1});
77 end
78
79 function ex = getMean(self)
80 % EX = GETMEAN()
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;
87 else
88 Markovian.getMean(self);
89 end
90 end
91
92 function SCV = getSCV(self)
93 % SCV = GETSCV()
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;
100 else
101 Markovian.getSCV(self);
102 end
103 end
104
105 function Ft = evalCDF(self,t)
106 % FT = EVALCDF(SELF,T)
107 % Evaluate the cumulative distribution function at t
108 % AT T
109
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));
115 else
116 Markovian.evalCDF(self,t);
117 end
118 end
119 end
120
121 methods(Static)
122 function he = fit(MEAN, SCV, SKEW)
123 % HE = FIT(MEAN, SCV, SKEW)
124 % Fit distribution from first three standard moments
125 e1 = MEAN;
126 e2 = (1+SCV)*e1^2;
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)
131 p = map_pie(PH);
132 lambda = -diag(PH{1});
133 he = HyperExp(p,lambda);
134 return
135 end
136 end
137 he = HyperExp.fitMeanAndSCV(MEAN,SCV);
138 he.immediate = MEAN < GlobalConstants.CoarseTol;
139 end
140
141 function he = fitRate(RATE)
142 % HE = FITRATE(RATE)
143 % Fit distribution with given rate
144 he = HyperExp(p, RATE, RATE);
145 he.immediate = 1/RATE < GlobalConstants.CoarseTol;
146 end
147
148 function he = fitMean(MEAN)
149 % HE = FITMEAN(MEAN)
150 % Fit distribution with given mean
151 he = HyperExp(p, 1/MEAN, 1/MEAN);
152 he.immediate = MEAN < GlobalConstants.CoarseTol;
153 end
154
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;
161 end
162
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.,
167 % p/mu1 = (1-p)/mu2
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;
173 end
174 mu2=(1-p)/p*mu1;
175 p = real(p);
176 mu1 = real(mu1);
177 mu2 = real(mu2);
178 he = HyperExp(p, mu1, mu2);
179 he.immediate = MEAN < GlobalConstants.CoarseTol;
180 end
181 end
182
183end
184