LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
pfqn_ble.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_PFQN_BLE_H
6#define LINE_API_PFQN_PFQN_BLE_H
7
8/**
9 * @file
10 * @ingroup api_pfqn
11 * Logistic expansion with the eps->0 bias correction (BLE).
12 *
13 * Templated port of matlab/src/api/pfqn/pfqn_ble.m. Cas17 Theorem 4.1 holds for
14 * eps >= eps_N > 0; the K(1+eps*N) self-looping populations are what make the
15 * integrand concentrate. Evaluated at eps->0, as pfqn_le does, the curvature at
16 * the saddle tends to 1 rather than growing with N, so Laplace's method has no
17 * asymptotic regime there and carries an O(1) relative bias of e/sqrt(2 pi) PER
18 * LAPLACED DIRECTION. The count is the exponent on sqrt(2 pi) in the branch
19 * taken: M-1 with Z = 0, where the radial integral is exact as Gamma(N+M), and M
20 * with Z > 0, where the radius is Laplaced too. Measured over the 1562 models of
21 * the Cas17 dataset (Zenodo 546873, sec5.3.1, sigma = 100) the Z > 0 deficit is M
22 * to within 0.01 units. The published expansion is NOT in error and the
23 * correction is EMPIRICAL, not part of Cas17; see _kb/03-api-layer.md.
24 *
25 * ARITHMETIC. Inherited from pfqn_le: the correction is a logarithm, so the
26 * routine is gated on num_traits<T>::has_transcendental for the same reason.
27 *
28 * DEGENERATE BRANCH. When there is no queueing station to expand around, pfqn_le
29 * returns the exact delay term and there is no Laplace step to correct, so
30 * pfqn_ble returns it unchanged; this is the MATLAB branching.
31 */
32
33#include <cmath>
34#include <cstddef>
35#include <vector>
36
39#include "line/num/number.h"
40#include "line/util/matrix.h"
41
42namespace line {
43namespace pfqn {
44
45/** Return value of pfqn_ble, mirroring [Gn, lGn]. */
46template <class T>
48
49/**
50 * Logistic expansion estimate of the normalizing constant, bias-corrected.
51 *
52 * @param L (M x R) demands, @param N (R) population, @param Z (R) think times
53 * (pass an empty vector or all zeros for the Z = 0 branch)
54 */
55template <class T>
56BleResult<T> pfqn_ble(const Matrix<T>& L, const std::vector<T>& N, const std::vector<T>& Z) {
58 "pfqn_ble requires transcendental arithmetic (Laplace approximation of an integral)");
59 using std::exp;
60 using std::log;
61 const std::size_t M = L.rows(), R = L.cols();
62 const T zero = num_traits<T>::from_int(0);
63
64 BleResult<T> res = pfqn_le(L, N, Z);
65
66 T Ntot = zero, Lsum = zero, Zsum = zero;
67 for (const T& x : N) Ntot += x;
68 for (const T& x : Z) Zsum += x;
69 for (std::size_t i = 0; i < M; ++i)
70 for (std::size_t r = 0; r < R; ++r) Lsum += L(i, r);
71 if (M == 0 || N.empty() || Ntot == zero || num_traits<T>::to_double(Lsum) < 1e-4) {
72 return res;
73 }
74
75 // Same predicate pfqn_le branches on, so the count always matches the branch.
76 const bool no_delay =
78 const long n_gauss = static_cast<long>(M) - (no_delay ? 1 : 0);
79 const T twopi = num_traits<T>::from_double(6.283185307179586476925286766559);
80 res.lG += num_traits<T>::from_int(n_gauss) *
82 res.G = exp(res.lG);
83 return res;
84}
85
86template <class T>
87BleResult<T> pfqn_ble(const Matrix<T>& L, const std::vector<T>& N) {
88 return pfqn_ble(L, N, std::vector<T>());
89}
90
91} // namespace pfqn
92} // namespace line
93
94#endif // LINE_API_PFQN_PFQN_BLE_H
std::size_t cols() const
Definition matrix.h:90
std::size_t rows() const
Definition matrix.h:89
Enumerations and the minimal distribution descriptor shared by the model layer of the C++ port.
Dense matrix and non-owning view.
BleResult< T > pfqn_ble(const Matrix< T > &L, const std::vector< T > &N, const std::vector< T > &Z)
Logistic expansion estimate of the normalizing constant, bias-corrected.
Definition pfqn_ble.h:56
LeResult< T > BleResult
Return value of pfqn_ble, mirroring [Gn, lGn].
Definition pfqn_ble.h:47
LeResult< T > pfqn_le(const Matrix< T > &L, const std::vector< T > &N, const std::vector< T > &Z)
Logistic expansion estimate of the normalizing constant.
Definition pfqn_le.h:245
Number-type abstraction for the templated API port.
Logistic expansion (LE) asymptotic approximation of the normalizing constant of a closed product-form...
static constexpr double Zero
Definition lang_types.h:670
Return value of pfqn_le, mirroring [Gn, lGn].
Definition pfqn_le.h:233