5#ifndef LINE_LANG_LANG_TYPES_H
6#define LINE_LANG_LANG_TYPES_H
98 default:
return "Unknown Metric";
156 default:
return "INIT";
272 default:
return "none";
292 throw UnsupportedError(
"lqn reader: unsupported scheduling discipline '" + s +
"'");
318 std::string(
"the LQN XML schema has no spelling for scheduling discipline '") +
319 sched_to_text(s) +
"'; it carries inf, fcfs, ps, ref, hol, pri, rand, sjf, ljf and lcfs");
412 default:
return "disabled";
464enum class LqnElement { HOST = 0, TASK = 1, ENTRY = 2, ACTIVITY = 3, CALL = 4 };
598 default:
return "none";
626 default:
return false;
639using CdScaling = std::function<std::vector<T>(
const std::vector<T>&)>;
652using GdScaling = std::function<std::vector<T>(
const std::vector<T>&)>;
670 static constexpr double Zero = 1e-14;
679 static constexpr double MaxInt = 2147483647.0;
775 std::shared_ptr<PriorSpec<T>>
prior;
809 d.
params.push_back(lambda);
875 if (r == 0)
throw InputError(
"Erlang: the number of phases must be positive");
876 if (!(phase_rate > zero))
throw InputError(
"Erlang: the phase rate must be positive");
880 d.
params.push_back(phase_rate);
886 for (std::size_t i = 0; i < r; ++i) {
887 d.
D0(i, i) = T(-phase_rate);
888 if (i + 1 < r) d.
D0(i, i + 1) = phase_rate;
890 d.
D1(r - 1, 0) = phase_rate;
906 if (!(c2 > zero))
throw InputError(
"Erlang.fitMeanAndSCV: the SCV must be positive");
909 "Erlang.fitMeanAndSCV: the Erlang distribution requires a squared coefficient "
910 "of variation <= 1; use HyperExp, Coxian or APH above 1");
913 const std::size_t r =
static_cast<std::size_t
>(r_d < 1.0 ? 1.0 : r_d);
933 const std::size_t n = p.size();
934 if (n == 0 || lambda.size() != n)
935 throw InputError(
"HyperExp: p and lambda must be non-empty and of equal length");
939 for (
const T& v : p) d.
params.push_back(v);
940 for (
const T& v : lambda) d.
params.push_back(v);
943 T m1 = zero, m2 = zero;
944 for (std::size_t i = 0; i < n; ++i) {
945 if (!(lambda[i] > zero))
throw InputError(
"HyperExp: the phase rates must be positive");
946 d.
D0(i, i) = T(-lambda[i]);
947 for (std::size_t j = 0; j < n; ++j) d.
D1(i, j) = T(lambda[i] * p[j]);
948 m1 += T(p[i] / lambda[i]);
949 m2 += T(two * p[i] / (lambda[i] * lambda[i]));
952 d.
scv = T((m2 - m1 * m1) / (m1 * m1));
958 if (!(lambda1 > zero) || !(lambda2 > zero))
959 throw InputError(
"HyperExp: the phase rates must be positive");
960 if (p < zero || p > one)
throw InputError(
"HyperExp: p is not a probability");
965 d.
params.push_back(lambda1);
966 d.
params.push_back(lambda2);
967 const T q = T(one - p);
968 d.
mean = T(p / lambda1 + q / lambda2);
970 (p / (lambda1 * lambda1) + q / (lambda2 * lambda2)));
974 d.
D0(0, 0) = T(-lambda1);
975 d.
D0(1, 1) = T(-lambda2);
976 d.
D1(0, 0) = T(lambda1 * p);
977 d.
D1(0, 1) = T(lambda1 * q);
978 d.
D1(1, 0) = T(lambda2 * p);
979 d.
D1(1, 1) = T(lambda2 * q);
987 static Distrib coxian(
const std::vector<T>& mu,
const std::vector<T>& phi) {
989 const std::size_t n = mu.size();
990 if (n == 0 || phi.size() != n)
991 throw InputError(
"Coxian: mu and phi must be non-empty and of equal length");
995 for (
const T& v : mu) d.
params.push_back(v);
996 for (
const T& v : phi) d.
params.push_back(v);
999 for (std::size_t i = 0; i < n; ++i) {
1000 if (!(mu[i] > zero))
throw InputError(
"Coxian: the phase rates must be positive");
1001 d.
D0(i, i) = T(-mu[i]);
1002 if (i + 1 < n) d.
D0(i, i + 1) = T(mu[i] * (one - phi[i]));
1003 d.
D1(i, 0) = T(mu[i] * phi[i]);
1014 std::vector<T> mu, phi;
1017 phi.push_back(phi1);
1030 const std::size_t n = alpha.size();
1031 if (n == 0 || A.
rows() != n || A.
cols() != n)
1032 throw InputError(
"PH: alpha and the subgenerator have inconsistent sizes");
1036 for (
const T& v : alpha) d.
params.push_back(v);
1039 for (std::size_t i = 0; i < n; ++i) {
1041 for (std::size_t j = 0; j < n; ++j) out += A(i, j);
1042 for (std::size_t j = 0; j < n; ++j) d.
D1(i, j) = T(-out * alpha[j]);
1053 throw InputError(
"MAP: D0 and D1 must be square and of the same order");
1075 const std::size_t n = D0segs.size();
1076 if (n == 0 || D1segs.size() != n)
1077 throw InputError(who +
": the two segment lists must be non-empty and equally long");
1078 if (breakpoints.size() != n + 1)
1080 ": breakpoints is the BOUNDARY vector and must hold one more entry "
1081 "than there are segments");
1082 for (std::size_t k = 0; k + 1 < breakpoints.size(); ++k)
1083 if (!(breakpoints[k + 1] > breakpoints[k]))
1084 throw InputError(who +
": breakpoints must be strictly increasing");
1085 const std::size_t order = D0segs[0].rows();
1086 for (std::size_t k = 0; k < n; ++k)
1087 if (D0segs[k].rows() != order || D0segs[k].cols() != order ||
1088 D1segs[k].rows() != order || D1segs[k].cols() != order)
1090 ": every segment must have the same order; the schedule "
1091 "modulates one phase structure and does not switch between them");
1103 for (std::size_t k = 0; k < n; ++k) total += T(breakpoints[k + 1] - breakpoints[k]);
1106 for (std::size_t k = 0; k < n; ++k) {
1107 const T w = T(T(breakpoints[k + 1] - breakpoints[k]) / total);
1108 for (std::size_t a = 0; a < order; ++a)
1109 for (std::size_t b = 0; b < order; ++b) {
1110 d.
D0(a, b) += w * D0segs[k](a, b);
1111 d.
D1(a, b) += w * D1segs[k](a, b);
1139 const std::vector<
Matrix<T>>& D1segs,
bool cyclic) {
1148 static Distrib pht(
const std::vector<T>& breakpoints,
const std::vector<std::vector<T>>& alphas,
1149 const std::vector<
Matrix<T>>& Ssegs,
bool cyclic) {
1151 if (alphas.size() != Ssegs.size() || alphas.empty())
1152 throw InputError(
"PHt: alpha and S must have the same, non-zero number of segments");
1153 std::vector<Matrix<T>> D0segs, D1segs;
1154 for (std::size_t k = 0; k < Ssegs.size(); ++k) {
1156 const std::vector<T>& a = alphas[k];
1158 throw InputError(
"PHt: alpha and the sub-generator disagree in order");
1160 for (std::size_t i = 0; i < S.
rows(); ++i) {
1162 for (std::size_t j = 0; j < S.
cols(); ++j) s += S(i, j);
1163 for (std::size_t j = 0; j < S.
cols(); ++j)
D1(i, j) = T(-s * a[j]);
1165 D0segs.push_back(S);
1166 D1segs.push_back(
D1);
1177 static Distrib nhpp(
const std::vector<T>& breakpoints,
const std::vector<T>& rates,
1179 std::vector<Matrix<T>> D0segs, D1segs;
1180 for (std::size_t k = 0; k < rates.size(); ++k) {
1181 Matrix<T> a(1, 1, T(-rates[k])), b(1, 1, rates[k]);
1182 D0segs.push_back(a);
1183 D1segs.push_back(b);
1194 if (!(b > a))
throw InputError(
"Uniform: the upper bound must exceed the lower bound");
1201 const T w = T(b - a);
1210 throw InputError(
"Pareto: the shape must exceed 2 for a finite variance");
1214 d.
params.push_back(shape);
1215 d.
params.push_back(scale);
1216 d.
mean = T(shape * scale / (shape - one));
1217 const T var = T(scale * scale * shape / ((shape - one) * (shape - one)) / (shape - two));
1236 d.
params.push_back(shape);
1237 d.
params.push_back(scale);
1238 d.
mean = T(shape * scale);
1239 d.
scv = T(one / shape);
1246 "Weibull: its moments are values of the gamma function, which exact arithmetic "
1247 "has no representation for; use the double or real backend");
1251 if (!(a > 0.0) || !(r > 0.0))
1252 throw InputError(
"Weibull: the scale and the shape must be positive");
1253 const double g1 = std::tgamma(1.0 + 1.0 / r);
1254 const double g2 = std::tgamma(1.0 + 2.0 / r);
1258 d.
params.push_back(scale);
1259 d.
params.push_back(shape);
1269 "Lognormal: its moments are values of exp, which exact arithmetic has no "
1270 "representation for; use the double or real backend");
1274 if (!(sg > 0.0))
throw InputError(
"Lognormal: sigma must be positive");
1278 d.
params.push_back(logmean);
1279 d.
params.push_back(logsigma);
1296 throw InputError(
"Normal: sigma must be positive");
1301 d.
params.push_back(sigma);
1326 if (samples.empty())
throw InputError(
"Replayer: the trace is empty");
1333 for (
const T& x : samples) {
1355 if (!(b >= a))
throw InputError(
"DiscreteUniform: the upper bound must not be below the lower");
1361 d.
mean = T((a + b) / two);
1362 const T w = T(b - a + one);
1376 d.
scv = T((one - p) / p);
1389 d.
scv = T((one - p) / (n * p));
1402 d.
params.push_back(lambda);
1404 d.
scv = T(one / lambda);
1418 d.
mean = T(one / p);
1435 "Zipf: its moments are generalized harmonic sums of a real exponent, which exact "
1436 "arithmetic has no representation for; use the double or real backend");
1438 if (n == 0)
throw InputError(
"Zipf: the item count must be positive");
1440 auto harmonic = [n](
double e) {
1442 for (std::size_t k = 1; k <= n; ++k) acc += std::pow(
double(k), -e);
1445 const double h0 = harmonic(sv), h1 = harmonic(sv - 1.0), h2 = harmonic(sv - 2.0);
1451 const double m1 = h1 / h0;
1469 if (p.empty())
throw InputError(
"DiscreteSampler: the probability vector is empty");
1470 if (!x.empty() && x.size() != p.size())
1471 throw InputError(
"DiscreteSampler: p and x must have the same length");
1479 for (std::size_t k = 0; k < p.size(); ++k) {
1483 m2 += T(p[k] * pt * pt);
1489 d.
scv = T((m2 - m1 * m1) / (m1 * m1));
1500 if (x.size() != F.size() || x.size() < 2)
1501 throw InputError(
"EmpiricalCDF: x and F must be equally long and hold at least two points");
1509 for (std::size_t i = 0; i + 1 < x.size(); ++i) {
1510 const T mid = T((x[i + 1] - x[i]) / two + x[i]);
1511 const T w = T(F[i + 1] - F[i]);
1513 m2 += T(mid * mid * w);
1558 if (D1k.empty())
throw InputError(
"MMAP: no marked arrival block was given");
1562 throw InputError(
"MMAP: every marked block must have the order of D0");
1563 for (std::size_t i = 0; i < agg.
rows(); ++i)
1564 for (std::size_t j = 0; j < agg.
cols(); ++j) agg(i, j) += Dk(i, j);
1577 if (D.size() < 2)
throw InputError(
"BMAP: the block list must carry D0 and at least one batch block");
1578 const std::vector<Matrix<T>> batches(D.begin() + 1, D.end());
1599 v.push_back(
rate());
1602 for (std::size_t i = 0; i <
D0.
rows(); ++i) v.push_back(T(-
D0(i, i)));
1615 for (std::size_t i = 0; i <
D1.
rows(); ++i) {
1617 for (std::size_t j = 0; j <
D1.
cols(); ++j) s +=
D1(i, j);
1618 const T out = T(-
D0(i, i));
1638 const std::size_t n = alpha.size();
1640 for (
unsigned i = 0; i < k; ++i) x = solve_neg(A, x);
1642 for (std::size_t i = 0; i < n; ++i) acc += alpha[i] * x[i];
1644 for (
unsigned i = 2; i <= k; ++i) fact *= num_traits<T>::from_int(
static_cast<long>(i));
1645 return T(fact * acc);
1657 static std::vector<T> solve_neg(
const Matrix<T>& A,
const std::vector<T>& b) {
1659 const std::size_t n = A.
rows();
1660 if (A.
cols() != n || b.size() != n)
1661 throw InputError(
"phase-type moment: the subgenerator is not square");
1663 std::vector<T> x = b;
1664 for (std::size_t i = 0; i < n; ++i)
1665 for (std::size_t j = 0; j < n; ++j) M(i, j) = T(-A(i, j));
1666 for (std::size_t col = 0; col < n; ++col) {
1667 std::size_t best = col;
1669 for (std::size_t r = col + 1; r < n; ++r) {
1677 for (std::size_t j = 0; j < n; ++j) std::swap(M(col, j), M(best, j));
1678 std::swap(x[col], x[best]);
1680 if (M(col, col) == zero)
1681 throw NumericError(
"phase-type moment: the subgenerator is singular");
1682 for (std::size_t r = 0; r < n; ++r) {
1683 if (r == col)
continue;
1684 const T f = T(M(r, col) / M(col, col));
1685 if (f == zero)
continue;
1686 for (std::size_t j = 0; j < n; ++j) M(r, j) = T(M(r, j) - f * M(col, j));
1687 x[r] = T(x[r] - f * x[col]);
1690 for (std::size_t i = 0; i < n; ++i) x[i] = T(x[i] / M(i, i));
Cache(model, name, params).
ClassSwitch(model, name, C).
Delay(model, name): the infinite-server station.
NumericError(const std::string &what)
Place(model, name): a Petri-net place.
Queue(model, name, strategy).
Router(model, name): a stateless routing node.
Sink(model, name): the external departure node, which holds no jobs.
Source(model, name): the external arrival station.
Transition(model, name, params): a Petri-net transition.
UnsupportedError(const std::string &what)
The exception types the port throws.
Dense matrix and non-owning view.
SchedStrategy
Scheduling disciplines, with the values of MATLAB SchedStrategy.
DropStrategy
Blocking and loss rules, with the values of MATLAB DropStrategy.
TimingStrategy
SPN transition timing, with the values of MATLAB TimingStrategy.
@ IMMEDIATE
fires with zero delay, resolved by weight and priority
@ TIMED
fires after its firing distribution elapses
BalkingStrategy
Balking rules, with the values of MATLAB BalkingStrategy.
SignalType
G-network signal classes, with the values of MATLAB SignalType.
@ REPLY
completes a synchronous call, releasing a held server
@ NEGATIVE
removes a batch of jobs (Gelenbe's negative customer)
@ CATASTROPHE
removes EVERY job at the station
JoinStrategy
Join rules, with the values of MATLAB JoinStrategy.
PrecedenceType
Activity precedence kinds, with the values of MATLAB ActivityPrecedenceType.
LqnElement
LQN element kinds, with the values of MATLAB LayeredNetworkElement.
RoutingStrategy
Routing strategies, with the values of MATLAB RoutingStrategy.
@ SDR
Krzesinski (1987) product-form state-dependent routing.
SchedStrategy sched_from_lqnx(const std::string &s)
Parse the scheduling attribute of an .lqnx processor or task.
DepartureDiscipline
When a Place releases a served token, MATLAB DepartureDiscipline.
CallType
Call kinds, with the values of MATLAB CallType.
const char * metric_to_text(MetricType metric)
Port of MetricType.toText.
RemovalPolicy
Which job a negative signal removes, with the values of MATLAB RemovalPolicy.
@ LCFS
the newest waiting job; servers only once nobody waits
@ RANDOM
uniform over waiting AND in-service jobs
EventType
The events a state can undergo, with the values of MATLAB EventType.
@ PHASE
service advances a phase WITHOUT departing
@ READ
a cache item is read
@ FAILURE
the server breaks down, going from up to down
@ STAGE
a random environment changes stage
@ SWITCH
a polling server advances its switchover timer
@ LOCAL
dummy event, no state change outside the node
@ RENEGE
a waiting job abandons the queue (impatience)
@ POST
produce to a place or queue buffer
@ START
a job begins or resumes holding a server
@ ENABLE
an SPN mode becomes enabled
@ RETRY
an orbiting job retries entry at a retrial station
@ REPAIR
the server is repaired, going from down to up, resuming the held job, which is why it emits no START
@ PRE
consume from a place or queue buffer, no server effect
@ INIT
the model is initialized, t = 0
@ PREEMPT
a job holding a server is pushed back into the buffer
MetricType
Solver output metrics, with the numeric values of MATLAB MetricType.
HeteroSchedPolicy
How a heterogeneous station picks among its server types, MATLAB HeteroSchedPolicy.
PollingType
Polling service disciplines, with the values of MATLAB PollingType.
@ KLIMITED
serve at most K per visit (K in pollingPar)
@ EXHAUSTIVE
serve until the queue empties
@ GATED
serve exactly the jobs present at the polling instant
@ DECREMENTING
serve until the queue is one shorter than at arrival
JobClassType
Job class kinds, with the values of MATLAB JobClassType.
std::string sched_to_lqnx(SchedStrategy s)
The scheduling attribute an .lqnx processor or task carries for a strategy.
const char * node_type_to_text(NodeType t)
Name of a node kind, for diagnostics.
ProcessType
Distribution kinds, with the values of MATLAB ProcessType.
@ NORMAL
A Gaussian, and the ONE family whose value is not MATLAB's, because MATLAB has none to copy: ProcessT...
@ NHPP
The time-INHOMOGENEOUS families of Ko and Pender (ORL 45, 2017): an NHPP is a rate schedule lambda(t)...
@ PRIOR
A Prior: a weighted set of ALTERNATIVE distributions, or a density over a scalar parameter plus a fac...
std::function< std::vector< T >(const std::vector< T > &)> GdScaling
A globally state-dependent scaling, sn.gdscaling.
const char * sched_to_text(SchedStrategy s)
const char * process_to_text(ProcessType p)
The MATLAB ProcessType name, as sn.procid prints it.
bool process_is_markovian(ProcessType p)
ProcessType.isMarkovian: true when sn.proc carries an exact matrix representation of the law,...
std::function< std::vector< T >(const std::vector< T > &)> CdScaling
A class-dependent scaling map, sn.cdscaling.
const char * routing_to_text(RoutingStrategy r)
NodeType
Node kinds, with the values of MATLAB NodeType.
const char * event_to_text(EventType e)
ReplacementStrategy
Cache replacement policies, with the values of MATLAB ReplacementStrategy.
@ HLRU
h-LRU / LRU(m): h lists, promote i -> i+1 on a hit
@ CLIMB
move up one position on a hit (transposition rule)
@ QLRU
q-LRU: LRU with probabilistic admission on a miss
@ FIFO
first in, first out
ImpatienceType
Impatience kinds, with the values of MATLAB ImpatienceType.
Number-type abstraction for the templated API port.
bool is_immediate() const
static Distrib sched_dist(const std::vector< T > &breakpoints, const std::vector< Matrix< T > > &D0segs, const std::vector< Matrix< T > > &D1segs, bool cyclic, ProcessType tag)
The shared constructor of the three schedule families.
static Distrib empirical_cdf(const std::vector< T > &x, const std::vector< T > &F)
EmpiricalCDF(x, F): the moments of the MIDPOINT rule over the CDF bins, which is what MATLAB Empirica...
static Distrib nhpp(const std::vector< T > &breakpoints, const std::vector< T > &rates, bool cyclic)
NHPP(breakpoints, rates, cyclic): a MAPt of ORDER ONE, which is what an inhomogeneous Poisson process...
std::vector< T > mu_vec() const
Phase rates, MATLAB's getMu: the total outgoing rate of each phase.
bool has_map() const
True when the type carries a (D0,D1) pair of its own.
static Distrib replayer(const std::vector< double > &samples)
std::vector< double > sched_bp
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 dmap(const Matrix< T > &D0, const Matrix< T > &D1)
DMAP(D0, D1): a DISCRETE-time MAP, where D0 + D1 is stochastic rather than a generator.
static Distrib exp_rate(const T &r)
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.
std::vector< Matrix< double > > Dmark
static Distrib mapt(const std::vector< T > &breakpoints, const std::vector< Matrix< T > > &D0segs, const std::vector< Matrix< T > > &D1segs, bool cyclic)
MAPt(breakpoints, {D0_k}, {D1_k}, cyclic): a piecewise-constant (D0(t), D1(t)).
std::shared_ptr< Distrib< double > > declared
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.
bool has_schedule() const
static Distrib bmap(const std::vector< Matrix< T > > &D)
BMAP: the batch-size blocks D0, D1, ..., Dk, where Dj carries an arrival of batch size j.
static Distrib mmap(const Matrix< T > &D0, const std::vector< Matrix< T > > &D1k)
MMAP: D0 plus one D1 block per mark.
static Distrib disabled_dist()
static Distrib pht(const std::vector< T > &breakpoints, const std::vector< std::vector< T > > &alphas, const std::vector< Matrix< T > > &Ssegs, bool cyclic)
PHt(breakpoints, {alpha_k}, {S_k}, cyclic), stored as its equivalent MAP schedule: D0 = S and D1 = (-...
static double ph_moment(const std::vector< double > &alpha, const Matrix< double > &A, unsigned k)
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).
std::vector< double > params
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,...
std::vector< double > trace
static Distrib bernoulli(const T &p)
Bernoulli(p): one trial, mean p and variance p(1-p).
static double ph_moment_from(const Matrix< double > &A, std::size_t start, unsigned k)
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.
std::shared_ptr< PriorSpec< double > > prior
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)
static Distrib rap(const Matrix< T > &H0, const Matrix< T > &H1)
RAP(H0, H1): a rational arrival process, whose moments are the MAP ones.
static Distrib uniform(const T &a, const T &b)
Uniform(a, b).
std::vector< Matrix< double > > sched_D1
static Distrib lognormal(const T &logmean, const T &logsigma)
static Distrib hyperexp(const T &p, const T &lambda1, const T &lambda2)
std::vector< Matrix< double > > sched_D0
static Distrib me(const std::vector< T > &alpha, const Matrix< T > &A)
ME(alpha, A): the matrix-exponential distribution, whose moments are the phase-type ones – k!
static Distrib immediate()
The Immediate singleton.
std::vector< T > phi_vec() const
Completion probabilities, MATLAB's getPhi: (D1 e) .
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)
std::size_t phases() const
The order of the representation, MATLAB's sn.phases.
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,...
The MATLAB GlobalConstants, as reported by lineStart at its defaults.
static constexpr double Immediate
Rate of an Immediate distribution; its mean is 1/Immediate = 1e-8.
static constexpr double FineTol
static constexpr double ArcTol
Below this an off-diagonal entry is NO ARC of the phase / state graph.
static constexpr double Zero
static constexpr double CoarseTol
static constexpr double MaxInt
Stand-in for an unbounded COUNT, MATLAB GlobalConstants.MaxInt.
A LINE Distribution, as the model layer and sn carry it.
std::function< Distrib< T >(const T &)> factory
theta -> Distribution; the continuous form only.
bool continuous
True for the parameter-density form, false for the alternative-set form.
Distrib< T > param_dist
The law of the scalar parameter; the continuous form only.
std::vector< T > probabilities
std::vector< Distrib< T > > alternatives
The alternatives and their weights; the discrete form only.