LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
pfqn_mcub.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_PFQN_PFQN_MCUB_H
6
#define LINE_API_PFQN_PFQN_MCUB_H
7
8
/**
9
* @file
10
* @ingroup api_pfqn
11
* Kerola's multiclass composite bound (Perf. Eval. 6:1-9, eqs. 10-16) on the
12
* per-class throughput of a closed product-form network.
13
*
14
* Templated port of matlab/src/api/pfqn/pfqn_mcub.m. The multiclass Balanced
15
* Job Bound gives the per-class lower bound
16
*
17
* X_r^- = N_r / (sum_k L_kr + Z_r + (Ntot - 1) max_k L_kr)
18
*
19
* and the residual-utilization argument then gives the composite upper bound
20
*
21
* X_r^+ = min_k [1 - sum_{s != r} X_s^- L_ks] / L_kr
22
*
23
* at O(MR). Despite the name it has nothing to do with pfqn_cub, which is the
24
* Grundmann-Moeller cubature normalizing constant.
25
*
26
* ARITHMETIC. Sums, products, maxima and divisions only, so the bound is EXACT
27
* in rational arithmetic and is deliberately left ungated.
28
*/
29
30
#include <cstddef>
31
#include <vector>
32
33
#include "
line/num/number.h
"
34
#include "
line/util/error.h
"
35
#include "
line/util/matrix.h
"
36
37
namespace
line
{
38
namespace
pfqn
{
39
40
/** Return value of pfqn_mcub, mirroring [Xub, Xlb]. */
41
template
<
class
T>
42
struct
McubBounds
{
43
std::vector<T>
Xub
;
44
std::vector<T>
Xlb
;
45
};
46
47
/**
48
* @brief Kerola's multiclass composite bound (Perf. Eval. 6:1-9, eqs. 10-16)
49
* on the per-class throughput of a closed product-form network.
50
*
51
* @param L (M x R) demands, @param N (R) population, @param Z (R) think times
52
* (empty for zero think time)
53
*/
54
template
<
class
T>
55
McubBounds<T>
pfqn_mcub
(
const
Matrix<T>
& L,
const
std::vector<T>& N,
const
std::vector<T>& Z) {
56
const
std::size_t M = L.
rows
(), R = L.
cols
();
57
if
(N.size() != R)
throw
InputError
(
"pfqn_mcub: L and N disagree on the class count"
);
58
if
(!Z.empty() && Z.size() != R)
throw
InputError
(
"pfqn_mcub: Z has the wrong length"
);
59
const
T zero =
num_traits<T>::from_int
(0), one =
num_traits<T>::from_int
(1);
60
T Ntot = zero;
61
for
(
const
T& v : N) Ntot += v;
62
63
McubBounds<T>
r;
64
r.
Xlb
.assign(R, zero);
65
r.
Xub
.assign(R, zero);
66
for
(std::size_t s = 0; s < R; ++s) {
67
T R0 = zero, Lb = zero;
68
for
(std::size_t k = 0; k < M; ++k) {
69
R0 += L(k, s);
70
if
(L(k, s) > Lb) Lb = L(k, s);
71
}
72
const
T zr = Z.empty() ? zero : Z[s];
73
const
T den = T(R0 + zr + T(Ntot - one) * Lb);
74
if
(den == zero)
throw
NumericError
(
"pfqn_mcub: zero cycle time in the balanced job bound"
);
75
r.
Xlb
[s] = T(N[s] / den);
76
}
77
78
for
(std::size_t s = 0; s < R; ++s) {
79
bool
any =
false
;
80
T best = zero;
81
for
(std::size_t k = 0; k < M; ++k) {
82
if
(!(L(k, s) > zero))
continue
;
// MATLAB leaves the device at Inf
83
T Uoth = zero;
84
for
(std::size_t t = 0; t < R; ++t)
85
if
(t != s) Uoth += r.
Xlb
[t] * L(k, t);
86
const
T dev = T(T(one - Uoth) / L(k, s));
87
if
(!any || dev < best) {
88
best = dev;
89
any =
true
;
90
}
91
}
92
// MATLAB's min over an all-Inf device vector is Inf; a class with no
93
// demand anywhere is unconstrained, which the caller must handle.
94
if
(!any)
throw
InputError
(
"pfqn_mcub: a class has zero demand at every station"
);
95
r.
Xub
[s] = best;
96
}
97
return
r;
98
}
99
100
template
<
class
T>
101
McubBounds<T>
pfqn_mcub
(
const
Matrix<T>
& L,
const
std::vector<T>& N) {
102
return
pfqn_mcub
(L, N, std::vector<T>());
103
}
104
105
}
// namespace pfqn
106
}
// namespace line
107
108
#endif
// LINE_API_PFQN_PFQN_MCUB_H
line::InputError::InputError
InputError(const std::string &what)
Definition
error.h:39
line::Matrix
Definition
matrix.h:56
line::Matrix::cols
std::size_t cols() const
Definition
matrix.h:90
line::Matrix::rows
std::size_t rows() const
Definition
matrix.h:89
line::NumericError::NumericError
NumericError(const std::string &what)
Definition
error.h:45
error.h
The exception types the port throws.
matrix.h
Dense matrix and non-owning view.
line::pfqn
Definition
cd_peak_scaling.h:43
line::pfqn::pfqn_mcub
McubBounds< T > pfqn_mcub(const Matrix< T > &L, const std::vector< T > &N, const std::vector< T > &Z)
Kerola's multiclass composite bound (Perf.
Definition
pfqn_mcub.h:55
line
Definition
aoi_dist2ph.h:52
number.h
Number-type abstraction for the templated API port.
line::num_traits
Definition
number.h:111
line::pfqn::McubBounds
Return value of pfqn_mcub, mirroring [Xub, Xlb].
Definition
pfqn_mcub.h:42
line::pfqn::McubBounds::Xlb
std::vector< T > Xlb
Definition
pfqn_mcub.h:44
line::pfqn::McubBounds::Xub
std::vector< T > Xub
Definition
pfqn_mcub.h:43
include
line
api
pfqn
pfqn_mcub.h
Generated by
1.18.0