LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
fes_map_interdeparture.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_FES_MAP_INTERDEPARTURE_H
6#define LINE_API_FES_MAP_INTERDEPARTURE_H
7
8/**
9 * @file
10 * @ingroup api_fes
11 * Inter-departure MAP of a closed subnetwork made of one MAP station and one MAP
12 * flow-equivalent server.
13 *
14 * Templated port of matlab/src/api/fes/fes_map_interdeparture.m, mirrored by the
15 * JAR and native Python. Implements the block bidiagonal construction of Casale,
16 * Mi, Cherkasova and Smirni, IEEE Trans. Soft. Eng. 37(5), 2011, Section 5.2.2:
17 *
18 * T0 = [ D0 (x) I 0 0 0
19 * I (x) F1^1 D0 (+) F0^1 0 0
20 * ... ... ... ...
21 * 0 I (x) F1^{n-1} D0 (+) F0^{n-1} 0
22 * 0 0 I (x) F1^n I (x) F0^n ]
23 *
24 * T1 = superdiagonal blocks D1 (x) I, last block row zero
25 *
26 * Level k is the population of the flow-equivalent server, so the station holds
27 * n - k jobs and both processes may be load dependent. Marked transitions are the
28 * completions of the station, which are the departures fed to the rest of the
29 * model.
30 *
31 * ARITHMETIC: field operations only, exact at T = Rational.
32 */
33
34#include <cstddef>
35#include <vector>
36
39#include "line/num/number.h"
40#include "line/util/error.h"
41#include "line/util/matrix.h"
42
43namespace line {
44namespace fes {
45
46/**
47 * @brief Inter-departure MAP of a closed subnetwork made of one MAP station
48 * and one MAP flow-equivalent server.
49 *
50 * @param maps per-level service processes of the station, index j-1 holding j jobs
51 * @param fes per-level processes of the flow-equivalent server, index k-1 holding k jobs
52 * @param n number of jobs circulating in the subnetwork
53 * @return the pair (T0, T1) of the inter-departure MAP
54 */
55template <class T>
57 const std::vector<mam::Map<T>>& fes, std::size_t n) {
58 if (n < 1) throw InputError("fes_map_interdeparture: the subnetwork population must be at least 1");
59 const std::vector<mam::Map<T>> mapsLev = fes_map_levels(maps, n);
60 const std::vector<mam::Map<T>> fesLev = fes_map_levels(fes, n);
61
62 const std::size_t ms = mapsLev[0].order();
63 const std::size_t mf = fesLev[0].order();
64 const std::size_t blk = ms * mf;
65 const std::size_t dim = (n + 1) * blk;
66 const T zero = num_traits<T>::from_int(0);
67
68 mam::Map<T> out;
69 out.D0 = Matrix<T>(dim, dim, zero);
70 out.D1 = Matrix<T>(dim, dim, zero);
71
72 for (std::size_t k = 0; k <= n; ++k) {
73 const std::size_t off = k * blk;
74 const std::size_t j = n - k;
75 // D0 (x) I on the station phase, I (x) F0 on the flow-equivalent one
76 if (j > 0) {
77 const Matrix<T>& D0 = mapsLev[j - 1].D0;
78 for (std::size_t a = 0; a < ms; ++a)
79 for (std::size_t b = 0; b < ms; ++b)
80 for (std::size_t f = 0; f < mf; ++f)
81 out.D0(off + a * mf + f, off + b * mf + f) += D0(a, b);
82 }
83 if (k > 0) {
84 const Matrix<T>& F0 = fesLev[k - 1].D0;
85 for (std::size_t a = 0; a < ms; ++a)
86 for (std::size_t f = 0; f < mf; ++f)
87 for (std::size_t g = 0; g < mf; ++g)
88 out.D0(off + a * mf + f, off + a * mf + g) += F0(f, g);
89 const Matrix<T>& F1 = fesLev[k - 1].D1;
90 for (std::size_t a = 0; a < ms; ++a)
91 for (std::size_t f = 0; f < mf; ++f)
92 for (std::size_t g = 0; g < mf; ++g)
93 out.D0(off + a * mf + f, off - blk + a * mf + g) += F1(f, g);
94 }
95 if (j > 0) {
96 const Matrix<T>& D1 = mapsLev[j - 1].D1;
97 for (std::size_t a = 0; a < ms; ++a)
98 for (std::size_t b = 0; b < ms; ++b)
99 for (std::size_t f = 0; f < mf; ++f)
100 out.D1(off + a * mf + f, off + blk + b * mf + f) += D1(a, b);
101 }
102 }
103 return out;
104}
105
106} // namespace fes
107} // namespace line
108
109#endif // LINE_API_FES_MAP_INTERDEPARTURE_H
InputError(const std::string &what)
Definition error.h:39
The exception types the port throws.
Per-level processes of a load-dependent flow-equivalent server.
Markovian arrival process descriptors: stationary vectors, rate, moments, autocorrelation and the ind...
Dense matrix and non-owning view.
std::vector< mam::Map< T > > fes_map_levels(const mam::Map< T > &map, std::size_t n, double mi=1.0)
Replicate a load independent MAP over n levels, scaling level k by min(k, mi).
mam::Map< T > fes_map_interdeparture(const std::vector< mam::Map< T > > &maps, const std::vector< mam::Map< T > > &fes, std::size_t n)
Inter-departure MAP of a closed subnetwork made of one MAP station and one MAP flow-equivalent server...
Number-type abstraction for the templated API port.
A MAP as the pair of matrices (D0, D1).
Definition map_moment.h:53
Matrix< T > D1
Definition map_moment.h:55
Matrix< T > D0
Definition map_moment.h:54