LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
pfqn_cdfun.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_CDFUN_H
6#define LINE_API_PFQN_CDFUN_H
7
8/**
9 * @file
10 * @ingroup api_pfqn
11 * AMVA-QD class-dependence function.
12 *
13 * Templated port of matlab/src/api/pfqn/pfqn_cdfun.m, cross-checked against
14 * jar/src/main/java/jline/api/pfqn/ld/Pfqn_cdfun.java.
15 *
16 * Returns, for every station i, the reciprocal of the class-dependent scaling
17 * beta_{i,r}(n_{i1}, ..., n_{iR}) evaluated at the per-class population row
18 * nvec(i,:), for the requested class r.
19 *
20 * cdscaling[i] is a callable of that row. It may return a single value, i.e. a
21 * chain-independent scaling beta_i(n) shared by every class (the historical
22 * contract), or R values, i.e. the per-class scalings, of which element
23 * classIdx is taken. The per-class form expresses Sauer's chain-dependent
24 * service rates mu_{r,i}(n) (Sauer 1983, eq. (40)). An absent (empty) callable
25 * leaves the station at 1.
26 *
27 * Arithmetic: EXACT-CAPABLE. The function itself performs one reciprocal per
28 * station and nothing else, so it carries no transcendental gate; whether the
29 * result is exact is entirely a property of the supplied callables.
30 */
31
32#include <cstddef>
33#include <functional>
34#include <vector>
35
36#include "line/num/number.h"
37#include "line/util/error.h"
38#include "line/util/matrix.h"
39
40namespace line {
41namespace pfqn {
42
43/** A per-station class-dependence callable: the population row -> 1 or R rates. */
44template <class T>
45using CdScaling = std::function<std::vector<T>(const std::vector<T>&)>;
46
47/**
48 * @brief AMVA-QD class-dependence function.
49 *
50 * @param nvec (M x R) per-station, per-class populations
51 * @param cdscaling (M) callables; entries may be empty for "no scaling"
52 * @param classIdx 0-based class whose scaling is selected from a vector result
53 * @return (M) reciprocals of the scalings
54 */
55template <class T>
56std::vector<T> pfqn_cdfun(const Matrix<T>& nvec, const std::vector<CdScaling<T>>& cdscaling,
57 std::size_t classIdx) {
58 const std::size_t M = nvec.rows();
59 const std::size_t R = nvec.cols();
60 const T one = num_traits<T>::from_int(1);
61 std::vector<T> r(M, one);
62 if (cdscaling.empty()) return r;
63 if (cdscaling.size() != M)
64 throw InputError("pfqn_cdfun: scaling vector has the wrong station count");
65 for (std::size_t i = 0; i < M; ++i) {
66 if (!cdscaling[i]) continue;
67 std::vector<T> row(R);
68 for (std::size_t s = 0; s < R; ++s) row[s] = nvec(i, s);
69 const std::vector<T> v = cdscaling[i](row);
70 if (v.empty()) throw InputError("pfqn_cdfun: a scaling callable returned nothing");
71 const T& chosen = v.size() > 1 ? v.at(classIdx) : v[0];
72 if (chosen == num_traits<T>::from_int(0))
73 throw NumericError("pfqn_cdfun: a class-dependent scaling is zero");
74 r[i] = one / chosen;
75 }
76 return r;
77}
78
79/** MATLAB default: classIdx = 1, i.e. the first class. */
80template <class T>
81std::vector<T> pfqn_cdfun(const Matrix<T>& nvec, const std::vector<CdScaling<T>>& cdscaling) {
82 return pfqn_cdfun(nvec, cdscaling, static_cast<std::size_t>(0));
83}
84
85} // namespace pfqn
86} // namespace line
87
88#endif // LINE_API_PFQN_CDFUN_H
InputError(const std::string &what)
Definition error.h:39
std::size_t cols() const
Definition matrix.h:90
std::size_t rows() const
Definition matrix.h:89
NumericError(const std::string &what)
Definition error.h:45
The exception types the port throws.
Dense matrix and non-owning view.
std::function< std::vector< T >(const std::vector< T > &)> CdScaling
A per-station class-dependence callable: the population row -> 1 or R rates.
Definition pfqn_cdfun.h:45
std::vector< T > pfqn_cdfun(const Matrix< T > &nvec, const std::vector< CdScaling< T > > &cdscaling, std::size_t classIdx)
AMVA-QD class-dependence function.
Definition pfqn_cdfun.h:56
Number-type abstraction for the templated API port.