![]() |
LINE Solver (C++)
Templated C++ port of the LINE queueing solver
|
The MMAP[K]/PH[K]/1 FCFS queue: per-class mean number in system and per-class queue-length distribution. More...
#include <cstddef>#include <vector>#include "line/api/mam/mfq_solve.h"#include "line/api/mam/mmap_lambda.h"#include "line/api/mc/ctmc_solve.h"#include "line/num/number.h"#include "line/util/error.h"#include "line/util/linalg.h"#include "line/util/matrix.h"#include "line/util/sylvester.h"Go to the source code of this file.
Classes | |
| struct | line::mam::PhService< T > |
| One class's phase-type service law, He's (sigma_k, S_k). More... | |
| struct | line::mam::StDistrPh< T > |
| A phase-type law (alpha, A) as BUTools' 'stDistrPH' returns it. More... | |
Namespaces | |
| namespace | line |
| namespace | line::mam |
Functions | |
| template<class T> | |
| std::vector< StDistrPh< T > > | line::mam::mmapph1fcfs_stdistr_ph (const Mmap< T > &arrival, const std::vector< PhService< T > > &svc, double precision=1e-14) |
| Per-class SOJOURN TIME as a continuous phase-type law, BUTools' 'stDistrPH'. | |
| template<class T> | |
| std::vector< T > | line::mam::mmapph1fcfs_ncmean (const Mmap< T > &arrival, const std::vector< PhService< T > > &svc) |
| Per-class mean number of customers in the system, BUTools' 'ncMoms', 1. | |
| template<class T> | |
| std::vector< std::vector< T > > | line::mam::mmapph1fcfs_ncdistr (const Mmap< T > &arrival, const std::vector< PhService< T > > &svc, std::size_t levels) |
| Per-class queue-length distribution, BUTools' 'ncDistr', n: P(N_k = 0..n-1). | |
The MMAP[K]/PH[K]/1 FCFS queue: per-class mean number in system and per-class queue-length distribution.
This is the workhorse solver_mam_basic.m calls at every FCFS station, where MATLAB reaches BUTools' MMAPPH1FCFS. The algorithm is He's age process for the SM[K]/PH[K]/1/FCFS queue (Qiming He, "Analysis of a continuous time SM[K]/PH[K]/1/FCFS queue: age process, sojourn times, and queue lengths", Journal of Systems Science and Complexity 25(1), 133-155, 2012), which is the algorithm BUTools implements and which is what makes the two agree.
WHY THE AGE PROCESS AND NOT A QBD. A level-independent QBD over (number in system, arrival phase, in-service phase) is NOT Markovian here: under FCFS with class-dependent service, the law of the next service depends on the class of the job at the head of the queue, so the phase would have to carry the whole waiting sequence of classes. qsys_mapmap1.h gets away with a QBD precisely because it has one class. He's construction sidesteps this by tracking the AGE of the job in service against the arrival process, which closes as a fluid queue whose first-return matrix Psi is exactly what mfq_fundamental computes.
THE PIECES, and where each comes from in this port: Psi – the fluid first-return matrix of the age process, ADDA doubling (mfq_solve.h), the same routine BUTools reaches through FluidFundamentalMatrices(..., 'P'). T – kron(I_N, Sa) + Psi iVec, the age generator. pi0 – the age density at zero, a linear functional of the arrival stationary vector theta (ctmc_solve) and the per-class equilibrium service vectors beta (also ctmc_solve). the queue-length recursion – a chain of Sylvester equations T X + X kron(D0+Da-Dk, I_Ns) + C = 0 that all share their left and right coefficient matrices, so SylvesterFactor factors the Kronecker operator once and reuses it (util/sylvester.h).
ARITHMETIC. mfq_fundamental runs a tolerance-terminated doubling iteration and is gated on num_traits<T>::has_transcendental, so this function is {Double, Real} and refuses by name under exact/Rational. Everything else in it – the Kronecker assembly, the linear solves, the Sylvester chain – is field arithmetic and would be exact; the Riccati root is what is not.
MEASURED AGAINST MATLAB'S BUTools MMAPPH1FCFS: see cpp/tests/test_mam.cpp, which pins both entry points on a two-class MMAP/PH/1 fixture.
Definition in file mmapph1fcfs.h.