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

Linearizer for mixed open/closed queueing networks. More...

#include <cmath>
#include <cstddef>
#include <vector>
#include "line/api/pfqn/pfqn_amva_common.h"
#include "line/api/pfqn/pfqn_egflinearizer.h"
#include "line/api/pfqn/pfqn_gflinearizer.h"
#include "line/api/pfqn/pfqn_linearizer.h"
#include "line/api/pfqn/pfqn_linearizerms.h"
#include "line/num/number.h"
#include "line/util/error.h"
#include "line/util/matrix.h"
Include dependency graph for pfqn_linearizermx.h:

Go to the source code of this file.

Namespaces

namespace  line
namespace  line::pfqn

Enumerations

enum class  line::pfqn::LinearizerMxMethod { line::pfqn::Lin , line::pfqn::Gflin , line::pfqn::Egflin }
 Which Linearizer variant solves the closed subnetwork. More...

Functions

template<class T>
LinearizerResult< T > line::pfqn::pfqn_linearizermx (const std::vector< T > &lambda, const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, const std::vector< int > &nservers, const std::vector< SchedStrategy > &type, double tol, int maxiter, LinearizerMxMethod method, const Matrix< T > &QN0)
 Linearizer for mixed open/closed queueing networks.
template<class T>
LinearizerResult< T > line::pfqn::pfqn_linearizermx (const std::vector< T > &lambda, const Matrix< T > &L, const std::vector< int > &N, const Matrix< T > &Z, const std::vector< int > &nservers, LinearizerMxMethod method=LinearizerMxMethod::Egflin)
 MATLAB defaults: all-PS, tol = 1e-8, maxiter = 1000, 'egflin', no warm start.

Variables

constexpr int line::pfqn::kOpenClass = -1
 Population sentinel marking an open class, standing in for MATLAB's Inf.

Detailed Description

Linearizer for mixed open/closed queueing networks.

Templated port of matlab/src/api/pfqn/pfqn_linearizermx.m, cross-checked against jar/src/main/java/jline/api/pfqn/mva/Pfqn_linearizermx.java.

The open classes are solved in closed form from their fixed arrival rates: X_r = lambda_r and U(i,r) = lambda_r L(i,r). Their aggregate utilization U^o(i) = sum_{r open} U(i,r) then inflates the closed-class demands by the Bard-Schweitzer/Reiser open-class correction

Dc(i,c) = L(i,c) / (1 - U^o(i)),

and the resulting purely closed subnetwork is handed to one of the Linearizer variants: pfqn_linearizer, pfqn_gflinearizer with alpha = 2, or pfqn_egflinearizer with a Gompertz alpha per closed class, or pfqn_linearizerms when any station has more than one server. The open-class residence times are finally recovered from the closed-class queue lengths as W(i,r) = L(i,r) (1 + sum_c Qc(i,c)) / (1 - U^o(i)).

Arithmetic: TRANSCENDENTAL-GATED, on two independent grounds. Every branch delegates to a Linearizer variant that stops on a tolerance, so the answer is a fixed point only to within tol; and the 'egflin' branch evaluates the Gompertz exponent 0.6 + 1.4 exp(-8 exp(-0.8 N_c)), a genuine transcendental of the closed population, which has no meaning in an exact field.

Open classes. MATLAB marks them with N_r = Inf. There is no infinity in a general ordered field, so this port marks them with a negative entry (kOpenClass) in the otherwise non-negative population vector, and the lambda(isnan) = 0 style scrubbing of the reference is dropped: NaN is a floating-point artefact, not a value of T, and silently rewriting a caller's input to zero would hide a modelling error rather than fix one.

MATLAB-vs-JAR disagreement on the 'egflin' alpha, resolved in the JAR's favour. MATLAB builds the exponent vector in the GLOBAL class index space

alphaM = zeros(1,R);                       % R = total class count
for ridx = 1:length(closedClasses)
    r = closedClasses(ridx);
    alphaM(r) = 0.6 + 1.4*exp(-8*exp(-0.8*N(r)));
end

but pfqn_egflinearizer consumes it in the CLOSED-class index space, since it is called with Dc, which has only length(closedClasses) columns and whose class r is closedClasses(r). Whenever an open class precedes a closed one the two index spaces differ and the closed class silently receives the leading zero of alphaM, i.e. alpha = 0, so N_c^alpha_c collapses to 1 and the Gompertz scaling is switched off entirely. Verified on the two-station, two-class model of cpp/tests/test_pfqn_linearizer.cpp with class 1 open at lambda = 0.4 and class 2 closed at N = 3: MATLAB pfqn_linearizermx returns X_2 = 0.85177305755470, which reproduces exactly a direct pfqn_egflinearizer call with alpha = 0, whereas the intended exponent alpha = 1.2775503648739 gives X_2 = 0.84260134365230. The JAR indexes alphaM over Nclosed and is correct; this port follows the JAR. The defect is invisible in the single-class-per-index case where closedClasses == 1:R.

Definition in file pfqn_linearizermx.h.