LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
pfqn_mva_interval.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_MVA_INTERVAL_H
6
#define LINE_API_PFQN_PFQN_MVA_INTERVAL_H
7
8
/**
9
* @file
10
* @ingroup api_pfqn
11
* Exact interval-valued MVA for single-class closed product-form networks.
12
*
13
* Port of `matlab/src/api/pfqn/pfqn_mva_interval.m`, the algorithm of J. Luthi
14
* and G. Haring, "Mean value analysis for queueing network models with
15
* intervals as input parameters", Performance Evaluation 32(3):185-215, 1998.
16
*
17
* WHY CORNERS AND NOT INTERVAL ARITHMETIC. Single-class MVA is monotone in
18
* every input -- the throughput decreases in each demand and in the think time
19
* and increases in the population, a station's own queue length and residence
20
* time increase in its own demand and in the population and decrease in the
21
* other demands and in the think time, and the totals increase in every demand
22
* and in the population and decrease in the think time (their Theorems 2-5,
23
* Table 1). By their Theorem 1 the exact range of a function monotone in each
24
* argument is attained AT A CORNER of the input box, so every bound below is
25
* one ordinary MVA call at the corner the sign pattern selects: 2*(m+2) calls,
26
* m being the number of thick demand intervals. Running the recursion in
27
* interval arithmetic instead is valid but far wider, because every input
28
* recurs at each step -- the dependency problem, 14x too wide on the paper's
29
* own example.
30
*
31
* WHAT THE INTERVAL IS, AND WHAT IT IS NOT. It is the exact hull of MVA over
32
* the input box, conditional on the demands lying in that box; it says nothing
33
* about the accuracy of MVA itself. It must therefore NOT be composed with the
34
* brackets of SolverBA, which bracket the exact solution of a model whose
35
* demands are known. The two answer different questions and intersecting them
36
* would claim a guarantee neither provides.
37
*
38
* Delay stations are folded into Z exactly as `pfqn_mva` folds them: a delay
39
* demand interval enters as a term of the think-time interval, and the hull of
40
* the sum is the sum of the hulls when the delays vary independently.
41
* Load-independent single-server queueing stations only, one class only; the
42
* monotonicity theorems cover no other case.
43
*/
44
45
#include <algorithm>
46
#include <cstddef>
47
#include <vector>
48
49
#include "
line/api/pfqn/pfqn_mva.h
"
50
#include "
line/lang/lang_types.h
"
51
#include "
line/num/number.h
"
52
#include "
line/util/error.h
"
53
#include "
line/util/matrix.h
"
54
55
namespace
line
{
56
namespace
pfqn
{
57
58
/** Every output of `pfqn_mva_interval`, each a [lower, upper] pair. */
59
template
<
class
T>
60
struct
MvaIntervalResult
{
61
T
Xlo
,
Xup
;
///< throughput interval
62
Matrix<T>
Q
;
///< (M x 2) mean queue length per station
63
Matrix<T>
U
;
///< (M x 2) utilization enclosure per station
64
Matrix<T>
R
;
///< (M x 2) residence time per station
65
T
Rtot_lo
,
Rtot_up
;
///< total response time
66
T
Qtot_lo
,
Qtot_up
;
///< total number of jobs at the stations
67
};
68
69
/**
70
* @brief Exact interval-valued MVA for single-class closed product-form
71
* networks.
72
*
73
* @param L (M x 2) demand intervals, column 0 lower and column 1 upper.
74
* @param nlo lower population endpoint (integer, at least 1).
75
* @param nup upper population endpoint.
76
* @param zlo lower think-time endpoint.
77
* @param zup upper think-time endpoint.
78
*/
79
template
<
class
T>
80
MvaIntervalResult<T>
pfqn_mva_interval
(
const
Matrix<T>
& L,
int
nlo,
int
nup,
const
T& zlo,
81
const
T& zup) {
82
const
T zero =
num_traits<T>::from_int
(0), one =
num_traits<T>::from_int
(1);
83
if
(L.
empty
())
throw
InputError
(
"pfqn_mva_interval requires at least one queueing station"
);
84
if
(L.
cols
() != 2)
85
throw
InputError
(
86
"pfqn_mva_interval is a single-class method: L must be M x 2, one [lower upper] demand "
87
"interval per station"
);
88
const
std::size_t M = L.
rows
();
89
for
(std::size_t i = 0; i < M; ++i) {
90
if
(L(i, 0) < zero || L(i, 1) < zero)
91
throw
InputError
(
"pfqn_mva_interval: demands must be nonnegative"
);
92
if
(L(i, 0) > L(i, 1))
93
throw
InputError
(
94
"pfqn_mva_interval: an interval lower endpoint exceeds its upper endpoint"
);
95
}
96
if
(zlo < zero || zup < zero)
97
throw
InputError
(
"pfqn_mva_interval: think times must be nonnegative"
);
98
if
(zlo > zup)
99
throw
InputError
(
"pfqn_mva_interval: the think-time interval is inverted"
);
100
if
(nlo > nup)
throw
InputError
(
"pfqn_mva_interval: the population interval is inverted"
);
101
if
(nlo < 1)
102
throw
InputError
(
103
"pfqn_mva_interval requires a population interval with at least one job; the "
104
"monotonicity theorems assume n >= 1"
);
105
106
const
T tiny =
num_traits<T>::from_double
(
lang::GlobalConstants::Zero
);
107
std::vector<bool> thick(M,
false
);
108
Matrix<T>
Llo(M, 1, zero), Lup(M, 1, zero);
109
for
(std::size_t i = 0; i < M; ++i) {
110
Llo(i, 0) = L(i, 0);
111
Lup(i, 0) = L(i, 1);
112
thick[i] = L(i, 1) > T(L(i, 0) + tiny);
113
}
114
115
auto
call = [&](
const
Matrix<T>
& d,
int
n,
const
T& z) {
116
return
pfqn_mva
(d, std::vector<int>(1, n),
Matrix<T>
(1, 1, z));
117
};
118
119
MvaIntervalResult<T>
out;
120
out.
Q
=
Matrix<T>
(M, 2, zero);
121
out.
U
=
Matrix<T>
(M, 2, zero);
122
out.
R
=
Matrix<T>
(M, 2, zero);
123
124
// S1: the throughput upper bound, and the upper bounds of the stations whose
125
// demand is thin -- their own demand is fixed, so lowering the others
126
// maximizes them.
127
const
MvaResult<T>
s1 = call(Llo, nup, zlo);
128
out.
Xup
= s1.
XN
[0];
129
// S2: the same quantities at the opposite corner, giving the lower bounds.
130
const
MvaResult<T>
s2 = call(Lup, nlo, zup);
131
out.
Xlo
= s2.
XN
[0];
132
for
(std::size_t i = 0; i < M; ++i) {
133
if
(thick[i])
continue
;
134
out.
Q
(i, 1) = s1.
QN
(i, 0);
135
out.
R
(i, 1) = s1.
CN
(i, 0);
136
out.
Q
(i, 0) = s2.
QN
(i, 0);
137
out.
R
(i, 0) = s2.
CN
(i, 0);
138
}
139
140
// S3/S4: the totals increase in the demands and the population and decrease
141
// in the think time, so their corners differ from the throughput's.
142
const
MvaResult<T>
s3 = call(Llo, nlo, zup);
143
const
MvaResult<T>
s4 = call(Lup, nup, zlo);
144
out.
Rtot_lo
= zero;
145
out.
Qtot_lo
= zero;
146
out.
Rtot_up
= zero;
147
out.
Qtot_up
= zero;
148
for
(std::size_t i = 0; i < M; ++i) {
149
out.
Rtot_lo
+= s3.
CN
(i, 0);
150
out.
Qtot_lo
+= s3.
QN
(i, 0);
151
out.
Rtot_up
+= s4.
CN
(i, 0);
152
out.
Qtot_up
+= s4.
QN
(i, 0);
153
}
154
155
// S5/S6: one pair of calls per thick station, its own demand at the endpoint
156
// that maximizes (minimizes) it and the others at the opposite endpoint.
157
for
(std::size_t k = 0; k < M; ++k) {
158
if
(!thick[k])
continue
;
159
Matrix<T>
d = Llo;
160
d(k, 0) = Lup(k, 0);
161
const
MvaResult<T>
s5 = call(d, nup, zlo);
162
out.
Q
(k, 1) = s5.
QN
(k, 0);
163
out.
R
(k, 1) = s5.
CN
(k, 0);
164
d = Lup;
165
d(k, 0) = Llo(k, 0);
166
const
MvaResult<T>
s6 = call(d, nlo, zup);
167
out.
Q
(k, 0) = s6.
QN
(k, 0);
168
out.
R
(k, 0) = s6.
CN
(k, 0);
169
}
170
171
// U = X D is not covered by the monotonicity table, so it is enclosed by the
172
// product of the two intervals, capped at the range of a single-server
173
// utilization. Where the demand is thin the product is already exact.
174
for
(std::size_t i = 0; i < M; ++i) {
175
out.
U
(i, 0) = T(out.
Xlo
* Llo(i, 0));
176
const
T up = T(out.
Xup
* Lup(i, 0));
177
out.
U
(i, 1) = up < one ? up : one;
178
}
179
return
out;
180
}
181
182
}
// namespace pfqn
183
}
// namespace line
184
185
#endif
// LINE_API_PFQN_PFQN_MVA_INTERVAL_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::Matrix
Matrix()
Definition
matrix.h:58
line::Matrix::rows
std::size_t rows() const
Definition
matrix.h:89
line::Matrix::empty
bool empty() const
Definition
matrix.h:92
error.h
The exception types the port throws.
lang_types.h
Enumerations and the minimal distribution descriptor shared by the model layer of the C++ port.
matrix.h
Dense matrix and non-owning view.
line::pfqn
Definition
cd_peak_scaling.h:43
line::pfqn::pfqn_mva_interval
MvaIntervalResult< T > pfqn_mva_interval(const Matrix< T > &L, int nlo, int nup, const T &zlo, const T &zup)
Exact interval-valued MVA for single-class closed product-form networks.
Definition
pfqn_mva_interval.h:80
line::pfqn::pfqn_mva
MvaResult< T > pfqn_mva(const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, const std::vector< int > &mi)
Exact Mean Value Analysis for closed product-form networks (Reiser and Lavenberg 1980).
Definition
pfqn_mva.h:71
line
Definition
aoi_dist2ph.h:52
number.h
Number-type abstraction for the templated API port.
pfqn_mva.h
Exact Mean Value Analysis for closed product-form networks (Reiser and Lavenberg 1980).
line::lang::GlobalConstants::Zero
static constexpr double Zero
Definition
lang_types.h:670
line::num_traits
Definition
number.h:111
line::pfqn::MvaIntervalResult
Every output of pfqn_mva_interval, each a [lower, upper] pair.
Definition
pfqn_mva_interval.h:60
line::pfqn::MvaIntervalResult::R
Matrix< T > R
(M x 2) residence time per station
Definition
pfqn_mva_interval.h:64
line::pfqn::MvaIntervalResult::Xup
T Xup
throughput interval
Definition
pfqn_mva_interval.h:61
line::pfqn::MvaIntervalResult::Q
Matrix< T > Q
(M x 2) mean queue length per station
Definition
pfqn_mva_interval.h:62
line::pfqn::MvaIntervalResult::Qtot_lo
T Qtot_lo
Definition
pfqn_mva_interval.h:66
line::pfqn::MvaIntervalResult::Xlo
T Xlo
Definition
pfqn_mva_interval.h:61
line::pfqn::MvaIntervalResult::Rtot_lo
T Rtot_lo
Definition
pfqn_mva_interval.h:65
line::pfqn::MvaIntervalResult::U
Matrix< T > U
(M x 2) utilization enclosure per station
Definition
pfqn_mva_interval.h:63
line::pfqn::MvaIntervalResult::Qtot_up
T Qtot_up
total number of jobs at the stations
Definition
pfqn_mva_interval.h:66
line::pfqn::MvaIntervalResult::Rtot_up
T Rtot_up
total response time
Definition
pfqn_mva_interval.h:65
line::pfqn::MvaResult
Definition
pfqn_mva.h:44
line::pfqn::MvaResult::XN
std::vector< T > XN
(R) per-class throughput
Definition
pfqn_mva.h:45
line::pfqn::MvaResult::QN
Matrix< T > QN
(M x R) mean queue length
Definition
pfqn_mva.h:46
line::pfqn::MvaResult::CN
Matrix< T > CN
(M x R) residence time
Definition
pfqn_mva.h:48
include
line
api
pfqn
pfqn_mva_interval.h
Generated by
1.18.0