LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
fj_order_stat.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_ORDER_STAT_H
6#define LINE_API_FJ_ORDER_STAT_H
7
8/**
9 * @file
10 * @ingroup api_fj
11 * CDF and expected value of the k-th order statistic of K i.i.d. samples.
12 *
13 * Templated port of matlab/src/api/fj/fj_order_stat.m. The JAR carries the
14 * same CDF in jline.api.fj.FJ_order_stat (identical).
15 *
16 * F_{Y_k}(y) = sum_{j=k..K} C(K,j) F(y)^j (1 - F(y))^{K-j}
17 * F_{Y_K}(y) = F(y)^K (the maximum)
18 *
19 * MIXED ARITHMETIC. The CDF is a polynomial in the value of the base CDF, so
20 * it is exact in any field once F(y) is known -- and it satisfies the exact
21 * identity sum_{k=1..K} F_{Y_k} = K F, plus F_{Y_1} = 1 - (1-F)^K, both of
22 * which are bit-exact only in rational arithmetic.
23 *
24 * The expected value is a quadrature. For k = 1 and k = K it integrates the
25 * survival function directly; for an interior k the MATLAB file differentiates
26 * the supplied CDF by a central difference with a fixed step 1e-8, which is a
27 * tolerance-driven approximation. Both are therefore produced only when T
28 * carries transcendental functions, and mean_available reports which branch
29 * ran. The truncation point follows MATLAB: double from 1 until F(u) >= 1-1e-6,
30 * at most 100 times.
31 */
32
33#include <functional>
34
36#include "line/num/number.h"
37#include "line/util/error.h"
38
39namespace line {
40namespace fj {
41
42/**
43 * @brief CDF and expected value of the k-th order statistic of K i.i.d.
44 * samples.
45 *
46 * @param y evaluation point of the CDF
47 * @param k order of the statistic, 1 = minimum, K = maximum
48 * @param K number of samples
49 * @param F_X CDF of the branch distribution
50 * @return [F_Yk, E_Yk, mean_available]
51 */
52template <class T>
53FJOrderStatResult<T> fj_order_stat(const T& y, unsigned k, unsigned K,
54 const std::function<T(const T&)>& F_X) {
55 if (k < 1 || k > K) throw InputError("fj_order_stat: k must satisfy 1 <= k <= K");
56 if (!F_X) throw InputError("fj_order_stat: the CDF must be callable");
57 const T zero = num_traits<T>::from_int(0), one = num_traits<T>::from_int(1);
58
59 const T F_y = F_X(y);
60 T F_Yk = zero;
61 if (k == K) {
62 F_Yk = num_pow_int(F_y, K);
63 } else {
64 for (unsigned j = k; j <= K; ++j)
65 F_Yk += detail::fj_binom<T>(K, j) * num_pow_int(F_y, j) * num_pow_int(T(one - F_y), K - j);
66 }
67
69 // Truncation point: double from 1 until the CDF is essentially 1.
70 const T target = one - num_traits<T>::from_double(1e-6);
71 T upper = one;
72 for (unsigned it = 0; it < 100 && F_X(upper) < target; ++it) upper *= num_traits<T>::from_int(2);
73
74 T E_Yk = zero;
75 if (k == K) {
76 E_Yk = detail::simpson<T>([&](const T& t) { return T(one - num_pow_int(F_X(t), K)); }, zero, upper);
77 } else if (k == 1) {
78 E_Yk = detail::simpson<T>([&](const T& t) { return num_pow_int(T(one - F_X(t)), K); }, zero, upper);
79 } else {
80 const T eps = num_traits<T>::from_double(1e-8);
81 const T coeff = num_traits<T>::from_int(static_cast<long>(K)) * detail::fj_binom<T>(K - 1, k - 1);
82 E_Yk = detail::simpson<T>(
83 [&](const T& t) {
84 const T f = (F_X(T(t + eps)) - F_X(T(t - eps))) / (num_traits<T>::from_int(2) * eps);
85 const T Ft = F_X(t);
86 return T(t * coeff * f * num_pow_int(Ft, k - 1) * num_pow_int(T(one - Ft), K - k));
87 },
88 zero, upper);
89 }
90 return {F_Yk, E_Yk, true};
91 } else {
92 return {F_Yk, zero, false};
93 }
94}
95
96} // namespace fj
97} // namespace line
98
99#endif // LINE_API_FJ_ORDER_STAT_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.
FJOrderStatResult< T > fj_order_stat(const T &y, unsigned k, unsigned K, const std::function< T(const T &)> &F_X)
CDF and expected value of the k-th order statistic of K i.i.d.
T num_pow_int(const T &base, unsigned e)
Integer power, valid in any field (no transcendental requirement).
Definition number.h:192
Number-type abstraction for the templated API port.
[F_Yk, E_Yk] of fj_order_stat.
Definition fj_types.h:99