38inline double uniform_pdf(
double x,
double a = 0.0,
double b = 1.0)
41 throw std::invalid_argument(
"statcpp::uniform_pdf: a must be less than b");
60inline double uniform_cdf(
double x,
double a = 0.0,
double b = 1.0)
63 throw std::invalid_argument(
"statcpp::uniform_cdf: a must be less than b");
65 if (x < a)
return 0.0;
66 if (x > b)
return 1.0;
67 return (x - a) / (b - a);
84 throw std::invalid_argument(
"statcpp::uniform_quantile: a must be less than b");
86 if (p < 0.0 || p > 1.0) {
87 throw std::invalid_argument(
"statcpp::uniform_quantile: p must be in [0, 1]");
89 return a + p * (b - a);
102template <
typename Engine = default_random_engine>
106 throw std::invalid_argument(
"statcpp::uniform_rand: a must be less than b");
108 std::uniform_real_distribution<double> dist(a, b);
139inline double normal_pdf(
double x,
double mu = 0.0,
double sigma = 1.0)
142 throw std::invalid_argument(
"statcpp::normal_pdf: sigma must be positive");
144 double z = (x - mu) / sigma;
145 return std::exp(-0.5 * z * z) / (sigma *
sqrt_2_pi);
159inline double normal_cdf(
double x,
double mu = 0.0,
double sigma = 1.0)
162 throw std::invalid_argument(
"statcpp::normal_cdf: sigma must be positive");
188 throw std::invalid_argument(
"statcpp::normal_quantile: sigma must be positive");
190 if (p <= 0.0 || p >= 1.0) {
191 if (p == 0.0)
return -std::numeric_limits<double>::infinity();
192 if (p == 1.0)
return std::numeric_limits<double>::infinity();
193 throw std::invalid_argument(
"statcpp::normal_quantile: p must be in (0, 1)");
208template <
typename Engine = default_random_engine>
212 throw std::invalid_argument(
"statcpp::normal_rand: sigma must be positive");
214 std::normal_distribution<double> dist(mu, sigma);
247 throw std::invalid_argument(
"statcpp::exponential_pdf: lambda must be positive");
249 if (x < 0.0)
return 0.0;
250 return lambda * std::exp(-lambda * x);
266 throw std::invalid_argument(
"statcpp::exponential_cdf: lambda must be positive");
268 if (x < 0.0)
return 0.0;
269 return -std::expm1(-lambda * x);
285 throw std::invalid_argument(
"statcpp::exponential_quantile: lambda must be positive");
287 if (p < 0.0 || p >= 1.0) {
288 if (p == 1.0)
return std::numeric_limits<double>::infinity();
289 throw std::invalid_argument(
"statcpp::exponential_quantile: p must be in [0, 1)");
291 return -std::log(1.0 - p) / lambda;
303template <
typename Engine = default_random_engine>
307 throw std::invalid_argument(
"statcpp::exponential_rand: lambda must be positive");
309 std::exponential_distribution<double> dist(lambda);
340inline double gamma_pdf(
double x,
double shape,
double rate = 1.0)
343 throw std::invalid_argument(
"statcpp::gamma_pdf: shape must be positive");
346 throw std::invalid_argument(
"statcpp::gamma_pdf: rate must be positive");
348 if (x < 0.0)
return 0.0;
350 if (shape < 1.0)
return std::numeric_limits<double>::infinity();
351 if (shape == 1.0)
return rate;
355 return std::exp(shape * std::log(rate) + (shape - 1.0) * std::log(x) - rate * x -
lgamma(shape));
369inline double gamma_cdf(
double x,
double shape,
double rate = 1.0)
372 throw std::invalid_argument(
"statcpp::gamma_cdf: shape must be positive");
375 throw std::invalid_argument(
"statcpp::gamma_cdf: rate must be positive");
377 if (x <= 0.0)
return 0.0;
394 throw std::invalid_argument(
"statcpp::gamma_quantile: shape must be positive");
397 throw std::invalid_argument(
"statcpp::gamma_quantile: rate must be positive");
399 if (p < 0.0 || p > 1.0) {
400 throw std::invalid_argument(
"statcpp::gamma_quantile: p must be in [0, 1]");
402 if (p == 0.0)
return 0.0;
403 if (p == 1.0)
return std::numeric_limits<double>::infinity();
418template <
typename Engine = default_random_engine>
422 throw std::invalid_argument(
"statcpp::gamma_rand: shape must be positive");
425 throw std::invalid_argument(
"statcpp::gamma_rand: rate must be positive");
428 std::gamma_distribution<double> dist(shape, 1.0 / rate);
459inline double beta_pdf(
double x,
double alpha,
double beta_param)
462 throw std::invalid_argument(
"statcpp::beta_pdf: alpha must be positive");
464 if (beta_param <= 0.0) {
465 throw std::invalid_argument(
"statcpp::beta_pdf: beta must be positive");
467 if (x < 0.0 || x > 1.0)
return 0.0;
469 if (alpha < 1.0)
return std::numeric_limits<double>::infinity();
470 if (alpha == 1.0)
return beta_param;
474 if (beta_param < 1.0)
return std::numeric_limits<double>::infinity();
475 if (beta_param == 1.0)
return alpha;
479 return std::exp((alpha - 1.0) * std::log(x) + (beta_param - 1.0) * std::log(1.0 - x) -
lbeta(alpha, beta_param));
493inline double beta_cdf(
double x,
double alpha,
double beta_param)
496 throw std::invalid_argument(
"statcpp::beta_cdf: alpha must be positive");
498 if (beta_param <= 0.0) {
499 throw std::invalid_argument(
"statcpp::beta_cdf: beta must be positive");
501 if (x <= 0.0)
return 0.0;
502 if (x >= 1.0)
return 1.0;
504 return betainc(alpha, beta_param, x);
519 throw std::invalid_argument(
"statcpp::beta_quantile: alpha must be positive");
521 if (beta_param <= 0.0) {
522 throw std::invalid_argument(
"statcpp::beta_quantile: beta must be positive");
524 if (p < 0.0 || p > 1.0) {
525 throw std::invalid_argument(
"statcpp::beta_quantile: p must be in [0, 1]");
527 if (p == 0.0)
return 0.0;
528 if (p == 1.0)
return 1.0;
543template <
typename Engine = default_random_engine>
544double beta_rand(
double alpha,
double beta_param, Engine& engine)
547 throw std::invalid_argument(
"statcpp::beta_rand: alpha must be positive");
549 if (beta_param <= 0.0) {
550 throw std::invalid_argument(
"statcpp::beta_rand: beta must be positive");
553 std::gamma_distribution<double> dist_a(alpha, 1.0);
554 std::gamma_distribution<double> dist_b(beta_param, 1.0);
556 double x = dist_a(engine);
557 double y = dist_b(engine);
560 while (x + y <= 0.0) {
596 throw std::invalid_argument(
"statcpp::chisq_pdf: df must be positive");
616 throw std::invalid_argument(
"statcpp::chisq_cdf: df must be positive");
632 throw std::invalid_argument(
"statcpp::chisq_quantile: df must be positive");
646template <
typename Engine = default_random_engine>
650 throw std::invalid_argument(
"statcpp::chisq_rand: df must be positive");
680inline double t_pdf(
double x,
double df)
683 throw std::invalid_argument(
"statcpp::t_pdf: df must be positive");
686 double coef = std::exp(
lgamma((df + 1.0) / 2.0) -
lgamma(df / 2.0)) / std::sqrt(df *
pi);
687 return coef * std::pow(1.0 + x * x / df, -(df + 1.0) / 2.0);
707inline double t_cdf(
double x,
double df)
710 throw std::invalid_argument(
"statcpp::t_cdf: df must be positive");
714 double p =
betainc(df / 2.0, 0.5, df / (df + t2));
717 return 1.0 - 0.5 * p;
742 throw std::invalid_argument(
"statcpp::t_quantile: df must be positive");
744 if (p <= 0.0 || p >= 1.0) {
745 if (p == 0.0)
return -std::numeric_limits<double>::infinity();
746 if (p == 1.0)
return std::numeric_limits<double>::infinity();
747 throw std::invalid_argument(
"statcpp::t_quantile: p must be in (0, 1)");
754 if (df > 2.0 && df < 4.0) {
755 x *= std::sqrt(df / (df - 2.0));
758 const double eps = 1e-10;
759 const int max_iter = 50;
761 for (
int i = 0; i < max_iter; ++i) {
762 if (!std::isfinite(x)) {
765 double f =
t_cdf(x, df) - p;
766 if (std::abs(f) < eps) {
769 double fprime =
t_pdf(x, df);
770 if (fprime == 0.0)
break;
772 double x_new = x - f / fprime;
774 if (std::abs(x_new - x) < eps * (1.0 + std::abs(x))) {
781 if (!std::isfinite(x)) {
796template <
typename Engine = default_random_engine>
800 throw std::invalid_argument(
"statcpp::t_rand: df must be positive");
802 std::student_t_distribution<double> dist(df);
832inline double f_pdf(
double x,
double df1,
double df2)
835 throw std::invalid_argument(
"statcpp::f_pdf: df1 must be positive");
838 throw std::invalid_argument(
"statcpp::f_pdf: df2 must be positive");
840 if (x <= 0.0)
return 0.0;
842 double log_pdf = (df1 / 2.0) * std::log(df1) + (df2 / 2.0) * std::log(df2)
843 + (df1 / 2.0 - 1.0) * std::log(x)
844 - ((df1 + df2) / 2.0) * std::log(df1 * x + df2)
845 -
lbeta(df1 / 2.0, df2 / 2.0);
847 return std::exp(log_pdf);
862inline double f_cdf(
double x,
double df1,
double df2)
865 throw std::invalid_argument(
"statcpp::f_cdf: df1 must be positive");
868 throw std::invalid_argument(
"statcpp::f_cdf: df2 must be positive");
870 if (x <= 0.0)
return 0.0;
872 double z = df1 * x / (df1 * x + df2);
873 return betainc(df1 / 2.0, df2 / 2.0, z);
896 throw std::invalid_argument(
"statcpp::f_quantile: df1 must be positive");
899 throw std::invalid_argument(
"statcpp::f_quantile: df2 must be positive");
901 if (p < 0.0 || p > 1.0) {
902 throw std::invalid_argument(
"statcpp::f_quantile: p must be in [0, 1]");
904 if (p == 0.0)
return 0.0;
905 if (p == 1.0)
return std::numeric_limits<double>::infinity();
908 double z =
betaincinv(df1 / 2.0, df2 / 2.0, p);
909 double x = df2 * z / (df1 * (1.0 - z));
910 if (!std::isfinite(x) || x <= 0.0) {
914 const double eps = 1e-10;
915 const int max_iter = 50;
917 for (
int i = 0; i < max_iter; ++i) {
918 if (!std::isfinite(x) || x <= 0.0) {
921 double f =
f_cdf(x, df1, df2) - p;
922 if (std::abs(f) < eps) {
925 double fprime =
f_pdf(x, df1, df2);
926 if (fprime == 0.0)
break;
928 double x_new = x - f / fprime;
933 if (std::abs(x_new - x) < eps * x) {
940 if (!std::isfinite(x) || x <= 0.0) {
956template <
typename Engine = default_random_engine>
957double f_rand(
double df1,
double df2, Engine& engine)
960 throw std::invalid_argument(
"statcpp::f_rand: df1 must be positive");
963 throw std::invalid_argument(
"statcpp::f_rand: df2 must be positive");
965 std::fisher_f_distribution<double> dist(df1, df2);
976inline double f_rand(
double df1,
double df2)
999 throw std::invalid_argument(
"statcpp::lognormal_pdf: sigma must be positive");
1004 double log_x = std::log(x);
1005 double z = (log_x - mu) / sigma;
1006 return std::exp(-0.5 * z * z) / (x * sigma *
sqrt_2_pi);
1023 throw std::invalid_argument(
"statcpp::lognormal_cdf: sigma must be positive");
1028 double log_x = std::log(x);
1029 return norm_cdf((log_x - mu) / sigma);
1046 throw std::invalid_argument(
"statcpp::lognormal_quantile: sigma must be positive");
1048 if (p <= 0.0 || p >= 1.0) {
1049 if (p == 0.0)
return 0.0;
1050 if (p == 1.0)
return std::numeric_limits<double>::infinity();
1051 throw std::invalid_argument(
"statcpp::lognormal_quantile: p must be in (0, 1)");
1066template <
typename Engine = default_random_engine>
1070 throw std::invalid_argument(
"statcpp::lognormal_rand: sigma must be positive");
1072 std::lognormal_distribution<double> dist(mu, sigma);
1073 return dist(engine);
1106 throw std::invalid_argument(
"statcpp::weibull_pdf: shape must be positive");
1109 throw std::invalid_argument(
"statcpp::weibull_pdf: scale must be positive");
1116 return std::numeric_limits<double>::infinity();
1117 }
else if (shape == 1.0) {
1123 double z = x / scale;
1124 return (shape / scale) * std::pow(z, shape - 1.0) * std::exp(-std::pow(z, shape));
1141 throw std::invalid_argument(
"statcpp::weibull_cdf: shape must be positive");
1144 throw std::invalid_argument(
"statcpp::weibull_cdf: scale must be positive");
1149 double z = x / scale;
1150 return 1.0 - std::exp(-std::pow(z, shape));
1167 throw std::invalid_argument(
"statcpp::weibull_quantile: shape must be positive");
1170 throw std::invalid_argument(
"statcpp::weibull_quantile: scale must be positive");
1172 if (p < 0.0 || p > 1.0) {
1173 throw std::invalid_argument(
"statcpp::weibull_quantile: p must be in [0, 1]");
1175 if (p == 0.0)
return 0.0;
1176 if (p == 1.0)
return std::numeric_limits<double>::infinity();
1177 return scale * std::pow(-std::log(1.0 - p), 1.0 / shape);
1190template <
typename Engine = default_random_engine>
1194 throw std::invalid_argument(
"statcpp::weibull_rand: shape must be positive");
1197 throw std::invalid_argument(
"statcpp::weibull_rand: scale must be positive");
1199 std::weibull_distribution<double> dist(shape, scale);
1200 return dist(engine);
1238 throw std::invalid_argument(
"statcpp::studentized_range_cdf: k must be >= 2");
1241 throw std::invalid_argument(
"statcpp::studentized_range_cdf: df must be positive");
1243 if (q <= 0.0)
return 0.0;
1248 double result = 2.0 *
t_cdf(q /
sqrt_2, df) - 1.0;
1249 return std::max(0.0, std::min(1.0, result));
1254 static constexpr int ihalf = 6;
1255 static constexpr double xleg[ihalf] = {
1256 0.981560634246719250690549090149,
1257 0.904117256370474856678465866119,
1258 0.769902674194304687036893833213,
1259 0.587317954286617447296702418941,
1260 0.367831498998180193752691536644,
1261 0.125233408511468915472441369464
1263 static constexpr double aleg[ihalf] = {
1264 0.047175336386511827194615961485,
1265 0.106939325995318430960254718194,
1266 0.160078328543346226334652529543,
1267 0.203167426723065921749064455810,
1268 0.233492536538354808760849898925,
1269 0.249147045813402785000562436043
1274 auto wprob = [&](
double w,
double cc) ->
double {
1275 static constexpr double C1 = -30.0;
1276 static constexpr double C2 = -50.0;
1277 static constexpr double C3 = 60.0;
1278 static constexpr double bb = 8.0;
1279 static constexpr double wlar = 3.0;
1280 static constexpr double wincr1 = 2.0;
1281 static constexpr double wincr2 = 3.0;
1282 static constexpr double M_1_SQRT_2PI = 0.398942280401432677939946059934;
1284 double qsqz = w * 0.5;
1285 if (qsqz >= bb)
return 1.0;
1288 double pr_w = 2.0 *
norm_cdf(qsqz) - 1.0;
1289 if (pr_w >= std::exp(C2 / cc))
1290 pr_w = std::pow(pr_w, cc);
1295 double wincr = (w > wlar) ? wincr1 : wincr2;
1299 double binc = (bb - qsqz) / wincr;
1300 double bub = blb + binc;
1301 double einsum = 0.0;
1302 double cc1 = cc - 1.0;
1304 for (
int wi = 0; wi < static_cast<int>(wincr); ++wi) {
1306 double a = 0.5 * (bub + blb);
1307 double b = 0.5 * (bub - blb);
1309 for (
int jj = 1; jj <= 12; ++jj) {
1319 double ac = a + b * xx;
1321 double qexpo = ac * ac;
1322 if (qexpo > C3)
break;
1325 double pminus = 2.0 *
norm_cdf(ac - w);
1326 double rinsum = (pplus * 0.5) - (pminus * 0.5);
1328 if (rinsum >= std::exp(C1 / cc1)) {
1329 rinsum = aleg[jj <= ihalf ? jj - 1 : 12 - jj]
1330 * std::exp(-0.5 * qexpo) * std::pow(rinsum, cc1);
1334 elsum *= (2.0 * b) * cc * M_1_SQRT_2PI;
1341 if (pr_w <= std::exp(C1))
return 0.0;
1343 pr_w = std::pow(pr_w, 1.0);
1344 return std::max(0.0, std::min(1.0, pr_w));
1354 static constexpr int ihalfq = 8;
1355 static constexpr double xlegq[ihalfq] = {
1356 0.989400934991649932596154244360,
1357 0.944575023073232576077988415535,
1358 0.865631202387831743880467897712,
1359 0.755404408355003033895101194847,
1360 0.617876244402643748446671764049,
1361 0.458016777657227386342419442984,
1362 0.281603550779258913230460501460,
1363 0.095012509837637440185319335425
1365 static constexpr double alegq[ihalfq] = {
1366 0.027152459411754094851780572456,
1367 0.062253523938647892862843836994,
1368 0.095158511682492784809925107602,
1369 0.124628971255533872052476282192,
1370 0.149595988816576732081501730547,
1371 0.169156519395002538189312079030,
1372 0.182603415044923588866763667969,
1373 0.189450610455068496285396723208
1377 double f2 = df * 0.5;
1378 double f2lf = (f2 * std::log(df)) - (df * std::log(2.0)) -
lgamma(f2);
1379 double f21 = f2 - 1.0;
1380 double ff4 = df * 0.25;
1384 if (df <= 100.0) ulen = 1.0;
1385 else if (df <= 800.0) ulen = 0.5;
1386 else if (df <= 5000.0) ulen = 0.25;
1389 f2lf += std::log(ulen);
1393 for (
int i = 1; i <= 50; ++i) {
1395 double twa1 = (2.0 * i - 1.0) * ulen;
1397 for (
int jj = 1; jj <= 16; ++jj) {
1403 j = jj - ihalfq - 1;
1404 t_point = twa1 + xlegq[j] * ulen;
1405 t1 = f2lf + f21 * std::log(t_point) - t_point * ff4;
1408 t_point = twa1 - xlegq[j] * ulen;
1409 t1 = f2lf + f21 * std::log(t_point) - t_point * ff4;
1412 if (t_point <= 0.0)
continue;
1416 qsqz = q * std::sqrt((xlegq[j] * ulen + twa1) * 0.5);
1418 qsqz = q * std::sqrt((-(xlegq[j] * ulen) + twa1) * 0.5);
1421 double wprb = wprob(qsqz, k);
1422 otsum += (wprb * alegq[j]) * std::exp(t1);
1427 if (
static_cast<double>(i) * ulen >= 1.0 && otsum <= 1e-14) {
1434 return std::max(0.0, std::min(1.0, ans));
1463 throw std::invalid_argument(
"statcpp::studentized_range_quantile: k must be >= 2");
1466 throw std::invalid_argument(
"statcpp::studentized_range_quantile: df must be positive");
1468 if (p < 0.0 || p > 1.0) {
1469 throw std::invalid_argument(
"statcpp::studentized_range_quantile: p must be in [0, 1]");
1471 if (p == 0.0)
return 0.0;
1472 if (p == 1.0)
return std::numeric_limits<double>::infinity();
1476 double x = q0 * (1.0 + 0.2 * (k - 2.0) / std::sqrt(df));
1477 if (!std::isfinite(x) || x < 1.0) x = 1.0;
1480 const double eps = 1e-10;
1481 const int max_iter = 50;
1483 for (
int i = 0; i < max_iter; ++i) {
1484 if (!std::isfinite(x) || x <= 0.0) {
1488 if (std::abs(f) < eps)
return x;
1491 double dx = std::max(1e-6, x * 1e-6);
1494 if (fprime <= 0.0)
break;
1496 double x_new = x - f / fprime;
1497 if (x_new <= 0.0) x_new = x * 0.5;
1499 if (std::abs(x_new - x) < eps * (1.0 + std::abs(x)))
return x_new;
1503 if (!std::isfinite(x) || x <= 0.0) {
double betainc(double a, double b, double x)
Regularized incomplete beta function.
double lognormal_rand(double mu, double sigma, Engine &engine)
Log-normal distribution random number generation.
double t_rand(double df, Engine &engine)
t-distribution random number generation
double gamma_cdf(double x, double shape, double rate=1.0)
Gamma distribution cumulative distribution function (CDF)
double normal_quantile(double p, double mu=0.0, double sigma=1.0)
Normal distribution quantile function (inverse CDF, percent point function)
double chisq_rand(double df, Engine &engine)
Chi-square distribution random number generation.
double lbeta(double a, double b)
Log-beta function.
double studentized_range_cdf(double q, double k, double df)
CDF of the studentized range distribution.
double f_quantile(double p, double df1, double df2)
F-distribution quantile function (Newton-Raphson method)
double gamma_pdf(double x, double shape, double rate=1.0)
Gamma distribution probability density function (PDF)
constexpr double pi
Pi constant.
double chisq_cdf(double x, double df)
Chi-square distribution cumulative distribution function (CDF)
double t_pdf(double x, double df)
t-distribution probability density function (PDF)
double normal_cdf(double x, double mu=0.0, double sigma=1.0)
Normal distribution cumulative distribution function (CDF)
double normal_pdf(double x, double mu=0.0, double sigma=1.0)
Normal distribution probability density function (PDF)
double t_cdf(double x, double df)
t-distribution cumulative distribution function (CDF)
double normal_rand(double mu, double sigma, Engine &engine)
Normal distribution random number generation.
double norm_cdf(double x)
Standard normal CDF.
double weibull_rand(double shape, double scale, Engine &engine)
Weibull distribution random number generation.
double norm_quantile(double p)
Standard normal quantile function.
constexpr double sqrt_2
Square root of 2.
double beta_pdf(double x, double alpha, double beta_param)
Beta distribution probability density function (PDF)
constexpr double sqrt_2_pi
Square root of 2*pi.
double lognormal_cdf(double x, double mu=0.0, double sigma=1.0)
Log-normal distribution cumulative distribution function (CDF)
double gammainc_lower_inv(double a, double p)
Inverse lower regularized incomplete gamma function.
double weibull_pdf(double x, double shape, double scale=1.0)
Weibull distribution probability density function (PDF)
double uniform_rand(double a, double b, Engine &engine)
Uniform distribution random number generation.
double weibull_cdf(double x, double shape, double scale=1.0)
Weibull distribution cumulative distribution function (CDF)
double betaincinv(double a, double b, double p)
Inverse regularized incomplete beta function.
double chisq_pdf(double x, double df)
Chi-square distribution probability density function (PDF)
double exponential_cdf(double x, double lambda=1.0)
Exponential distribution cumulative distribution function (CDF)
double chisq_quantile(double p, double df)
Chi-square distribution quantile function.
double f_pdf(double x, double df1, double df2)
F-distribution probability density function (PDF)
double gammainc_lower(double a, double x)
Lower regularized incomplete gamma function.
double uniform_cdf(double x, double a=0.0, double b=1.0)
Uniform distribution cumulative distribution function (CDF)
double t_quantile(double p, double df)
t-distribution quantile function (Newton-Raphson method)
double gamma_rand(double shape, double rate, Engine &engine)
Gamma distribution random number generation.
double weibull_quantile(double p, double shape, double scale=1.0)
Weibull distribution quantile function.
double lognormal_pdf(double x, double mu=0.0, double sigma=1.0)
Log-normal distribution probability density function (PDF)
double gamma_quantile(double p, double shape, double rate=1.0)
Gamma distribution quantile function.
double beta_cdf(double x, double alpha, double beta_param)
Beta distribution cumulative distribution function (CDF)
default_random_engine & get_random_engine()
Singleton accessor for global random engine.
double exponential_quantile(double p, double lambda=1.0)
Exponential distribution quantile function.
double uniform_quantile(double p, double a=0.0, double b=1.0)
Uniform distribution quantile function (inverse CDF)
double uniform_pdf(double x, double a=0.0, double b=1.0)
Uniform distribution probability density function (PDF)
double f_rand(double df1, double df2, Engine &engine)
F-distribution random number generation.
double beta_rand(double alpha, double beta_param, Engine &engine)
Beta distribution random number generation (using gamma variates)
double exponential_rand(double lambda, Engine &engine)
Exponential distribution random number generation.
double lognormal_quantile(double p, double mu=0.0, double sigma=1.0)
Log-normal distribution quantile function.
double studentized_range_quantile(double p, double k, double df)
Quantile function of the studentized range distribution.
double f_cdf(double x, double df1, double df2)
F-distribution cumulative distribution function (CDF)
double lgamma(double x)
Log-gamma function.
double exponential_pdf(double x, double lambda=1.0)
Exponential distribution probability density function (PDF)
double beta_quantile(double p, double alpha, double beta_param)
Beta distribution quantile function.
Random engine wrapper and utilities.
Special mathematical functions implementation.