1function [QN, UN, RN, TN, pi, G] = solver_mam_bmap_map_1(bmap, service_map, options)
2% SOLVER_MAM_BMAP_MAP_1 Solves a BMAP/MAP/1 queue
using M/G/1 type analysis
4% [QN, UN, RN, TN, PI, G] = SOLVER_MAM_BMAP_MAP_1(BMAP, SERVICE_MAP) solves a
5% BMAP/MAP/1 queue with batch Markovian arrival process BMAP and Markovian
6% service process SERVICE_MAP. Uses M/G/1 type matrix-analytic methods via
10% bmap - BMAP
object or cell array {D0, D1, D2, ..., DK} where
11% D0: transitions without arrivals
12% Dk: transitions triggering batch size k arrivals (k >= 1)
13% service_map - MAP
object or cell array {S0, S1} where
14% S0: transitions without service completions
15% S1: transitions triggering service completions
16% options - (optional) Options structure with fields:
17% .nMoments: number of queue length moments to compute (default: 3)
20% QN - Mean queue length (1st moment)
21% UN - Server utilization
22% RN - Mean response time
23% TN - Throughput (arrival rate)
24% pi - Aggregated stationary probability [pi0, pi1, pi2+pi3+...]
25% G - G matrix (minimal nonnegative solution)
27% The BMAP/MAP/1 queue
is modeled as an M/G/1 type Markov chain where:
28% - Level corresponds to queue length
29% - Phases correspond to combined (BMAP phase, MAP phase) states
31% M/G/1 type structure (level can jump UP by any amount, DOWN by exactly 1):
32% A0 = I_ma ⊗ S1 (service completion, level -1)
33% A1 = D0 ⊗ I_ms + I_ma ⊗ S0 (phase changes, level 0)
34% A_{k+1} = D_k ⊗ I_ms (batch arrival size k, level +k)
37% - Stathopoulos, Riska, Hua, Smirni: ETAQA algorithm
38% - MAMSolver: www.cs.wm.edu/MAMSolver
40% Copyright (c) 2012-2026, Imperial College London
43%% Input validation and setup
47if ~isfield(options,
'nMoments')
51% Extract BMAP matrices
53 K = bmap.getMaxBatchSize();
55 D{1} = bmap.D(0); % D0
57 D{k+1} = bmap.D(1, k); % Dk (batch size k)
61 K = length(D) - 1; % max batch size
63 error(
'BMAP must be a BMAP object or cell array {D0, D1, ..., DK}');
66% Extract MAP service matrices
67if isa(service_map,
'MAP')
68 S0 = service_map.D(0);
69 S1 = service_map.D(1);
70elseif iscell(service_map) && length(service_map) == 2
74 error(
'service_map must be a MAP object or cell array {S0, S1}');
78ma = size(D{1}, 1); % BMAP phases
79ms = size(S0, 1); % MAP service phases
80m = ma * ms; % Combined phases per level
84 if size(D{k}, 1) ~= ma || size(D{k}, 2) ~= ma
85 error(
'All BMAP matrices must be %dx%d', ma, ma);
88if size(S0, 1) ~= ms || size(S0, 2) ~= ms || size(S1, 1) ~= ms || size(S1, 2) ~= ms
89 error(
'MAP service matrices must be %dx%d', ms, ms);
92%% Construct M/G/1 type matrices
using Kronecker products
93% A = [A0, A1, A2, ..., A_{K+1}]
for levels >= 1
94% A0 = I_ma ⊗ S1 (service completion, level -1)
95% A1 = D0 ⊗ I_ms + I_ma ⊗ S0 (phase changes, level 0)
96% A_{k+1} = D_k ⊗ I_ms
for k >= 1 (batch arrivals size k, level +k)
101A = zeros(m, m * (K + 2));
103% A0 = I_ma ⊗ S1 (service completion)
107% A1 = D0 ⊗ I_ms + I_ma ⊗ S0 (phase changes only)
108A1 = kron(D{1}, I_ms) + kron(I_ma, S0);
111% A_{k+1} = D_k ⊗ I_ms
for k >= 1 (batch arrivals)
113 Ak = kron(D{k+1}, I_ms);
114 A(:, (k+1)*m + 1 : (k+2)*m) = Ak;
117% B = [B0, B1, B2, ..., BK]
for level 0 (empty queue)
118% At level 0, no service can occur, so we add S1 back to the diagonal block
119% B0 = D0 ⊗ I_ms + I_ma ⊗ (S0 + S1)
120% B_k = D_k ⊗ I_ms
for k >= 1
122B = zeros(m, m * (K + 1));
124% B0: At level 0, no service (add S1 back as self-loop)
125B0 = kron(D{1}, I_ms) + kron(I_ma, S0 + S1);
128% B_k = D_k ⊗ I_ms
for k >= 1 (batch arrivals from empty queue)
130 Bk = kron(D{k+1}, I_ms);
131 B(:, k*m + 1 : (k+1)*m) = Bk;
134%% Verify stability condition
135% Compute arrival rate from BMAP
137D1_total = zeros(ma, ma);
139 D1_total = D1_total + D{k+1};
142% Stationary distribution of BMAP
143pi_bmap = map_prob({D0, D1_total});
146% Total customer arrival rate: sum_k (k * π * Dk * e)
149 rate_k = pi_bmap * D{k+1} * e_ma;
150 lambda_total = lambda_total + k * rate_k;
153% Compute service rate from MAP
154pi_map = map_prob({S0, S1});
156mu = pi_map * S1 * e_ms; % Service rate
159rho = lambda_total / mu;
162 warning(
'solver_mam_bmap_map_1:Unstable', ...
163 'System is unstable (rho = %.4f >= 1). Results may be invalid.', rho);
166%% Compute G matrix
using MG1_G_ETAQA
169%% Compute stationary probabilities
using MG1_pi_ETAQA
170pi = MG1_pi_ETAQA(B, A, G);
172%% Compute queue length moments
using MG1_qlen_ETAQA
173qlen_moments = zeros(1, options.nMoments);
174for n = 1:options.nMoments
175 qlen_moments(n) = MG1_qlen_ETAQA(B, A, pi, n);
178%% Compute performance metrics
179QN = qlen_moments(1); % Mean queue length (E[N])
180UN = rho; % Utilization
181TN = lambda_total; % Throughput (total arrival rate)
182RN = QN / TN; % Mean response time (Little
's law: E[R] = E[N] / λ)