2 % @brief Solves a RAP/RAP/1 queue
using QBD methods
4 % @author LINE Development Team
8 % @brief Analyzes RAP/RAP/1 queue
using Quasi-Birth-Death process
11 % This function solves a RAP/RAP/1 queue (Rational Arrival Process)
using
12 % QBD methods, computing throughput, queue length, utilization, and other
13 % performance metrics.
15 % The two RAPs are INDEPENDENT of each other, so
the QBD phase space
is the
16 % product of
the two phase spaces and
the blocks
factor as Kronecker
17 % products. This function
is the thin product-space wrapper;
the analysis
18 % itself
is the block-level core qbd_rap.m, which solves an arbitrary QBD
19 % with RAP components. A model whose arrival process and sequence of
20 % service times share a phase space, and are therefore cross-correlated,
21 % has no such product structure and must call qbd_rap directly.
24 % N. G. Bean and B. F. Nielsen,
"Quasi-Birth-and-Death Processes with
25 % Rational Arrival Process Components", Stochastic Models, 26(3), 2010,
26 % pp. 309-334. The analysis rests on
the prediction-process interpretation
27 % of a RAP due to Asmussen and Bladt, which
is what allows a QBD argument
28 % to be carried over to matrices that are not nonnegative. The same
29 % prediction process underlies
the conditional-vector RAP sampler in
32 % @par Phase ordering:
33 % The QBD phase
is the pair (arrival phase, service phase) laid out with
34 %
the ARRIVAL phase major and
the service phase minor, i.e.
the phase index
35 %
is (a-1)*ns + s. That
is the ordering produced by kron(RAPa, eye(ns)) and
36 % kron(eye(na), RAPs), and pqueue
is indexed by it downstream in
37 % solver_mam_basic, so
the two Kronecker factors must not be swapped.
41 % [XN, QN, UN, pqueue, R, eta, G, B, L, F] = qbd_raprap1(RAPa, RAPs)
42 % [XN, QN, UN, pqueue, R, eta, G, B, L, F] = qbd_raprap1(RAPa, RAPs, util)
47 % <tr><th>Name<th>Description
48 % <tr><td>RAPa<td>Arrival process (RAP)
49 % <tr><td>RAPs<td>Service process (RAP)
50 % <tr><td>util<td>(Optional) Target utilization to scale service rate
55 % <tr><th>Name<th>Description
56 % <tr><td>XN<td>System throughput
57 % <tr><td>QN<td>Mean queue length
58 % <tr><td>UN<td>Utilization
59 % <tr><td>pqueue<td>Queue length distribution
60 % <tr><td>R<td>Rate matrix R
61 % <tr><td>eta<td>Caudal characteristic
62 % <tr><td>G<td>Rate matrix G
63 % <tr><td>B<td>Backward transition block
64 % <tr><td>L<td>Local transition block
65 % <tr><td>F<td>Forward transition block
68function [XN,QN,UN,pqueue,R,eta,G,B,L,F]=qbd_raprap1(RAPa,RAPs,util)
69% [XN,QN,UN,PQUEUE,R,ETA]=QBD_RAPRAP1(RAPA,RAPS,UTIL)
74if nargin>=3 %exist(
'util',
'var')
75 RAPs = map_scale(RAPs,util/map_lambda(RAPa));
78% QBD blocks of
the RAP/RAP/1 queue: a level
is the number in system, a
79% phase
is the (arrival,service) RAP phase pair, arrival phase major. The
80% level rises on an arrival (F), falls on a service completion (B), and
the
81% two RAPs evolve independently between level changes (L,
the Kronecker sum
82% of
the two hidden generators). At level 0
the queue
is empty, so no
83% service completion can occur and only
the arrival RAP evolves:
the
84% boundary local block
is B1 = kron(Ca,I) and
the boundary up-block
is F.
85F = kron(RAPa{2},eye(ns)); % arrivals, level up
86L = kron(RAPa{1},eye(ns)) + kron(eye(na),RAPs{1});
87B = kron(eye(na),RAPs{2}); % service completions, level down
88B1 = kron(RAPa{1},eye(ns));
90% Theorem 7 of Bean and Nielsen (2010), in qbd_rap.m: G from
the quadratic
91% matrix equation, U = L + F*G, R = F*inv(-U), and pi0 from
the boundary
92% equation pi0*(B1 + R*B) = 0 normalised by pi0*inv(I-R)*e = 1.
93[~,~,R,G,~,eta,~,pi0] = qbd_rap(F, L, B, F, B1, 0);
95% Level series. The truncation rule
is the one of QBD_pi with MaxNumComp
96% 100: accumulate levels until
the mass reaches 1-1e-10, capped at 101
97% level vectors. qbd_rap returns
the exact mean queue length in closed
98% form, but
this function keeps reporting
the truncated series because
99% pqueue
is the documented
return value and downstream consumers (and
the
100% JAR and Python ports) must cut
the tail at exactly
the same point,
101% otherwise
the means disagree at
the 1e-9 level.
106while sumpi < 1-1e-10 && numit < 1+maxNumComp
107 pqueue(numit+1,1:(na*ns)) = pqueue(numit,:)*R;
109 sumpi = sumpi + sum(pqueue(numit,:));
112numLevels = size(pqueue,1);
113levelProb = sum(pqueue,2);
114QN = (0:(numLevels-1))*levelProb;
119 UN= 1 - sum(pqueue(1,:));