LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
fj_xmax_hyperexp.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_HYPEREXP_H
6
#define LINE_API_FJ_XMAX_HYPEREXP_H
7
8
/**
9
* @file
10
* @ingroup api_fj
11
* Expected maximum of K i.i.d. two-phase hyperexponential service times.
12
*
13
* Templated port of matlab/src/api/fj/fj_xmax_hyperexp.m.
14
*
15
* X_K^max = sum_{n=1..K} (-1)^{n+1} sum_{m=0..n}
16
* C(n,m) p1^m p2^{n-m} / (m mu1 + (n-m) mu2)
17
*
18
* from the inclusion-exclusion expansion of 1 - F(x)^K. Every term is
19
* rational, so the sum is exact in the field -- which is the point, because
20
* it alternates: the terms grow like 2^K while the result stays O(log K/mu),
21
* so in double the answer is destroyed by cancellation somewhere around
22
* K = 25 and is pure noise by K = 40.
23
*
24
* REFERENCE DEFECT: FJ_xmax.fj_xmax_hyperexp in
25
* jar/src/main/java/jline/api/fj/FJ_xmax.java drops the p1^m p2^{n-m} factor
26
* from the inner sum, so the JAR computes a different quantity and ignores p1
27
* entirely except in its validation. MATLAB is ground truth and is what this
28
* port follows.
29
*/
30
31
#include "
line/api/fj/fj_types.h
"
32
#include "
line/num/number.h
"
33
#include "
line/util/error.h
"
34
35
namespace
line
{
36
namespace
fj
{
37
38
/**
39
* @brief Expected maximum of K i.i.d. two-phase hyperexponential service
40
* times.
41
*
42
* @param K number of branches, K >= 1
43
* @param p1 probability of the first phase, 0 < p1 < 1
44
* @param mu1 rate of the first phase, > 0
45
* @param mu2 rate of the second phase, > 0
46
* @return expected maximum of K hyperexponential samples
47
*/
48
template
<
class
T>
49
T
fj_xmax_hyperexp
(
unsigned
K,
const
T& p1,
const
T& mu1,
const
T& mu2) {
50
detail::require_positive_K(K,
"fj_xmax_hyperexp"
);
51
const
T zero =
num_traits<T>::from_int
(0), one =
num_traits<T>::from_int
(1);
52
if
(p1 <= zero || p1 >= one)
throw
InputError
(
"fj_xmax_hyperexp: p1 must lie in (0,1)"
);
53
if
(mu1 <= zero || mu2 <= zero)
throw
InputError
(
"fj_xmax_hyperexp: the rates mu1 and mu2 must be positive"
);
54
const
T p2 = one - p1;
55
56
T Xmax = zero;
57
for
(
unsigned
n = 1; n <= K; ++n) {
58
T inner = zero;
59
for
(
unsigned
m = 0; m <= n; ++m) {
60
const
T den =
num_traits<T>::from_int
(
static_cast<
long
>
(m)) * mu1 +
61
num_traits<T>::from_int
(
static_cast<
long
>
(n - m)) * mu2;
62
if
(den > zero)
63
inner += detail::fj_binom<T>(n, m) *
num_pow_int
(p1, m) *
num_pow_int
(p2, n - m) / den;
64
}
65
if
((n + 1) % 2 == 0) Xmax += inner;
66
else
Xmax -= inner;
67
}
68
return
Xmax;
69
}
70
71
}
// namespace fj
72
}
// namespace line
73
74
#endif
// LINE_API_FJ_XMAX_HYPEREXP_H
line::InputError::InputError
InputError(const std::string &what)
Definition
error.h:39
error.h
The exception types the port throws.
fj_types.h
Shared return types and arithmetic helpers for the templated fork-join port.
line::fj
Definition
fj_amva.h:34
line::fj::fj_xmax_hyperexp
T fj_xmax_hyperexp(unsigned K, const T &p1, const T &mu1, const T &mu2)
Expected maximum of K i.i.d.
Definition
fj_xmax_hyperexp.h:49
line
Definition
aoi_dist2ph.h:52
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:192
number.h
Number-type abstraction for the templated API port.
line::num_traits
Definition
number.h:111
include
line
api
fj
fj_xmax_hyperexp.h
Generated by
1.18.0