LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
distributions.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2026, QORE Lab, Imperial College London
3 * All rights reserved.
4 */
5#ifndef LINE_LANG_DISTRIBUTIONS_H
6#define LINE_LANG_DISTRIBUTIONS_H
7
8/**
9 * @file
10 * @ingroup line_lang
11 * @ingroup line_public
12 * The distributions a user names, spelled as their Python twins.
13 *
14 * queue1.set_service(closed, Exp(1.0));
15 * delay.set_service(open, Erlang(3.0, 2));
16 * delay.set_service(open, HyperExp(0.5, 3.0, 10.0));
17 *
18 * against Python's `Exp(1.0)`, `Erlang(3.0, 2)`, `HyperExp(0.5, 3.0, 10.0)`.
19 *
20 * EACH IS A THIN NAME OVER THE FACTORY THAT ALREADY EXISTS. Every constructor
21 * assigns the `Distrib<double>` that `lang_types.h` builds, so the numeric
22 * behaviour is the factory's and nothing new is computed here; deriving from
23 * `Distrib<double>` is what lets one slice cleanly into `set_service`, which
24 * takes the base by const reference.
25 *
26 * The fitters keep Python's static-method spelling
27 * (`HyperExp::fit_mean_and_scv`), forwarding to `line/lang/dist_fitters.h`.
28 *
29 * `double`-only, as Python is. Reach for `lang::Distrib<T>`'s own factories
30 * directly for the multiprecision paths.
31 */
32
33#include <cstddef>
34#include <fstream>
35#include <string>
36#include <vector>
37
40#include "line/util/error.h"
41
42namespace line {
43
45
46/** Every named law below is a `Distrib<double>` under another name. */
47#define LINE_DIST_CTOR(Cls) \
48 struct Cls : lang::Distrib<double>
49
50/** `Exp(rate)`: the exponential law of the given RATE, as Python's `Exp`. */
52 explicit Exp(double rate) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::exp_rate(rate); }
53 /** `Exp.fitMean(mean)`. */
54 static Exp fit_mean(double m) { return Exp(1.0 / m); }
55 /** `Exp.fitRate(rate)`. */
56 static Exp fit_rate(double r) { return Exp(r); }
57};
58
59/** `Erlang(phase_rate, nphases)`. */
61 Erlang(double phase_rate, std::size_t nphases) {
62 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::erlang(phase_rate, nphases);
63 }
64 /** `Erlang.fitMeanAndSCV(mean, scv)`. */
65 static lang::Distrib<double> fit_mean_and_scv(double m, double scv) {
67 }
68 /** `Erlang.fitMeanAndOrder(mean, k)`. */
69 static lang::Distrib<double> fit_mean_and_order(double m, std::size_t k) {
71 }
72};
73
74/** `HyperExp(p, lambda1, lambda2)`. */
75LINE_DIST_CTOR(HyperExp) {
76 HyperExp(double p, double lambda1, double lambda2) {
77 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::hyperexp(p, lambda1, lambda2);
78 }
79 HyperExp(const std::vector<double>& p, const std::vector<double>& lambda) {
80 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::hyperexp_n(p, lambda);
81 }
82 /** `HyperExp.fitMeanAndSCV(mean, scv)`. */
83 static lang::Distrib<double> fit_mean_and_scv(double m, double scv) {
85 }
86 /** `HyperExp.fitMeanAndSCVBalanced(mean, scv)`. */
87 static lang::Distrib<double> fit_mean_and_scv_balanced(double m, double scv) {
89 }
90};
91
92/** `Coxian(mu, phi)`. */
94 Coxian(const std::vector<double>& mu, const std::vector<double>& phi) {
95 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::coxian(mu, phi);
96 }
97 /** `Coxian.fitMeanAndSCV(mean, scv)`. */
98 static lang::Distrib<double> fit_mean_and_scv(double m, double scv) {
100 }
101 /** `Coxian.fitCentral(mean, scv, skew)`. */
102 static lang::Distrib<double> fit_central(double m, double scv, double skew) {
103 return lang::coxian_fit_central<double>(m, scv, skew);
104 }
105};
106
107/** `Cox2(mu1, mu2, phi1)`. */
109 Cox2(double mu1, double mu2, double phi1) {
110 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::cox2(mu1, mu2, phi1);
111 }
112 /** `Cox2.fitCentral(mean, scv, skew)`. */
113 static lang::Distrib<double> fit_central(double m, double scv, double skew) {
114 return lang::cox2_fit_central<double>(m, scv, skew);
115 }
116};
117
118/** `PH(alpha, A)`: a general phase-type law. */
120 PH(const std::vector<double>& alpha, const Matrix<double>& A) {
121 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::phase_type(alpha, A, false);
122 }
123};
124
125/** `APH(alpha, A)`: the acyclic phase-type law. */
127 APH(const std::vector<double>& alpha, const Matrix<double>& A) {
128 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::phase_type(alpha, A, true);
129 }
130 /** `APH.fitMeanAndSCV(mean, scv)`. */
131 static lang::Distrib<double> fit_mean_and_scv(double m, double scv) {
132 return lang::aph_fit_mean_scv<double>(m, scv);
133 }
134 /** `APH.fitCentral(mean, scv, skew)`. */
135 static lang::Distrib<double> fit_central(double m, double scv, double skew) {
136 return lang::aph_fit_central<double>(m, scv, skew);
137 }
138};
139
140/** `MAP(D0, D1)`. */
142 MAP(const Matrix<double>& D0, const Matrix<double>& D1) {
144 }
145};
146
147/** `Det(t)`: the deterministic law. */
149 explicit Det(double t) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::det(t); }
150};
151
152/** `Immediate()`: a zero-time transition. */
153LINE_DIST_CTOR(Immediate) {
154 Immediate() { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::immediate(); }
155};
156
157/** `Disabled()`: the class is not served here. */
158LINE_DIST_CTOR(Disabled) {
159 Disabled() { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::disabled_dist(); }
160};
161
162/** `Uniform(a, b)`. */
164 Uniform(double a, double b) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::uniform(a, b); }
165};
166
167/** `Pareto(shape, scale)`. */
169 Pareto(double shape, double scale) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::pareto(shape, scale); }
170 /** `Pareto.fitMeanAndSCV(mean, scv)`. */
171 static lang::Distrib<double> fit_mean_and_scv(double m, double scv) {
173 }
174};
175
176/** `Gamma(shape, scale)`. */
178 Gamma(double shape, double scale) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::gamma_dist(shape, scale); }
179 /** `Gamma.fitMeanAndSCV(mean, scv)`. */
180 static lang::Distrib<double> fit_mean_and_scv(double m, double scv) {
182 }
183};
184
185/** `Weibull(scale, shape)`. */
187 Weibull(double scale, double shape) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::weibull(scale, shape); }
188};
189
190/** `Lognormal(logmean, logsigma)`. */
191LINE_DIST_CTOR(Lognormal) {
192 Lognormal(double logmean, double logsigma) {
193 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::lognormal(logmean, logsigma);
194 }
195};
196
197/** `Normal(mu, sigma)`. */
199 Normal(double mu, double sigma) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::normal(mu, sigma); }
200};
201
202/** `Geometric(p)`. */
203LINE_DIST_CTOR(Geometric) {
204 explicit Geometric(double p) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::geometric(p); }
205};
206
207/** `Bernoulli(p)`. */
208LINE_DIST_CTOR(Bernoulli) {
209 explicit Bernoulli(double p) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::bernoulli(p); }
210};
211
212/** `Binomial(n, p)`. */
213LINE_DIST_CTOR(Binomial) {
214 Binomial(double n, double p) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::binomial(n, p); }
215};
216
217/** `Poisson(lambda)`. */
219 explicit Poisson(double lambda) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::poisson(lambda); }
220};
221
222/** `DiscreteUniform(a, b)`. */
223LINE_DIST_CTOR(DiscreteUniform) {
224 DiscreteUniform(double a, double b) {
226 }
227};
228
229/** `Zipf(s, n)`. */
231 Zipf(double s, std::size_t n) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::zipf(s, n); }
232};
233
234/** `DiscreteSampler(p, x)`. */
235LINE_DIST_CTOR(DiscreteSampler) {
236 explicit DiscreteSampler(const std::vector<double>& p) {
237 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::discrete_sampler(p, std::vector<double>());
238 }
239 DiscreteSampler(const std::vector<double>& p, const std::vector<double>& x) {
241 }
242};
243
244/** `Replayer(samples)` / `Replayer(path)`: the trace-driven law. */
245LINE_DIST_CTOR(Replayer) {
246 explicit Replayer(const std::vector<double>& samples) {
247 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::replayer(samples);
248 }
249 explicit Replayer(const std::string& path) {
250 std::ifstream in(path.c_str());
251 if (!in) throw InputError("Replayer: cannot open the trace file '" + path + "'");
252 std::vector<double> samples;
253 double value = 0.0;
254 while (in >> value) samples.push_back(value);
255 if (!in.eof())
256 throw InputError("Replayer: the trace file '" + path + "' contains a non-number");
257 if (samples.empty())
258 throw InputError("Replayer: the trace file '" + path + "' has no samples");
259 static_cast<lang::Distrib<double>&>(*this) =
261 }
262 Replayer(const std::vector<double>& samples, const std::string& path) {
263 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::replayer_from(samples, path);
264 }
265};
266
267#undef LINE_DIST_CTOR
268
269} // namespace line
270
271#endif // LINE_LANG_DISTRIBUTIONS_H
InputError(const std::string &what)
Definition error.h:39
The moment fitters the reference distributions carry as STATIC FACTORIES: Erlang.fitMeanAndOrder,...
The exception types the port throws.
Enumerations and the minimal distribution descriptor shared by the model layer of the C++ port.
Distrib< T > hyperexp_fit_mean_scv_balanced(const T &mean, const T &scv)
HyperExp.fitMeanAndSCVBalanced(MEAN, SCV): the balanced-means branch, p / mu1 = (1 - p) / mu2.
Distrib< T > aph_fit_central(const T &mean, const T &var, const T &skew)
APH.fitCentral(MEAN, VAR, SKEW): the three central moments converted to raw ones and matched by a can...
Distrib< T > erlang_fit_mean_order(const T &mean, std::size_t k)
Erlang.fitMeanAndOrder(MEAN, k): k phases, each of rate k / MEAN.
Distrib< T > coxian_fit_central(const T &mean, const T &var, const T &skew)
Coxian.fitCentral, which the reference forwards to Cox2.fitCentral.
Distrib< T > aph_fit_mean_scv(const T &mean, const T &scv)
APH.fitMeanAndSCV(MEAN, SCV), through mam::aph_fit_mean_scv.
Distrib< T > gamma_fit_mean_scv(const T &mean, const T &scv)
Gamma.fitMeanAndSCV(MEAN, SCV): shape 1/SCV, scale MEAN * SCV.
Distrib< T > pareto_fit_mean_scv(const T &mean, const T &scv)
Pareto.fitMeanAndSCV(MEAN, SCV): alpha = 1 + sqrt(1 + 1/SCV) and k = MEAN (alpha - 1) / alpha.
Distrib< T > coxian_fit_mean_scv(const T &mean, const T &scv)
Coxian.fitMeanAndSCV(MEAN, SCV), branch for branch.
Distrib< T > hyperexp_fit_mean_scv(const T &mean, const T &scv)
HyperExp.fitMeanAndSCV(MEAN, SCV), which is map_hyperexp at p = 0.99 read back as (p,...
Distrib< T > cox2_fit_central(const T &mean, const T &var, const T &skew)
Cox2.fitCentral(MEAN, VAR, SKEW): the two-phase Coxian matching three central moments exactly when th...
Conservation laws of a layered queueing network, enumerated from its structure.
Definition aoi_dist2ph.h:52
lang::Distrib< double > Distribution
LINE_DIST_CTOR(Exp)
Exp(rate): the exponential law of the given RATE, as Python's Exp.
static Distrib replayer(const std::vector< T > &samples)
Replayer / Trace: the samples, with their empirical first two moments.
static Distrib normal(const T &mu, const T &sigma)
Normal(mu, sigma): the Gaussian, for use as a continuous Prior's parameter density.
static Distrib exp_rate(const T &r)
Definition lang_types.h:945
static Distrib phase_type(const std::vector< T > &alpha, const Matrix< T > &A, bool acyclic)
PH / APH given by (alpha, A): D0 = A and D1 = (-A e) alpha.
static Distrib weibull(const T &scale, const T &shape)
static Distrib replayer_from(const std::vector< T > &samples, const std::string &path)
Replayer / Trace read FROM A FILE, which keeps the path beside the samples.
static Distrib disabled_dist()
Definition lang_types.h:988
static Distrib erlang_fit(const T &m, const T &c2)
Erlang fitted to a mean and an SCV, as MATLAB's Erlang.fitMeanAndSCV.
static Distrib pareto(const T &shape, const T &scale)
Pareto(shape, scale), with the MATLAB parameter order (alpha, k).
static Distrib gamma_dist(const T &shape, const T &scale)
Gamma(shape, scale), Weibull(scale, shape) and Lognormal(mu, sigma).
static Distrib cox2(const T &mu1, const T &mu2, const T &phi1)
Cox2(mu1, mu2, phi1), MATLAB's two-phase Coxian constructor.
static Distrib map_dist(const Matrix< T > &D0, const Matrix< T > &D1, ProcessType tag)
A MAP given by its two matrices; the moments are those of its stationary phase.
static Distrib poisson(const T &lambda)
Poisson(lambda), whose SCV is 1/lambda – the count's variance is lambda and its mean is lambda,...
static Distrib bernoulli(const T &p)
Bernoulli(p): one trial, mean p and variance p(1-p).
static Distrib hyperexp_n(const std::vector< T > &p, const std::vector< T > &lambda)
HyperExp(p, lambda1, lambda2): phase i chosen with probability p_i.
static Distrib discrete_uniform(const T &a, const T &b)
DiscreteUniform(a, b) over the integers a..b inclusive.
static Distrib geometric(const T &p)
Geometric(p) on the MATLAB convention: the NUMBER OF TRIALS to the first success, support {1,...
static Distrib det(const T &m)
Definition lang_types.h:989
static Distrib uniform(const T &a, const T &b)
Uniform(a, b).
static Distrib lognormal(const T &logmean, const T &logsigma)
static Distrib hyperexp(const T &p, const T &lambda1, const T &lambda2)
static Distrib immediate()
The Immediate singleton.
Definition lang_types.h:977
static Distrib erlang(const T &phase_rate, std::size_t r)
Erlang(alpha, r): r phases of rate alpha, as MATLAB's Erlang(phaseRate, nphases).
static Distrib coxian(const std::vector< T > &mu, const std::vector< T > &phi)
Coxian(mu, phi): phase i completes with probability phi(i) and otherwise moves to phase i+1.
static Distrib discrete_sampler(const std::vector< T > &p, const std::vector< T > &x)
DiscreteSampler(p, x): the pmf p over the points x.
static Distrib binomial(const T &n, const T &p)
Binomial(n, p).
static Distrib zipf(const T &s, std::size_t n)
Zipf(s, n) over the ranks 1..n, with the generalized harmonic moments H(s-1,n)/H(s,...