5#ifndef LINE_LANG_PRIOR_H
6#define LINE_LANG_PRIOR_H
83 explicit PriorRng(
unsigned long seed) : g_(static_cast<std::uint_fast32_t>(seed)) {}
85 const std::uint64_t a = g_() >> 5, b = g_() >> 6;
86 return (
static_cast<double>(a) * 67108864.0 +
static_cast<double>(b) + 0.5) /
111 const std::vector<T>& probabilities) {
113 if (alternatives.empty())
throw InputError(
"Prior: the alternative set is empty");
114 if (alternatives.size() != probabilities.size())
115 throw InputError(
"Prior: there are " + std::to_string(alternatives.size()) +
116 " alternatives and " + std::to_string(probabilities.size()) +
119 for (std::size_t i = 0; i < probabilities.size(); ++i) {
120 if (probabilities[i] < zero)
throw InputError(
"Prior: the probabilities must be nonnegative");
121 tot += probabilities[i];
122 if (alternatives[i].disabled)
123 throw InputError(
"Prior: alternative " + std::to_string(i + 1) +
" is disabled");
124 if (alternatives[i].is_prior())
125 throw InputError(
"Prior: alternative " + std::to_string(i + 1) +
126 " is itself a Prior; nest the uncertainty in one Prior instead");
129 throw InputError(
"Prior: the probabilities must sum to 1 (they sum to " +
134 d.
prior = std::make_shared<PriorSpec<T>>();
135 d.
prior->continuous =
false;
136 d.
prior->alternatives = alternatives;
137 d.
prior->probabilities = probabilities;
151 const std::function<
Distrib<T>(
const T&)>& factory) {
152 if (param_dist.
disabled)
throw InputError(
"Prior: the parameter distribution is disabled");
154 throw InputError(
"Prior: the parameter distribution is itself a Prior");
155 if (!factory)
throw InputError(
"Prior: the distribution factory is empty");
158 throw InputError(
"Prior: the distribution factory must return a usable Distribution");
162 d.
prior = std::make_shared<PriorSpec<T>>();
163 d.
prior->continuous =
true;
164 d.
prior->param_dist = param_dist;
165 d.
prior->factory = factory;
180 const std::function<
Distrib<T>(
const T&)>& factory =
182 if (k < 1)
throw InputError(
"Prior.fromSample: k must be a positive observation count");
184 throw InputError(
"Prior.fromSample: s must be a positive sum of observed lifetimes");
185 std::function<Distrib<T>(
const T&)> f = factory;
199 if (!d.
is_prior())
throw InputError(
"prior_discretize: the distribution is not a Prior");
200 if (method !=
"quadrature" && method !=
"montecarlo")
201 throw InputError(
"prior_discretize: unknown discretization method '" + method +
"'");
202 if (n < 1)
throw InputError(
"prior_discretize: the node count must be at least 1");
208 if (method ==
"quadrature") {
220 for (std::size_t i = 0; i < n; ++i) {
221 const double u =
rng.uniform() * acc;
223 while (k + 1 < cum.size() && cum[k] < u) ++k;
230 for (std::size_t i = 0; i < n; ++i) {
232 if (method ==
"quadrature") {
236 static_cast<double>(n));
242 throw InputError(
"prior_discretize: the factory returned an unusable Distribution");
243 out.
dists.push_back(alt);
261 for (std::size_t i = 0; i < g.
dists.size(); ++i) m += T(g.
weights[i] * g.
dists[i].mean);
277 for (std::size_t i = 0; i < g.
dists.size(); ++i) {
278 const T m = g.
dists[i].mean;
279 const T v = T(g.
dists[i].scv * m * m);
282 e_mean_sq += T(g.
weights[i] * m * m);
285 throw NumericError(
"prior_scv: the prior-weighted mean is not positive");
286 const T total_var = T(e_var + (e_mean_sq - e_mean * e_mean));
287 return T(total_var / (e_mean * e_mean));
303 const T sigma2 = T(scv * mu * mu);
308 for (std::size_t i = 0; i < g.
dists.size(); ++i) {
309 const T mi = g.
dists[i].mean;
310 const T vi = T(g.
dists[i].scv * mi * mi);
311 const T m3i = T(
dist_moment(g.
dists[i], 3) - three * mi * vi - mi * mi * mi);
312 const T delta = T(mi - mu);
313 third += T(g.
weights[i] * (m3i + three * vi * delta + delta * delta * delta));
NumericError(const std::string &what)
The uniform stream the Monte Carlo design draws from.
PriorRng(unsigned long seed)
What refreshProcessRepresentations and refreshLST compute FROM a distribution: the (D0,...
The exception types the port throws.
Enumerations and the minimal distribution descriptor shared by the model layer of the C++ port.
void prior_refresh_moments(Distrib< T > &d)
Write the mixture moments onto a Prior, the counterpart of dist_refresh_moments for the Markovian fam...
constexpr std::size_t kPriorDefaultNodes
The default number of nodes per continuous Prior, MATLAB options.samples.
PriorDesign< T > prior_discretize(const Distrib< T > &d, std::size_t n, const std::string &method, PriorRng &rng)
Reduce a Prior to n weighted alternatives, MATLAB Prior.discretize.
T prior_cdf(const Distrib< T > &d, const T &t)
F(t) = sum_i p_i F_i(t), MATLAB Prior.evalCDF.
T dist_quantile(const Distrib< T > &d, const T &p)
The p-quantile, by bisection on dist_cdf.
T prior_lst(const Distrib< T > &d, const T &s)
L(s) = sum_i p_i L_i(s), MATLAB Prior.evalLST.
Distrib< T > prior_continuous(const Distrib< T > ¶m_dist, const std::function< Distrib< T >(const T &)> &factory)
Prior(paramDist, distFactory): the continuous form.
T dist_lst(const Distrib< T > &d, const T &s)
sn.lst: the Laplace-Stieltjes transform E[exp(-sX)].
T prior_mean(const Distrib< T > &d)
E[X] = sum_i p_i E[X_i], MATLAB Prior.getMean.
Distrib< T > prior_discrete(const std::vector< Distrib< T > > &alternatives, const std::vector< T > &probabilities)
Prior(distributions, probabilities): the discrete form.
T dist_cdf(const Distrib< T > &d, const T &x)
F(x) = P{X <= x}, MATLAB's Distribution.evalCDF.
Distrib< T > prior_from_sample(std::size_t k, const T &s, const std::function< Distrib< T >(const T &)> &factory=std::function< Distrib< T >(const T &)>())
Prior.fromSample(k, s): the posterior of a rate estimated from lifetime data.
@ PRIOR
A Prior: a weighted set of ALTERNATIVE distributions, or a density over a scalar parameter plus a fac...
T prior_skewness(const Distrib< T > &d)
The skewness of the mixture, MATLAB Prior.getSkewness.
T dist_moment(const Distrib< T > &d, unsigned k)
The k-th raw moment.
T prior_scv(const Distrib< T > &d)
The SCV by the law of total variance, MATLAB Prior.getSCV.
Number-type abstraction for the templated API port.
static Distrib exp_rate(const T &r)
std::shared_ptr< PriorSpec< T > > prior
The alternatives of a Prior, set only when type == PRIOR.
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 constexpr double FineTol
static constexpr double CoarseTol
A Prior reduced to alternatives and weights; the output of prior_discretize.
std::vector< Distrib< T > > dists
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.