LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
cd_peak_scaling.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_CD_PEAK_SCALING_H
6#define LINE_API_PFQN_CD_PEAK_SCALING_H
7
8/**
9 * @file
10 * @ingroup api_pfqn
11 * Peak of a class-dependence handle over the reachable population lattice.
12 *
13 * Templated port of matlab/src/api/pfqn/cd_peak_scaling.m. The handle beta(n)
14 * returns either a scalar shared by every class or a per-class vector; the
15 * peak is taken over both the lattice states 0 <= n <= NK and the classes,
16 * because utilization is a per-station quantity and the whole station shares
17 * one normalizer, exactly as max(lldscaling(ist,:)) does for the
18 * load-dependent case. That single normalizer is what every solver divides by
19 * when reporting U = T S / bmax at a station with limited class dependence.
20 *
21 * NON-FINITE VALUES are skipped, as in the reference (v = v(isfinite(v))): a
22 * class-dependence handle may legitimately return Inf for an unreachable
23 * composition, and letting that become the normalizer would zero every
24 * utilization at the station. A state whose every entry is non-finite
25 * contributes nothing, and if that is every state the peak stays at zero.
26 *
27 * ARITHMETIC. A maximum over evaluations of the caller's handle: no
28 * transcendental function is applied, so the routine is EXACT in rational
29 * arithmetic and is deliberately left ungated. Whether the result is exact
30 * depends only on the handle.
31 */
32
33#include <cmath>
34#include <cstddef>
35#include <functional>
36#include <vector>
37
38#include "line/num/number.h"
39#include "line/util/error.h"
41
42namespace line {
43namespace pfqn {
44
45/**
46 * @brief Peak of a class-dependence handle over the reachable population
47 * lattice.
48 *
49 * @param beta class-dependence handle, evaluated on a per-class count vector
50 * @param NK (R) per-class population bound
51 */
52template <class T>
53T cd_peak_scaling(const std::function<std::vector<T>(const std::vector<int>&)>& beta,
54 const std::vector<int>& NK) {
55 if (NK.empty()) throw InputError("cd_peak_scaling: empty population vector");
56 for (int v : NK)
57 if (v < 0) throw InputError("cd_peak_scaling: negative population");
58 T bmax = num_traits<T>::from_int(0);
59 std::vector<int> n(NK.size(), 0);
60 bool more = true;
61 while (more) {
62 int tot = 0;
63 for (int v : n) tot += v;
64 if (tot > 0) {
65 const std::vector<T> v = beta(n);
66 for (const T& x : v) {
67 if (!std::isfinite(num_traits<T>::to_double(x))) continue;
68 if (x > bmax) bmax = x;
69 }
70 }
71 more = next_pop(n, NK);
72 }
73 return bmax;
74}
75
76} // namespace pfqn
77} // namespace line
78
79#endif // LINE_API_PFQN_CD_PEAK_SCALING_H
InputError(const std::string &what)
Definition error.h:39
The exception types the port throws.
T cd_peak_scaling(const std::function< std::vector< T >(const std::vector< int > &)> &beta, const std::vector< int > &NK)
Peak of a class-dependence handle over the reachable population lattice.
bool next_pop(std::vector< int > &n, const std::vector< int > &N)
Advance n to the next population vector in the lattice 0 <= n <= N, odometer order with the last clas...
Definition population.h:56
Number-type abstraction for the templated API port.
Population-vector enumeration and combinatorics.