LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
pfqn_pff_delay.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_PFF_DELAY_H
6#define LINE_API_PFQN_PFF_DELAY_H
7
8/**
9 * @file
10 * @ingroup api_pfqn
11 * Product-form factor of a delay station.
12 *
13 * Templated port of jar/src/main/java/jline/api/pfqn/nc/Pfqn_pff_delay.java.
14 * MATLAB has no standalone counterpart: the same expression is inlined wherever
15 * a normalizing-constant recursion folds in the delay term.
16 *
17 * F_Z(n) = prod_r Z_r^{n_r} / n_r!
18 *
19 * the contribution of the delay stations to the normalizing constant of a
20 * closed product-form network. The empty population gives 1, and a class with a
21 * positive population but no think time gives 0, the delay being unreachable
22 * for it.
23 *
24 * The product is accumulated in the LOG DOMAIN and exponentiated once, so a
25 * large population does not overflow through the intermediate powers even where
26 * the value itself is representable.
27 *
28 * Arithmetic: TRANSCENDENTAL, because of that log-domain accumulation. The same
29 * quantity in exact arithmetic is available from the delay balance function
30 * inside pfqn_ca, which forms it as a ratio of exact rationals.
31 */
32
33#include <cmath>
34#include <cstddef>
35#include <vector>
36
38#include "line/num/number.h"
39#include "line/util/error.h"
40
41namespace line {
42namespace pfqn {
43
44/**
45 * @brief Product-form factor of a delay station.
46 *
47 * @param Z (R) think times of the delay station
48 * @param n (R) population of each class
49 */
50template <class T>
51T pfqn_pff_delay(const std::vector<T>& Z, const std::vector<int>& n) {
53 "pfqn_pff_delay accumulates in the log domain and needs transcendental "
54 "arithmetic");
55 using std::exp;
56 using std::log;
57 const std::size_t R = n.size();
58 if (Z.size() != R)
59 throw InputError("pfqn_pff_delay: Z and n disagree on the class count");
60 const T zero = num_traits<T>::from_int(0);
61 long total = 0;
62 for (std::size_t r = 0; r < R; ++r) total += n[r];
63 if (total == 0) return num_traits<T>::from_int(1);
64
65 T f = zero;
66 for (std::size_t r = 0; r < R; ++r) {
67 if (Z[r] > zero) {
68 f += log(Z[r]) * num_traits<T>::from_int(n[r]);
69 f -= detail::num_factln<T>(num_traits<T>::from_int(n[r]));
70 } else if (n[r] > 0) {
71 return zero;
72 }
73 }
74 return exp(f);
75}
76
77} // namespace pfqn
78} // namespace line
79
80#endif // LINE_API_PFQN_PFF_DELAY_H
InputError(const std::string &what)
Definition error.h:39
The exception types the port throws.
T pfqn_pff_delay(const std::vector< T > &Z, const std::vector< int > &n)
Product-form factor of a delay station.
Number-type abstraction for the templated API port.
Shared scalar machinery for the integration / asymptotic members of the pfqn family (pfqn_le,...