1function result = qsys_mmapg1k(D0, D1c, svc, K, varargin)
2% RESULT = QSYS_MMAPG1K(D0, D1C, SVC, K)
4% Exact per-
class throughput and loss ratio of an
MMAP[K]/G/1/K queue with
5% tail drop: marked Markovian arrivals, arbitrary service time distribution
6% F common to all classes, and a finite buffer of K packets (
the position
7% held by
the packet in transmission included).
9% Two classes of equal arrival rate but different interarrival variability
10% or autocorrelation receive different loss ratios, which
is the effect that
11% motivates [1]. Aggregate-only finite-buffer analyses cannot express it:
12% they
return a single blocking probability p and set T_k = lambda_k*(1-p),
13% making
the loss ratio identical across classes by construction.
15% D0 - M x M hidden transition matrix of
the arrival
MMAP
16% D1C - 1 x R cell array, D1C{k} = M x M arrival matrix of
class k.
17% D0 + sum_k D1C{k} must be an irreducible generator.
18% SVC - service time descriptor, see QSYS_MAPG1K
19% K - buffer size in packets, K >= 1
21% Options are forwarded to QSYS_MAPG1K (
'tol',
'nmax').
23% Returns a
struct with fields:
24% throughput(k) - throughput of class k [pkts/s]
25% lossRatio(k) - loss ratio of class k, in [0,1]
26% lambda(k) - arrival rate of class k [pkts/s]
27% lambdaAggregate, throughputAggregate, lossAggregate
28% p0, pK - empty/full buffer probabilities
29% pKvec - 1 x M,
P(buffer full, phase j)
30% plevel - 1 x (K+1), time-stationary
P(level = l)
31% meanQueueLength - E[number in system]
32% meanServiceTime, rho, utilization
34% Method. The aggregate MAP {D0, sum_k D1C{k}} drives QSYS_MAPG1K, whose
35% embedded chain returns
the joint law of buffer level and MAP phase. A
36%
class-k arrival leaves phase i at rate (D1C{k}*e)_i, so
the rate of
class-k
37% arrivals that meet a full buffer
is pKvec*D1C{k}*e, and
38% lambda_k = pi*D1C{k}*e, L_k = (pKvec*D1C{k}*e)/lambda_k,
39% with pi
the stationary phase law of
the aggregate. This
is exact: no
40% independence between classes
is assumed and no PASTA argument
is used,
the
41% phase resolution of pKvec doing
the work instead.
43% Relation to [1]. Reference [1] instead keeps one flow exact and replaces
44%
the rest by a Poisson stream of
the same rate, invoking Palm-Khinchin, and
45% repeats that once per flow. That approximation
is needed only when
the
46% joint arrival process
is unavailable, its exact form costing prod_n M_n
47% phases for N independent flows. When
the joint
MMAP is already at hand, as
48% it
is inside a solver that propagates MMAPs between stations,
the phase
49% resolution above
is both exact and cheaper. Use QSYS_MAPG1K_PERFLOW for
50%
the setting of [1], where flows are given as N separate MAPs.
52% Assumes a single server and a service law that
is iid and independent of
53% class. Per-class service makes
the departure rate depend on which class
54% holds
the server, which this model does not represent.
57% [1] Chydzinski, A. Per-Flow Throughput of a FIFO Buffer. Applied System
58% Innovation 2026, 9, 112.
60% See also QSYS_MAPG1K, QSYS_MAPG1K_PERFLOW, QSYS_MG1K_LOSS.
63 line_error(mfilename,
'D1C must be a cell array of per-class D1 matrices.');
69 if any(size(D1c{k}) ~= [M M])
70 line_error(mfilename, sprintf(
'D1C{%d} must be %dx%d.', k, M, M));
75r = qsys_mapg1k(D0, D1, svc, K, varargin{:});
78pit = map_prob({D0, D1});
85 lam(k) = pit*D1c{k}*e;
87 Lk(k) = (r.pKvec*D1c{k}*e)/lam(k);
91 Tk(k) = lam(k)*(1 - Lk(k));
95result.throughput = Tk;
98result.lambdaAggregate = sum(lam);
99result.throughputAggregate = sum(Tk);
100result.lossAggregate = r.lossProbability;
103result.pKvec = r.pKvec;
104result.plevel = r.plevel;
105result.meanQueueLength = r.meanQueueLength;
106result.meanServiceTime = r.meanServiceTime;
107result.utilization = r.utilization;
109result.analyzer = 'qsys_mmapg1k
';