LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
fj_char_max.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_CHAR_MAX_H
6#define LINE_API_FJ_CHAR_MAX_H
7
8/**
9 * @file
10 * @ingroup api_fj
11 * Gravey's characteristic maximum M_K, an upper bound on the expected maximum
12 * of K i.i.d. random variables.
13 *
14 * Templated port of matlab/src/api/fj/fj_char_max.m, cross-checked against
15 * FJ_char_max.fj_char_max_exp and fj_char_max_erlang in
16 * jar/src/main/java/jline/api/fj/FJ_char_max.java (identical; the JAR splits
17 * the MATLAB dist_type switch into two entry points, which this port mirrors
18 * as two overloads).
19 *
20 * m_K is the greatest lower bound with P(X > m_K) <= 1/K, and
21 * M_K = m_K + K int_{m_K}^inf P(X > x) dx.
22 *
23 * exponential: m_K = ln(K)/mu, M_K = H_K/mu (the bound is tight here)
24 * Erlang-k: m_K solves exp(-mu m) sum_{i<k} (mu m)^i/i! = 1/K,
25 * M_K = (k/mu)[1 + K exp(-mu m_K) (mu m_K)^k / k!]
26 *
27 * static_assert(num_traits<T>::has_transcendental) -- a log in the
28 * exponential case and a bracketed root of a transcendental equation in the
29 * Erlang one.
30 *
31 * The MATLAB 'general' mode, which takes an arbitrary survival function
32 * handle and integrates its tail to infinity by adaptive quadrature after a
33 * doubling search for the truncation point, is NOT ported: the truncation
34 * search has no termination guarantee for a heavy tail and the JAR omits it
35 * too. Callers with a specific tail should use fj_order_stat.
36 */
37
41#include "line/num/number.h"
42#include "line/util/error.h"
43
44namespace line {
45namespace fj {
46
47/**
48 * Exponential branch.
49 *
50 * @param K number of samples, K >= 1
51 * @param mu rate, > 0
52 * @return [MK, mK]
53 */
54template <class T>
55FJCharMaxResult<T> fj_char_max(unsigned K, const T& mu) {
57 "fj_char_max requires transcendental arithmetic");
58 detail::require_positive_K(K, "fj_char_max");
59 if (mu <= num_traits<T>::from_int(0)) throw InputError("fj_char_max: the rate mu must be positive");
60 const T Kt = num_traits<T>::from_int(static_cast<long>(K));
61 return {T(fj_harmonic<T>(K) / mu), T(detail::num_log(Kt) / mu)};
62}
63
64/**
65 * Erlang-k branch.
66 *
67 * @param K number of samples, K >= 1
68 * @param k Erlang stages, k >= 1
69 * @param mu per-stage rate, > 0
70 * @return [MK, mK]
71 */
72template <class T>
73FJCharMaxResult<T> fj_char_max(unsigned K, unsigned k, const T& mu) {
75 "fj_char_max requires transcendental arithmetic");
76 detail::require_positive_K(K, "fj_char_max");
77 if (k < 1) throw InputError("fj_char_max: the Erlang stage count k must be positive");
78 if (mu <= num_traits<T>::from_int(0)) throw InputError("fj_char_max: the rate mu must be positive");
79
80 const T one = num_traits<T>::from_int(1);
81 const T Kt = num_traits<T>::from_int(static_cast<long>(K));
82 const T kt = num_traits<T>::from_int(static_cast<long>(k));
83 const T target = one / Kt;
84
85 T hi = kt / mu + detail::num_log(Kt) / mu;
86 if (hi <= num_traits<T>::from_int(0)) hi = kt / mu;
87 while (detail::erlang_survival(hi, k, mu) > target) hi *= num_traits<T>::from_int(2);
88 const T mK = detail::bisect<T>(
89 [&](const T& x) { return T(detail::erlang_survival(x, k, mu) - target); },
90 num_traits<T>::from_int(0), hi, "fj_char_max");
91
92 const T MK = (kt / mu) * (one + Kt * detail::num_exp(T(-mu * mK)) * num_pow_int(T(mu * mK), k) /
94 return {MK, mK};
95}
96
97} // namespace fj
98} // namespace line
99
100#endif // LINE_API_FJ_CHAR_MAX_H
InputError(const std::string &what)
Definition error.h:39
The exception types the port throws.
Harmonic number H_K = sum_{k=1..K} 1/k.
Shared return types and arithmetic helpers for the templated fork-join port.
Expected maximum of K i.i.d.
FJCharMaxResult< T > fj_char_max(unsigned K, const T &mu)
Exponential branch.
Definition fj_char_max.h:55
T fj_harmonic(unsigned K)
Harmonic number H_K = sum_{k=1..K} 1/k.
Definition fj_harmonic.h:37
Conservation laws of a layered queueing network, enumerated from its structure.
Definition aoi_dist2ph.h:52
T num_factorial(unsigned n)
Factorial as a value of T.
Definition number.h:210
T num_pow_int(const T &base, unsigned e)
Integer power, valid in any field (no transcendental requirement).
Definition number.h:218
Number-type abstraction for the templated API port.
[MK, mK] of fj_char_max: characteristic maximum and its threshold.
Definition fj_types.h:55