LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
fj_xmax_coxian.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_COXIAN_H
6
#define LINE_API_FJ_XMAX_COXIAN_H
7
8
/**
9
* @file
10
* @ingroup api_fj
11
* Expected maximum of K i.i.d. two-stage Coxian variables.
12
*
13
* Templated port of matlab/src/api/fj/fj_xmax_coxian.m.
14
*
15
* With X = T1 + B T2, T1 ~ Exp(mu1), T2 ~ Exp(mu2) and B ~ Bernoulli(q), the
16
* survival function is a two-term exponential mixture
17
*
18
* S(t) = A exp(-mu1 t) + B exp(-mu2 t),
19
* A = (1-q) + q mu2/(mu2-mu1), B = -q mu1/(mu2-mu1),
20
*
21
* so expanding 1 - (1-S)^K binomially and integrating term by term gives
22
*
23
* E[Y_K] = sum_{j=1..K} (-1)^(j+1) C(K,j)
24
* sum_{i=0..j} C(j,i) A^(j-i) B^i / ((j-i) mu1 + i mu2).
25
*
26
* At coincident stage rates the mixture degenerates into
27
* S(t) = (1 + q mu t) exp(-mu t) and the same expansion is carried out with
28
* integral t^m exp(-j mu t) dt = m!/(j mu)^(m+1), which is selected
29
* automatically.
30
*/
31
32
#include "
line/api/fj/fj_types.h
"
33
#include "
line/num/number.h
"
34
#include "
line/util/error.h
"
35
36
namespace
line
{
37
namespace
fj
{
38
39
/** [Xmax, m1, c2] of fj_xmax_coxian. */
40
template
<
class
T>
41
struct
FJXmaxCoxianResult
{
42
T
Xmax
;
43
T
m1
;
44
T
c2
;
45
};
46
47
/**
48
* @brief Expected maximum of K i.i.d. two-stage Coxian variables.
49
*
50
* @param K number of branches, K >= 1
51
* @param mu1 rate of the first stage
52
* @param mu2 rate of the second stage
53
* @param q probability that the second stage is visited, in [0,1]
54
* @return the exact expected maximum with the branch mean and SCV
55
*/
56
template
<
class
T>
57
FJXmaxCoxianResult<T>
fj_xmax_coxian
(
unsigned
K,
const
T& mu1,
const
T& mu2,
const
T& q) {
58
detail::require_positive_K(K,
"fj_xmax_coxian"
);
59
const
T zero =
num_traits<T>::from_int
(0), one =
num_traits<T>::from_int
(1),
60
two =
num_traits<T>::from_int
(2);
61
if
(!(mu1 > zero) || !(mu2 > zero))
62
throw
InputError
(
"fj_xmax_coxian: both stage rates must be positive"
);
63
if
(q < zero || q > one)
64
throw
InputError
(
"fj_xmax_coxian: the branching probability must lie in [0,1]"
);
65
if
(K > 60)
throw
InputError
(
"fj_xmax_coxian: the binomial expansion loses precision past K=60"
);
66
67
FJXmaxCoxianResult<T>
out;
68
out.
m1
= one / mu1 + q / mu2;
69
const
T var1 = one / (mu1 * mu1) + q * (two - q) / (mu2 * mu2);
70
out.
c2
= var1 / (out.
m1
* out.
m1
);
71
72
T acc = zero;
73
const
double
gap =
num_traits<T>::to_double
(mu2 - mu1);
74
const
double
scale =
num_traits<T>::to_double
(mu1 > mu2 ? mu1 : mu2);
75
if
((gap > 0 ? gap : -gap) > 1e-12 * scale) {
76
const
T A = (one - q) + q * mu2 / (mu2 - mu1);
77
const
T B = -q * mu1 / (mu2 - mu1);
78
for
(
unsigned
j = 1; j <= K; ++j) {
79
T inner = zero;
80
for
(
unsigned
i = 0; i <= j; ++i) {
81
const
T rate =
num_traits<T>::from_int
(
static_cast<
long
>
(j - i)) * mu1 +
82
num_traits<T>::from_int
(
static_cast<
long
>
(i)) * mu2;
83
T Apw = one, Bpw = one;
84
for
(
unsigned
e = 0; e < j - i; ++e) Apw *= A;
85
for
(
unsigned
e = 0; e < i; ++e) Bpw *= B;
86
inner += detail::fj_binom<T>(j, i) * Apw * Bpw / rate;
87
}
88
const
T term = detail::fj_binom<T>(K, j) * inner;
89
if
(j % 2 == 1) acc += term;
else
acc -= term;
90
}
91
}
else
{
92
// Coincident stage rates: S(t) = (1 + q mu t) exp(-mu t)
93
const
T mu = mu1;
94
for
(
unsigned
j = 1; j <= K; ++j) {
95
T inner = zero;
96
const
T jmu =
num_traits<T>::from_int
(
static_cast<
long
>
(j)) * mu;
97
for
(
unsigned
i = 0; i <= j; ++i) {
98
T num = one, den = one, fact = one;
99
for
(
unsigned
e = 0; e < i; ++e) num *= q * mu;
100
for
(
unsigned
e = 2; e <= i; ++e) fact *= num_traits<T>::from_int(
static_cast<
long
>
(e));
101
for
(
unsigned
e = 0; e <= i; ++e) den *= jmu;
102
inner += detail::fj_binom<T>(j, i) * num * fact / den;
103
}
104
const
T term = detail::fj_binom<T>(K, j) * inner;
105
if
(j % 2 == 1) acc += term;
else
acc -= term;
106
}
107
}
108
out.
Xmax
= acc;
109
return
out;
110
}
111
112
}
// namespace fj
113
}
// namespace line
114
115
#endif
// LINE_API_FJ_XMAX_COXIAN_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_coxian
FJXmaxCoxianResult< T > fj_xmax_coxian(unsigned K, const T &mu1, const T &mu2, const T &q)
Expected maximum of K i.i.d.
Definition
fj_xmax_coxian.h:57
line
Definition
aoi_dist2ph.h:52
number.h
Number-type abstraction for the templated API port.
line::fj::FJXmaxCoxianResult
[Xmax, m1, c2] of fj_xmax_coxian.
Definition
fj_xmax_coxian.h:41
line::fj::FJXmaxCoxianResult::m1
T m1
Definition
fj_xmax_coxian.h:43
line::fj::FJXmaxCoxianResult::c2
T c2
Definition
fj_xmax_coxian.h:44
line::fj::FJXmaxCoxianResult::Xmax
T Xmax
Definition
fj_xmax_coxian.h:42
line::num_traits
Definition
number.h:111
include
line
api
fj
fj_xmax_coxian.h
Generated by
1.18.0