LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
fj_xmax_pareto.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_XMAX_PARETO_H
6#define LINE_API_FJ_XMAX_PARETO_H
7
8/**
9 * @file
10 * @ingroup api_fj
11 * Expected maximum and characteristic maximum of K i.i.d. shifted-Pareto
12 * samples with survival S(x) = (k/(k+x))^beta.
13 *
14 * Templated port of matlab/src/api/fj/fj_xmax_pareto.m, cross-checked against
15 * FJ_xmax.fj_xmax_pareto and fj_xmax_pareto_char_max in
16 * jar/src/main/java/jline/api/fj/FJ_xmax.java (identical formulas; the JAR
17 * replaces MATLAB's adaptive `integral` with a 10001-point composite Simpson
18 * rule on the same truncated range, which this port also does).
19 *
20 * Xmax = int_0^inf [1 - F(x)^K] dx, truncated at k K^{2/beta} * 10
21 * m_K = k (K^{1/beta} - 1)
22 * M_K = m_K + K k^beta (k + m_K)^{1-beta} / (beta - 1)
23 *
24 * static_assert(num_traits<T>::has_transcendental) -- real powers throughout
25 * plus the quadrature. Worth flagging: the truncation point is a heuristic and
26 * the Pareto tail is heavy, so Xmax is systematically underestimated; the
27 * shortfall grows as beta approaches 2 and the function rejects beta <= 2
28 * outright because the mean of the maximum is then the only finite moment
29 * left. M_K, by contrast, is a closed form and is exact.
30 */
31
33#include "line/num/number.h"
34#include "line/util/error.h"
35
36namespace line {
37namespace fj {
38
39/**
40 * @brief Expected maximum and characteristic maximum of K i.i.d.
41 * shifted-Pareto samples with survival S(x) = (k/(k+x))^beta.
42 *
43 * @param K number of samples, K >= 1
44 * @param beta Pareto shape, must exceed 2 for finite moments
45 * @param k Pareto scale, > 0 (MATLAB defaults it to beta - 1, the value
46 * that makes the branch mean equal to 1)
47 * @return [Xmax, MK]
48 */
49template <class T>
50FJXmaxParetoResult<T> fj_xmax_pareto(unsigned K, const T& beta, const T& k) {
52 "fj_xmax_pareto requires transcendental arithmetic");
53 detail::require_positive_K(K, "fj_xmax_pareto");
54 const T zero = num_traits<T>::from_int(0), one = num_traits<T>::from_int(1);
55 if (beta <= num_traits<T>::from_int(2))
56 throw InputError("fj_xmax_pareto: the shape beta must exceed 2 for finite moments");
57 if (k <= zero) throw InputError("fj_xmax_pareto: the scale k must be positive");
58
59 const T Kt = num_traits<T>::from_int(static_cast<long>(K));
60 const T upper = k * detail::num_pow(Kt, T(num_traits<T>::from_int(2) / beta)) * num_traits<T>::from_int(10);
61 const T Xmax = detail::simpson<T>(
62 [&](const T& x) {
63 const T xx = x > zero ? x : zero;
64 const T F = one - detail::num_pow(T(k / (k + xx)), beta);
65 return T(one - num_pow_int(F, K));
66 },
67 zero, upper);
68
69 const T mK = k * (detail::num_pow(Kt, T(one / beta)) - one);
70 const T tail = detail::num_pow(k, beta) * detail::num_pow(T(k + mK), T(one - beta)) / (beta - one);
71 return {Xmax, T(mK + Kt * tail)};
72}
73
74/** MATLAB's default scale k = beta - 1, which normalizes the branch mean to 1. */
75template <class T>
76FJXmaxParetoResult<T> fj_xmax_pareto(unsigned K, const T& beta) {
77 return fj_xmax_pareto(K, beta, T(beta - num_traits<T>::from_int(1)));
78}
79
80} // namespace fj
81} // namespace line
82
83#endif // LINE_API_FJ_XMAX_PARETO_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.
FJXmaxParetoResult< T > fj_xmax_pareto(unsigned K, const T &beta, const T &k)
Expected maximum and characteristic maximum 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.
[Xmax, MK] of fj_xmax_pareto.
Definition fj_types.h:86