LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
qbd_setupdelayoff.m
1%{ @file qbd_setupdelayoff.m
2 % @brief Queue-length analysis for system with setup delay and turn-off
3 %
4 % @author LINE Development Team
5%}
6
7%{
8 % @brief Analyzes queue length for system with setup and turn-off phases
9 %
10 % @details
11 % This function performs queue-length analysis for a queueing system with
12 % setup delay and turn-off periods using QBD methods.
13 %
14 % @par Syntax:
15 % @code
16 % QN = qbd_setupdelayoff(lambda, mu, alpharate, alphascv, betarate, betascv)
17 % @endcode
18 %
19 % @par Parameters:
20 % <table>
21 % <tr><th>Name<th>Description
22 % <tr><td>lambda<td>Arrival rate
23 % <tr><td>mu<td>Service rate
24 % <tr><td>alpharate<td>Rate of setup delay phase
25 % <tr><td>alphascv<td>Squared coefficient of variation for setup delay
26 % <tr><td>betarate<td>Rate of turn-off phase
27 % <tr><td>betascv<td>Squared coefficient of variation for turn-off period
28 % </table>
29 %
30 % @par Returns:
31 % <table>
32 % <tr><th>Name<th>Description
33 % <tr><td>QN<td>Average queue length
34 % </table>
35%}
36function QN = qbd_setupdelayoff(lambda, mu, alpharate, alphascv, betarate, betascv)
37
38% The phases are given as rates, so an exponential one is built directly from
39% its rate rather than round-tripped through its mean. APH.fitMeanAndSCV maps
40% any mean at or below GlobalConstants.FineTol to Exp(Inf), and an Immediate
41% setup or delay-off has rate GlobalConstants.Immediate whose mean is exactly
42% FineTol; the round trip therefore turned a finite 1e8 rate into an infinite
43% one, put -Inf in the generator, and collapsed QBD_pi onto the boundary level,
44% so the level loop below ran past the end of pn. For SCV 1 the fit returns
45% Exp(1/MEAN) anyway, so this is the same process everywhere else.
46% Both phases are taken in canonical Coxian form, whose entry vector is [1 0 ..]
47% for every SCV. The chain below overloads its phase indices (at the boundary
48% level phase 1 is the off server and phases na+1.. are the delay-off; above it
49% phases 1..na are the setup and na+1 is the busy server), so a level-up
50% transition cannot also redistribute the phase: an arrival to an off server has
51% to enter the setup at phase 1. APH.fitMeanAndSCV violates that for SCV > 1,
52% where it returns a hyperexponential entered at phase 2 with probability 3/4,
53% which the chain then silently entered at phase 1 regardless.
54alpha = coxian_phase(alpharate, alphascv);
55na = length(alpha{1});
56% Completion rate of each phase. A Coxian may complete from any phase, not only
57% from the last one, so these are read per phase rather than off the diagonal.
58ta = -sum(alpha{1},2);
59
60beta = coxian_phase(betarate, betascv);
61nb = length(beta{1});
62tb = -sum(beta{1},2);
63n = na+nb;
64
65F = zeros(n); % forward transitions
66B = zeros(n); % backward transitions
67for i=1:na
68 F(i,i) = lambda;
69end
70for i=1:nb
71 F(na+i,na+1) = lambda;
72end
73F(na+1,na+1) = lambda;
74B(na+1,na+1) = mu;
75
76L = zeros(n); % local transitions
77for i=1:na
78 % Whole generator row, so a phase that both advances and completes (any
79 % Coxian with SCV > 1) contributes both; reading only the diagonal and the
80 % strict upper triangle assumed a pure series, which holds only for SCV <= 1.
81 L(i,1:na) = alpha{1}(i,1:na);
82 L(i,i) = L(i,i) - lambda;
83 L(i,na+1) = ta(i); % setup completes from phase i -> busy server
84end
85L(na+1,na+1) = -mu -lambda;
86for i=2:nb
87 L(na+i,na+i) = -lambda;
88end
89%[B,L,F]
90
91L0 = zeros(na+nb); % local transitions at the boundary level
92for i=1:na
93 L0(i,i) = -lambda;
94end
95for i=1:nb
96 % As above, the whole generator row: the delay-off may expire from any
97 % phase, and its phase-to-phase rate is the generator entry, not the
98 % diagonal (they coincide only for a series phase).
99 L0(na+i,na+(1:nb)) = beta{1}(i,1:nb);
100 L0(na+i,na+i) = L0(na+i,na+i) - lambda;
101 L0(na+i,1) = tb(i); % delay-off expires from phase i -> server off
102end
103%[L0,F]
104
105[~,R,~] = QBD_CR(B,L,F);
106pn = QBD_pi(B,L0,R);
107
108% Mean queue length: QBD_pi returns the level probabilities as a flat vector
109% of n phases per level, so level ni occupies pn(ni*n+1 : (ni+1)*n), exactly n
110% entries. Summing n+1 of them while advancing by n let each window reach into
111% the next level, so one phase per level was counted twice, under two different
112% weights, and the terminating check then dropped the last level: the queue
113% length came out high by up to 15% (worse the slower the setup, which is where
114% the overlapped phases hold most mass). Level 0 is skipped, holding no jobs.
115QN = 0; % queue-lengths
116j = n+1;
117ni = 0;
118while j+n-1 <= length(pn)
119 ni = ni + 1;
120 QN = QN + ni*sum(pn(j:(j+n-1)));
121 j = j +n;
122end
123end
124
125function p = coxian_phase(rate, scv)
126% P = COXIAN_PHASE(RATE, SCV) - canonical PH representation of a phase given
127% its rate, entered at phase 1 for every SCV. Exponential phases are built from
128% the rate directly, which is exact and avoids the mean-based FineTol cutoff in
129% the fitters.
130if scv == 1.0
131 p = Exp(rate).getProcess;
132else
133 p = Coxian.fitMeanAndSCV(1/rate, scv).getProcess;
134end
135end
Definition Station.m:245