LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
qsys_phph1.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_QSYS_QSYS_PHPH1_H
6#define LINE_API_QSYS_QSYS_PHPH1_H
7
8/**
9 * @file
10 * @ingroup api_qsys
11 * The PH/PH/1 FCFS queue.
12 *
13 * ALGORITHM, AND HOW IT DIFFERS FROM THE MATLAB REFERENCE.
14 * matlab/src/api/qsys/qsys_phph1.m converts the arrival PH to a MAP and then
15 * calls BUTools' MMAPPH1FCFS, which is not transcribed here. This port computes
16 * the SAME quantities from the port's
17 * own QBD machinery. Both the arrival PH (alpha, T) and the service PH
18 * (beta, S) become renewal MAPs,
19 *
20 * arrival: D0 = T, D1 = (-T e) alpha, service: D0 = S, D1 = (-S e) beta,
21 *
22 * and the resulting MAP/MAP/1 queue is solved as the level-independent QBD
23 * described in qsys_mapmap1.h. Different algorithm, same quantity. Both
24 * processes are renewal by construction, so the reference and the port model
25 * the identical stochastic system; only the numerical route differs.
26 *
27 * MEASURED AGREEMENT (MATLAB R2025a, T = double). Metric order is
28 * meanQueueLength / meanWaitingTime / meanSojournTime / utilization.
29 * - M/M/1 collapse, qsys_phph1(alpha = [1], T = [-2], beta = [1], S = [-3]):
30 * MATLAB 1.999999999999999 / 0.6666666666666656 / 0.9999999999999989 /
31 * 0.6666666666666666; the port returns the textbook 2 / 0.666666666666668 /
32 * 1 / 0.666666666666667. Relative differences 5e-16, 1.8e-15, 1.1e-15.
33 * - Erlang-2 arrivals alpha = [1 0], T = [-4 4; 0 -4] (lambda = 2) with
34 * Erlang-2 service beta = [1 0], S = [-6 6; 0 -6] (mean 1/3): MATLAB
35 * 1.250000000000001 / 0.2916666666666675 / 0.6250000000000008 /
36 * 0.6666666666666666; port 1.25 / 0.291666666666667 / 0.625000000000001 /
37 * 0.666666666666667. Relative differences 8e-16, 1.7e-15, 1.1e-15.
38 * - Hyperexponential arrivals alpha = [0.7 0.3], T = diag(-5, -1)
39 * (mean 0.44, lambda = 25/11) with exponential service beta = [1],
40 * S = [-10/3]: MATLAB 3.273624198148769 / 1.140394647185455 /
41 * 1.440394647185455 / 0.6818181818181819; port 3.27362419814877 /
42 * 1.14039464718546 / 1.44039464718546 / 0.681818181818182. Relative
43 * differences below 4e-15 on every metric.
44 *
45 * The port reproduces the BUTools reference to machine precision throughout
46 * this family; the residual is the reference's own rounding, not a truncation,
47 * because these level distributions decay fast enough that the reference's
48 * numQLProbs = 100 cutoff is not visible. The slower-decaying instances in
49 * qsys_mapph1.h expose the reference's truncation floor instead.
50 *
51 * ARITHMETIC. Gated on num_traits<T>::has_transcendental, inherited from
52 * qsys_mapmap1 and ultimately from the cyclic reduction that produces R; see
53 * qbd_r.h. The two PH-to-MAP conversions are exact matrix algebra.
54 */
55
56#include <cstddef>
57#include <vector>
58
61#include "line/num/number.h"
62#include "line/util/error.h"
63#include "line/util/matrix.h"
64
65namespace line {
66namespace qsys {
67
68/**
69 * PH/PH/1 by the exact QBD solution of the equivalent MAP/MAP/1 queue.
70 *
71 * @param alpha PH arrival entry vector, length n
72 * @param Tm PH arrival sub-generator, n x n
73 * @param beta PH service entry vector, length m
74 * @param S PH service sub-generator, m x m
75 * @param dist_size how many entries of queueLengthDist to materialize
76 */
77template <class T>
78MapMap1Result<T> qsys_phph1(const std::vector<T>& alpha, const Matrix<T>& Tm,
79 const std::vector<T>& beta, const Matrix<T>& S,
80 std::size_t dist_size) {
82 "qsys_phph1 requires transcendental arithmetic");
83 return qsys_mapmap1(detail::ph_to_map(alpha, Tm), detail::ph_to_map(beta, S), dist_size);
84}
85
86/** qsys_phph1 with 100 materialized levels, the reference's numQLProbs. */
87template <class T>
88MapMap1Result<T> qsys_phph1(const std::vector<T>& alpha, const Matrix<T>& Tm,
89 const std::vector<T>& beta, const Matrix<T>& S) {
90 return qsys_phph1(alpha, Tm, beta, S, static_cast<std::size_t>(100));
91}
92
93} // namespace qsys
94} // namespace line
95
96#endif // LINE_API_QSYS_QSYS_PHPH1_H
The exception types the port throws.
Dense matrix and non-owning view.
MapMap1Result< T > qsys_phph1(const std::vector< T > &alpha, const Matrix< T > &Tm, const std::vector< T > &beta, const Matrix< T > &S, std::size_t dist_size)
PH/PH/1 by the exact QBD solution of the equivalent MAP/MAP/1 queue.
Definition qsys_phph1.h:78
MapMap1Result< T > qsys_mapmap1(const mam::Map< T > &arrival, const mam::Map< T > &service, std::size_t dist_size)
MAP/MAP/1 by the exact QBD solution.
Number-type abstraction for the templated API port.
The MAP/MAP/1 FCFS queue: mean number in system, waiting time, sojourn time, utilization and the queu...
The MAP/PH/1 FCFS queue.
Return value of the MAP/MAP/1 family (qsys_mapmap1, qsys_mapph1, qsys_phph1), carrying the same quant...