LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
pfqn_procomom.h File Reference

ProCoMoM: marginal queue-length probabilities of a closed multiclass product-form network by the class-oriented method of moments. More...

#include <cmath>
#include <cstddef>
#include <random>
#include <vector>
#include "line/api/pfqn/pfqn_comb_common.h"
#include "line/api/pfqn/pfqn_comom.h"
#include "line/num/number.h"
#include "line/util/error.h"
#include "line/util/lstsq.h"
#include "line/util/matrix.h"
Include dependency graph for pfqn_procomom.h:

Go to the source code of this file.

Classes

struct  line::pfqn::ProcomomResult< T >
 Return value of pfqn_procomom, mirroring [Pr, Q]. More...
struct  line::pfqn::Procomom2Result< T >
 Return value of pfqn_procomom2, mirroring [pk, lG, G, T, F, B]. More...

Namespaces

namespace  line
 Conservation laws of a layered queueing network, enumerated from its structure.
namespace  line::pfqn

Functions

template<class T>
ProcomomResult< T > line::pfqn::pfqn_procomom (const Matrix< T > &L, const std::vector< int > &N, const std::vector< T > &Z, const T &atol)
 Marginal queue-length distributions of every station.
template<class T>
ProcomomResult< T > line::pfqn::pfqn_procomom (const Matrix< T > &L, const std::vector< int > &N, const std::vector< T > &Z)
 Overload with the reference's default tolerance.
template<class T>
Procomom2Result< T > line::pfqn::pfqn_procomom2 (const std::vector< T > &L, const std::vector< int > &N, const std::vector< T > &Z, const std::vector< T > &mu, int m)
 Queue-plus-delay marginal by the transfer-matrix form of ProCoMoM.
template<class T>
Procomom2Result< T > line::pfqn::pfqn_procomom2 (const std::vector< T > &L, const std::vector< int > &N, const std::vector< T > &Z)
 Overload with the load-independent, unit-multiplicity defaults.

Detailed Description

ProCoMoM: marginal queue-length probabilities of a closed multiclass product-form network by the class-oriented method of moments.

Templated port of matlab/src/api/pfqn/pfqn_procomom.m and matlab/src/api/pfqn/pfqn_procomom2.m.

pfqn_procomom carries, instead of the plain moments of pfqn_comom, the generating coefficients of ONE station's marginal distribution: pk(:, j+1) holds the basis coefficients of P(n_station = j). The basis is the same Dn = multichoose(R,M) layout as pfqn_comom, with the reference's UP shifts (Dn + e_s) where pfqn_comom uses down shifts, and the station of interest is rotated into the last row of L so the two extra couplings, DC (same level, one job less at the station) and DD (previous level), always refer to row M. Every station is solved in turn and its distribution normalized to sum 1.

pfqn_procomom2 is the two-node special case, a queue plus a delay, where the whole recursion collapses to a product of bidiagonal transfer matrices,

F = prod_r T_r^{N_r} / N_r!, T_r(row,row) = Z_r, T_r(row,row+1) = (n + m - 1) L_r / mu(n),

and the unnormalized marginal is F e_last. No linear system is solved at all.

SYSTEM SHAPE. The ProCoMoM matrix is NOT square: countrows(r) contributes M rows per basis vector in the propagation branch but M + r - 1 (or 1) in the equation branch, so for M = R = 2 the class-1 step is 6 x 6 and the class-2 step is 7 x 6. The reference solves it with an economy QR when full rank and with a truncated SVD when not. Both are done here by util/lstsq.h in exact arithmetic: the normal equations give the identical least-squares vector, and a full-rank factorization gives the identical minimum-norm vector.

RANK-DEFICIENCY REMEDY, as in the reference: when some generating system is rank deficient the whole problem is re-solved with L and Z perturbed by delta*(1+rand) at delta = Lscale*10^{-10,-8,-6,-4}, keeping the first attempt that is full rank, non-negative to -1e-6 and row-normalized to within 0.01 (the last attempt otherwise). The draws follow MATLAB's rng(23000,'twister') stream (mt19937, genrand_res53, restarted at every attempt), so the perturbed systems are the ones MATLAB solves. rankdef reports the rank state of the solution finally returned.

Arithmetic: EXACT-CAPABLE. Field operations and least-squares solves only.

REFERENCE DEFECTS in pfqn_procomom2.m, all reproducible, none corrected in MATLAB by this port (it does not edit MATLAB):

  1. pfqn_procomom2(L,N,Z) raises "Not enough input arguments". The nargin < 4 branch evaluates ones(m, sum(N)+1), but m is assigned only by the nargin < 5 branch BELOW it. Reproduce with pfqn_procomom2([0.4 0.6],[2 1],[1 2]).
  2. Debug scaffolding runs on EVERY call: QN=double(Q) and a full pfqn_mvald(...) are executed without semicolons, so the routine prints QN, XNMVA, QNMVA and pik to the console and pays for an O(prod(N+1)) load-dependent MVA it does not use. Visible in the output of the call above.
  3. Dead branch: if any(~isfinite(pk(1,1))) || ~isfinite(G) ... elseif ~isfinite(G) – the elseif is subsumed by the first test and can never be taken.

This port implements the transfer-matrix method only, with no printing and no MVA call, and accepts the three-argument form.

Definition in file pfqn_procomom.h.