LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
fj_quantile.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_API_FJ_QUANTILE_H
6#define LINE_API_FJ_QUANTILE_H
7
8/**
9 * @file
10 * @ingroup api_fj
11 * Quantile of the maximum of K i.i.d. samples.
12 *
13 * Templated port of matlab/src/api/fj/fj_quantile.m, cross-checked against
14 * jar/src/main/java/jline/api/fj/FJ_quantile.java (identical).
15 *
16 * Gumbel approximation: x(K,q) = ln K - ln ln(1/q)
17 * exact, given F^-1: x(K,q) = F^{-1}(q^{1/K})
18 *
19 * static_assert(num_traits<T>::has_transcendental) -- a log in the first form
20 * and a real root in the second. The Gumbel form is documented as inaccurate
21 * at small K and is not a bound in either direction, so it should not be used
22 * to certify a service-level target.
23 */
24
25#include <functional>
26
28#include "line/num/number.h"
29#include "line/util/error.h"
30
31namespace line {
32namespace fj {
33
34/**
35 * Gumbel approximation.
36 *
37 * @param K number of samples, K >= 1
38 * @param q quantile level, 0 < q < 1
39 */
40template <class T>
41T fj_quantile(unsigned K, const T& q) {
43 "fj_quantile requires transcendental arithmetic");
44 detail::require_positive_K(K, "fj_quantile");
45 const T zero = num_traits<T>::from_int(0), one = num_traits<T>::from_int(1);
46 if (q <= zero || q >= one) throw InputError("fj_quantile: q must satisfy 0 < q < 1");
47 const T Kt = num_traits<T>::from_int(static_cast<long>(K));
48 return detail::num_log(Kt) - detail::num_log(T(detail::num_log(T(one / q))));
49}
50
51/**
52 * Exact quantile through the supplied inverse CDF.
53 *
54 * @param K number of samples, K >= 1
55 * @param q quantile level, 0 < q < 1
56 * @param Finv inverse CDF of the branch distribution
57 */
58template <class T>
59T fj_quantile(unsigned K, const T& q, const std::function<T(const T&)>& Finv) {
61 "fj_quantile requires transcendental arithmetic");
62 detail::require_positive_K(K, "fj_quantile");
63 const T zero = num_traits<T>::from_int(0), one = num_traits<T>::from_int(1);
64 if (q <= zero || q >= one) throw InputError("fj_quantile: q must satisfy 0 < q < 1");
65 if (!Finv) throw InputError("fj_quantile: the inverse CDF must be callable");
66 return Finv(T(detail::num_pow(q, T(one / num_traits<T>::from_int(static_cast<long>(K))))));
67}
68
69} // namespace fj
70} // namespace line
71
72#endif // LINE_API_FJ_QUANTILE_H
InputError(const std::string &what)
Definition error.h:39
The exception types the port throws.
Shared return types and arithmetic helpers for the templated fork-join port.
T fj_quantile(unsigned K, const T &q)
Gumbel approximation.
Definition fj_quantile.h:41
Number-type abstraction for the templated API port.