LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
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
38
#include "
line/api/fj/fj_harmonic.h
"
39
#include "
line/api/fj/fj_types.h
"
40
#include "
line/api/fj/fj_xmax_erlang.h
"
41
#include "
line/num/number.h
"
42
#include "
line/util/error.h
"
43
44
namespace
line
{
45
namespace
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
*/
54
template
<
class
T>
55
FJCharMaxResult<T>
fj_char_max
(
unsigned
K,
const
T& mu) {
56
static_assert
(
num_traits<T>::has_transcendental
,
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
*/
72
template
<
class
T>
73
FJCharMaxResult<T>
fj_char_max
(
unsigned
K,
unsigned
k,
const
T& mu) {
74
static_assert
(
num_traits<T>::has_transcendental
,
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) /
93
num_factorial<T>
(k));
94
return
{MK, mK};
95
}
96
97
}
// namespace fj
98
}
// namespace line
99
100
#endif
// LINE_API_FJ_CHAR_MAX_H
line::InputError::InputError
InputError(const std::string &what)
Definition
error.h:39
error.h
The exception types the port throws.
fj_harmonic.h
Harmonic number H_K = sum_{k=1..K} 1/k.
fj_types.h
Shared return types and arithmetic helpers for the templated fork-join port.
fj_xmax_erlang.h
Expected maximum of K i.i.d.
line::fj
Definition
fj_amva.h:34
line::fj::fj_char_max
FJCharMaxResult< T > fj_char_max(unsigned K, const T &mu)
Exponential branch.
Definition
fj_char_max.h:55
line::fj::fj_harmonic
T fj_harmonic(unsigned K)
Harmonic number H_K = sum_{k=1..K} 1/k.
Definition
fj_harmonic.h:37
line
Conservation laws of a layered queueing network, enumerated from its structure.
Definition
aoi_dist2ph.h:52
line::num_factorial
T num_factorial(unsigned n)
Factorial as a value of T.
Definition
number.h:210
line::num_pow_int
T num_pow_int(const T &base, unsigned e)
Integer power, valid in any field (no transcendental requirement).
Definition
number.h:218
number.h
Number-type abstraction for the templated API port.
line::fj::FJCharMaxResult
[MK, mK] of fj_char_max: characteristic maximum and its threshold.
Definition
fj_types.h:55
line::num_traits
Definition
number.h:137
include
line
api
fj
fj_char_max.h
Generated by
1.18.0