LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
da_traffic_superpos.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_DA_DA_TRAFFIC_SUPERPOS_H
6#define LINE_API_DA_DA_TRAFFIC_SUPERPOS_H
7
8/**
9 * @file
10 * @ingroup api_da
11 * Superposition of independent renewal flows (Whitt's QNA stationary-interval
12 * method).
13 *
14 * Templated port of matlab/src/api/da/da_traffic_superpos.m. Given flows with
15 * rates lambda(i) and squared coefficients of variation a2(i), the merged flow
16 * is assigned the rate-weighted mixture
17 *
18 * d2 = sum_i lambda(i) a2(i) / sum_i lambda(i),
19 *
20 * flows with a non-finite rate being dropped first (MATLAB's isfinite mask).
21 * The rate of the merged flow is sum_i lambda(i) and is not returned: the
22 * decomposition step that calls this already holds it.
23 *
24 * A weighted mean is a sum and one division, so this is a finite field
25 * computation and instantiates at exact arithmetic with no rounding: for
26 * rational rates and SCVs the merged SCV is the exact rational mixture. No
27 * transcendental gate.
28 *
29 * The finiteness mask only ever removes anything in an inexact instantiation;
30 * an exact rational is finite by construction, so for T = Rational the mask is
31 * the identity and every flow is kept.
32 */
33
34#include <cmath>
35#include <cstddef>
36#include <vector>
37
38#include "line/num/number.h"
39#include "line/util/error.h"
40
41namespace line {
42namespace da {
43
44namespace detail {
45
46/** MATLAB isfinite: always true in an exact instantiation. */
47template <class T>
48bool da_is_finite(const T& v) {
49 if (num_traits<T>::is_exact) return true;
50 return std::isfinite(num_traits<T>::to_double(v));
51}
52
53} // namespace detail
54
55/**
56 * @brief Superposition of independent renewal flows (Whitt's QNA
57 * stationary-interval method).
58 *
59 * @param lambda (m) flow rates; entries that are not finite are ignored
60 * @param a2 (m) squared coefficients of variation of the same flows
61 * @return the squared coefficient of variation of the superposed flow
62 */
63template <class T>
64T da_traffic_superpos(const std::vector<T>& lambda, const std::vector<T>& a2) {
65 if (lambda.size() != a2.size())
66 throw InputError("da_traffic_superpos: lambda and a2 have different lengths");
67 if (lambda.empty()) throw InputError("da_traffic_superpos: no flows to superpose");
68
69 T num = num_traits<T>::from_int(0);
70 T den = num_traits<T>::from_int(0);
71 std::size_t kept = 0;
72 for (std::size_t i = 0; i < lambda.size(); ++i) {
73 if (!detail::da_is_finite(lambda[i])) continue;
74 num += a2[i] * lambda[i];
75 den += lambda[i];
76 ++kept;
77 }
78 if (kept == 0) throw InputError("da_traffic_superpos: every flow rate is non-finite");
79 if (den == num_traits<T>::from_int(0))
80 throw NumericError("da_traffic_superpos: the superposed flow has zero rate");
81 return num / den;
82}
83
84} // namespace da
85} // namespace line
86
87#endif // LINE_API_DA_DA_TRAFFIC_SUPERPOS_H
InputError(const std::string &what)
Definition error.h:39
NumericError(const std::string &what)
Definition error.h:45
The exception types the port throws.
T da_traffic_superpos(const std::vector< T > &lambda, const std::vector< T > &a2)
Superposition of independent renewal flows (Whitt's QNA stationary-interval method).
Number-type abstraction for the templated API port.