5#ifndef LINE_LANG_DIST_FITTERS_H
6#define LINE_LANG_DIST_FITTERS_H
59T fpow(
const T& b,
const T& e) {
79 const std::size_t n = m.
D0.rows();
80 for (std::size_t i = 0; i < n; ++i) {
82 for (std::size_t j = 0; j < n; ++j) out += m.
D1(i, j);
84 std::vector<T> alpha(n);
85 for (std::size_t j = 0; j < n; ++j) alpha[j] = T(m.
D1(i, j) / out);
88 throw NumericError(
"ph_from_map: no phase completes, so the fitted PH has no alpha");
98 if (k == 0)
throw InputError(
"Erlang.fitMeanAndOrder: the order must be positive");
100 throw InputError(
"Erlang.fitMeanAndOrder: the mean must be positive");
115 "HyperExp.fitMeanAndSCV needs a square root of the moment discriminant");
119 const T mu1 = T(-m.
D0(0, 0)), mu2 = T(-m.
D0(1, 1));
120 const T p = T(m.
D1(0, 0) / mu1);
131 "HyperExp.fitMeanAndSCVBalanced needs a square root");
133 const T root = fitdetail::fsqrt<T>(T((scv - one) / (scv + one)));
134 T p = T(one / two - root / two);
135 T mu1 = T(-(two * (root / two - one / two)) / mean);
137 p = T(root / two + one / two);
138 mu1 = T((two * (root / two + one / two)) / mean);
140 const T mu2 = T((one - p) / p * mu1);
162 std::vector<T> mu, phi;
163 if (c2 >= 1.0 - tol && c2 <= 1.0 + tol) {
164 mu.push_back(T(one / mean));
166 }
else if (c2 > 0.5 + tol && c2 < 1.0 - tol) {
167 const T r = fitdetail::fsqrt<T>(T(one + two * (scv - one)));
168 mu.push_back(T(two / mean / (one + r)));
169 mu.push_back(T(two / mean / (one - r)));
172 }
else if (c2 <= 0.5 + tol) {
173 const std::size_t n =
static_cast<std::size_t
>(std::ceil(1.0 / c2));
175 mu.assign(n, lambda);
180 mu.push_back(T(two / mean));
181 mu.push_back(T(mu[0] / (two * scv)));
182 phi.push_back(T(one - mu[1] / mu[0]));
200 const T scv = T(var / (mean * mean));
202 const T e2 = T((one + scv) * e1 * e1);
213 const T s = fitdetail::fsqrt<T>(disc);
218 mu2[0] = T(-(a - e3 + s) / den);
219 mu2[1] = T((e3 - a + s) / den);
220 for (
int k = 0; k < 2; ++k) {
221 const T phi = T(one - mu2[k] * e1 + mu2[k] / mu1[k]);
255 const T scv = T(var / (mean * mean));
257 const T e2 = T((one + scv) * e1 * e1);
283 const T shape = T(one + fitdetail::fsqrt<T>(T(one + one / scv)));
Minimal-order acyclic phase-type fit of the first three moments (matlab/lib/kpctoolbox/aph/aph_fit....
Acyclic phase-type fitters from the first two moments.
NumericError(const std::string &what)
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 > ph_from_map(const mam::Map< T > &m, bool acyclic)
A PH distribution from a fitted (D0, D1) pair.
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...
Map< T > aph_fit_mean_scv(const T &mean, const T &scv)
Port of APH.fitMeanAndSCV, the entry point the analyzers fit arrivals with.
Map< T > map_hyperexp(const T &mean, const T &scv, const T &p_in)
Two-phase hyperexponential renewal MAP matching a mean and an SCV >= 1, with branching probability p ...
AphFitResult< T > aph_fit(const T &e1, const T &e2, const T &e3, unsigned nmax, const T &tol)
Fit an APH(n) with n <= nmax to the raw moments e1, e2, e3.
Number-type abstraction for the templated API port.
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 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 hyperexp(const T &p, const T &lambda1, const T &lambda2)
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 exp_mean(const T &m)
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 constexpr double CoarseTol
A MAP as the pair of matrices (D0, D1).