LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
pfqn_cub_evals.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_CUB_EVALS_H
6#define LINE_API_PFQN_CUB_EVALS_H
7
8/**
9 * @file
10 * @ingroup api_pfqn
11 * Integrand-evaluation count of pfqn_cub, and the budget pfqn_nc prices it
12 * against.
13 *
14 * Port of matlab/src/api/pfqn/pfqn_cub_evals.m.
15 *
16 * The Grundmann-Moeller rule of degree `order` on the (M-1)-simplex evaluates
17 * sum_{d = 0..order} C(M-1+2d, M-1)
18 * points, and a non-zero think time makes pfqn_cub repeat the whole rule at
19 * each of its v-quadrature steps (a uniform grid of CUB_V_STEPS points, which
20 * must match the outer McKenna-Mitra integral in pfqn_cub.h).
21 *
22 * NOTE the two DIFFERENT binomials in play. The cost model pfqn_nc uses to
23 * RAISE the order counts C(M + 2d, M-1); the count here, which pfqn_nc then
24 * uses to LOWER it again, counts C(M-1+2d, M-1). Both are reproduced as in the
25 * reference: they are not the same expression and folding one into the other
26 * would change the selected order.
27 *
28 * Arithmetic: this is a cost model, not a numerical result. It is a plain
29 * double count and carries no number type.
30 */
31
32#include <cstddef>
33
34#include "line/num/number.h"
35#include "line/util/error.h"
37
38namespace line {
39namespace pfqn {
40
41/** The v-quadrature grid size of pfqn_cub; must match `steps` in pfqn_cub.h. */
42constexpr long CUB_V_STEPS = 10000;
43
44/**
45 * GlobalConstants.CubMaxEvals: the integrand-evaluation budget above which
46 * pfqn_nc lowers the cubature order (and, at order 0, prefers le over cub).
47 */
48constexpr double CUB_MAX_EVALS = 1e7;
49
50/**
51 * @brief Integrand-evaluation count of pfqn_cub, and the budget pfqn_nc
52 * prices it against.
53 *
54 * @param M number of queueing stations
55 * @param order Grundmann-Moeller degree
56 * @param Zsum total think time; a positive value costs the v-quadrature
57 * @return number of integrand evaluations pfqn_cub performs
58 */
59inline double pfqn_cub_evals(int M, int order, double Zsum) {
60 if (M < 1) throw InputError("pfqn_cub_evals: at least one station is required");
61 if (order < 0) throw InputError("pfqn_cub_evals: negative cubature order");
62 const int n = M - 1;
63 double nodes = 0.0;
64 for (int d = 0; d <= order; ++d) nodes += nck(n + 2 * d, n);
65 // GlobalConstants.FineTol, the reference's threshold for "has a think time"
66 if (Zsum >= 1e-8) return nodes * static_cast<double>(CUB_V_STEPS);
67 return nodes;
68}
69
70/** Zero think time, i.e. the bare simplex rule. */
71inline double pfqn_cub_evals(int M, int order) { return pfqn_cub_evals(M, order, 0.0); }
72
73} // namespace pfqn
74} // namespace line
75
76#endif // LINE_API_PFQN_CUB_EVALS_H
InputError(const std::string &what)
Definition error.h:39
The exception types the port throws.
constexpr double CUB_MAX_EVALS
GlobalConstants.CubMaxEvals: the integrand-evaluation budget above which pfqn_nc lowers the cubature ...
double pfqn_cub_evals(int M, int order, double Zsum)
Integrand-evaluation count of pfqn_cub, and the budget pfqn_nc prices it against.
constexpr long CUB_V_STEPS
The v-quadrature grid size of pfqn_cub; must match steps in pfqn_cub.h.
double nck(int n, int k)
Binomial coefficient with a thread-local memo table (mp_pfqn util/nck.c).
Definition population.h:69
Number-type abstraction for the templated API port.
Population-vector enumeration and combinatorics.