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 <string>
35#include <vector>
36
39
40namespace line {
41
43
44/** Every named law below is a `Distrib<double>` under another name. */
45#define LINE_DIST_CTOR(Cls) \
46 struct Cls : lang::Distrib<double>
47
48/** `Exp(rate)`: the exponential law of the given RATE, as Python's `Exp`. */
50 explicit Exp(double rate) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::exp_rate(rate); }
51 /** `Exp.fitMean(mean)`. */
52 static Exp fit_mean(double m) { return Exp(1.0 / m); }
53 /** `Exp.fitRate(rate)`. */
54 static Exp fit_rate(double r) { return Exp(r); }
55};
56
57/** `Erlang(phase_rate, nphases)`. */
59 Erlang(double phase_rate, std::size_t nphases) {
60 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::erlang(phase_rate, nphases);
61 }
62 /** `Erlang.fitMeanAndSCV(mean, scv)`. */
63 static lang::Distrib<double> fit_mean_and_scv(double m, double scv) {
65 }
66 /** `Erlang.fitMeanAndOrder(mean, k)`. */
67 static lang::Distrib<double> fit_mean_and_order(double m, std::size_t k) {
69 }
70};
71
72/** `HyperExp(p, lambda1, lambda2)`. */
73LINE_DIST_CTOR(HyperExp) {
74 HyperExp(double p, double lambda1, double lambda2) {
75 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::hyperexp(p, lambda1, lambda2);
76 }
77 HyperExp(const std::vector<double>& p, const std::vector<double>& lambda) {
78 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::hyperexp_n(p, lambda);
79 }
80 /** `HyperExp.fitMeanAndSCV(mean, scv)`. */
81 static lang::Distrib<double> fit_mean_and_scv(double m, double scv) {
83 }
84 /** `HyperExp.fitMeanAndSCVBalanced(mean, scv)`. */
85 static lang::Distrib<double> fit_mean_and_scv_balanced(double m, double scv) {
87 }
88};
89
90/** `Coxian(mu, phi)`. */
92 Coxian(const std::vector<double>& mu, const std::vector<double>& phi) {
93 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::coxian(mu, phi);
94 }
95 /** `Coxian.fitMeanAndSCV(mean, scv)`. */
96 static lang::Distrib<double> fit_mean_and_scv(double m, double scv) {
98 }
99 /** `Coxian.fitCentral(mean, scv, skew)`. */
100 static lang::Distrib<double> fit_central(double m, double scv, double skew) {
101 return lang::coxian_fit_central<double>(m, scv, skew);
102 }
103};
104
105/** `Cox2(mu1, mu2, phi1)`. */
107 Cox2(double mu1, double mu2, double phi1) {
108 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::cox2(mu1, mu2, phi1);
109 }
110 /** `Cox2.fitCentral(mean, scv, skew)`. */
111 static lang::Distrib<double> fit_central(double m, double scv, double skew) {
112 return lang::cox2_fit_central<double>(m, scv, skew);
113 }
114};
115
116/** `PH(alpha, A)`: a general phase-type law. */
118 PH(const std::vector<double>& alpha, const Matrix<double>& A) {
119 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::phase_type(alpha, A, false);
120 }
121};
122
123/** `APH(alpha, A)`: the acyclic phase-type law. */
125 APH(const std::vector<double>& alpha, const Matrix<double>& A) {
126 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::phase_type(alpha, A, true);
127 }
128 /** `APH.fitMeanAndSCV(mean, scv)`. */
129 static lang::Distrib<double> fit_mean_and_scv(double m, double scv) {
130 return lang::aph_fit_mean_scv<double>(m, scv);
131 }
132 /** `APH.fitCentral(mean, scv, skew)`. */
133 static lang::Distrib<double> fit_central(double m, double scv, double skew) {
134 return lang::aph_fit_central<double>(m, scv, skew);
135 }
136};
137
138/** `MAP(D0, D1)`. */
140 MAP(const Matrix<double>& D0, const Matrix<double>& D1) {
142 }
143};
144
145/** `Det(t)`: the deterministic law. */
147 explicit Det(double t) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::det(t); }
148};
149
150/** `Immediate()`: a zero-time transition. */
151LINE_DIST_CTOR(Immediate) {
152 Immediate() { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::immediate(); }
153};
154
155/** `Disabled()`: the class is not served here. */
156LINE_DIST_CTOR(Disabled) {
157 Disabled() { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::disabled_dist(); }
158};
159
160/** `Uniform(a, b)`. */
162 Uniform(double a, double b) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::uniform(a, b); }
163};
164
165/** `Pareto(shape, scale)`. */
167 Pareto(double shape, double scale) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::pareto(shape, scale); }
168 /** `Pareto.fitMeanAndSCV(mean, scv)`. */
169 static lang::Distrib<double> fit_mean_and_scv(double m, double scv) {
171 }
172};
173
174/** `Gamma(shape, scale)`. */
176 Gamma(double shape, double scale) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::gamma_dist(shape, scale); }
177 /** `Gamma.fitMeanAndSCV(mean, scv)`. */
178 static lang::Distrib<double> fit_mean_and_scv(double m, double scv) {
180 }
181};
182
183/** `Weibull(scale, shape)`. */
185 Weibull(double scale, double shape) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::weibull(scale, shape); }
186};
187
188/** `Lognormal(logmean, logsigma)`. */
189LINE_DIST_CTOR(Lognormal) {
190 Lognormal(double logmean, double logsigma) {
191 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::lognormal(logmean, logsigma);
192 }
193};
194
195/** `Normal(mu, sigma)`. */
197 Normal(double mu, double sigma) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::normal(mu, sigma); }
198};
199
200/** `Geometric(p)`. */
201LINE_DIST_CTOR(Geometric) {
202 explicit Geometric(double p) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::geometric(p); }
203};
204
205/** `Bernoulli(p)`. */
206LINE_DIST_CTOR(Bernoulli) {
207 explicit Bernoulli(double p) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::bernoulli(p); }
208};
209
210/** `Binomial(n, p)`. */
211LINE_DIST_CTOR(Binomial) {
212 Binomial(double n, double p) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::binomial(n, p); }
213};
214
215/** `Poisson(lambda)`. */
217 explicit Poisson(double lambda) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::poisson(lambda); }
218};
219
220/** `DiscreteUniform(a, b)`. */
221LINE_DIST_CTOR(DiscreteUniform) {
222 DiscreteUniform(double a, double b) {
224 }
225};
226
227/** `Zipf(s, n)`. */
229 Zipf(double s, std::size_t n) { static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::zipf(s, n); }
230};
231
232/** `DiscreteSampler(p, x)`. */
233LINE_DIST_CTOR(DiscreteSampler) {
234 explicit DiscreteSampler(const std::vector<double>& p) {
235 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::discrete_sampler(p, std::vector<double>());
236 }
237 DiscreteSampler(const std::vector<double>& p, const std::vector<double>& x) {
239 }
240};
241
242/** `Replayer(samples)` / `Replayer(samples, path)`: the trace-driven law. */
243LINE_DIST_CTOR(Replayer) {
244 explicit Replayer(const std::vector<double>& samples) {
245 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::replayer(samples);
246 }
247 Replayer(const std::vector<double>& samples, const std::string& path) {
248 static_cast<lang::Distrib<double>&>(*this) = lang::Distrib<double>::replayer_from(samples, path);
249 }
250};
251
252#undef LINE_DIST_CTOR
253
254} // namespace line
255
256#endif // LINE_LANG_DISTRIBUTIONS_H
The moment fitters the reference distributions carry as STATIC FACTORIES: Erlang.fitMeanAndOrder,...
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...
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:814
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:857
static Distrib erlang_fit(const T &m, const T &c2)
Erlang fitted to a mean and an SCV, as MATLAB's Erlang.fitMeanAndSCV.
Definition lang_types.h:904
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.
Definition lang_types.h:931
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:858
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)
Definition lang_types.h:956
static Distrib immediate()
The Immediate singleton.
Definition lang_types.h:846
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).
Definition lang_types.h:873
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.
Definition lang_types.h:987
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,...