LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
fes_map_levels.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_LEVELS_H
6#define LINE_API_FES_MAP_LEVELS_H
7
8/**
9 * @file
10 * @ingroup api_fes
11 * Per-level processes of a load-dependent flow-equivalent server.
12 *
13 * Templated port of matlab/src/api/fes/fes_map_levels.m, mirrored by the JAR and
14 * native Python.
15 *
16 * A flow-equivalent server is described by one MAP (F0^k, F1^k) per population
17 * level k = 1..n. A single MAP is replicated over the levels and scaled by
18 * min(k, mi), which reproduces a queue with mi servers and, for mi infinite, a
19 * delay station serving at rate k mu. The scaling is exact for exponential
20 * service and is the load-dependent rate approximation otherwise.
21 *
22 * ARITHMETIC: field operations only, exact at T = Rational.
23 */
24
25#include <cstddef>
26#include <vector>
27
29#include "line/num/number.h"
30#include "line/util/error.h"
31#include "line/util/matrix.h"
32
33namespace line {
34namespace fes {
35
36/** Replicate a load independent MAP over n levels, scaling level k by min(k, mi). */
37template <class T>
38std::vector<mam::Map<T>> fes_map_levels(const mam::Map<T>& map, std::size_t n, double mi = 1.0) {
39 std::vector<mam::Map<T>> levels;
40 levels.reserve(n);
41 for (std::size_t k = 1; k <= n; ++k) {
42 const double sd = (static_cast<double>(k) < mi) ? static_cast<double>(k) : mi;
43 const T s = num_traits<T>::from_int(static_cast<long>(sd));
44 mam::Map<T> lev = map;
45 for (std::size_t i = 0; i < lev.D0.rows(); ++i)
46 for (std::size_t j = 0; j < lev.D0.cols(); ++j) {
47 lev.D0(i, j) = s * lev.D0(i, j);
48 lev.D1(i, j) = s * lev.D1(i, j);
49 }
50 levels.push_back(lev);
51 }
52 return levels;
53}
54
55/** Validate a load dependent descriptor and return its first n levels. */
56template <class T>
57std::vector<mam::Map<T>> fes_map_levels(const std::vector<mam::Map<T>>& levels, std::size_t n) {
58 if (levels.size() < n)
59 throw InputError("fes_map_levels: the flow-equivalent server has fewer levels than required");
60 const std::size_t mf = levels[0].order();
61 for (std::size_t k = 0; k < n; ++k)
62 if (levels[k].order() != mf)
63 throw InputError("fes_map_levels: all levels must have the same number of phases");
64 return std::vector<mam::Map<T>>(levels.begin(), levels.begin() + static_cast<long>(n));
65}
66
67} // namespace fes
68} // namespace line
69
70#endif // LINE_API_FES_MAP_LEVELS_H
InputError(const std::string &what)
Definition error.h:39
The exception types the port throws.
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).
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