1function [Q, levelOf] = solver_mam_ldqbd_flatten(ld)
2% SOLVER_MAM_LDQBD_FLATTEN Assemble a flat generator from LD-QBD blocks.
4% [Q, LEVELOF] = SOLVER_MAM_LDQBD_FLATTEN(LD) takes the block-tridiagonal
5% representation LD (fields Q0/Q1/Q2/Nlev as produced by solver_mam_ldqbd) and
6% returns the dense infinitesimal generator Q over the level/phase state space,
7% together with LEVELOF(s) = the queue level of flat state s.
9% Level 0
is a single (empty-queue) state; levels 1..Nlev each carry nPhases
10% phases (PH service) or a single state (exponential). Used by the SolverENV
11% state-vector analyzer to propagate an entry distribution over the LD-QBD.
13% Copyright (c) 2012-2026, Imperial College London
16Q0 = ld.Q0; Q1 = ld.Q1; Q2 = ld.Q2;
19% Per-level state-space size and offsets.
20levelSize = zeros(1, Nlev + 1);
22 levelSize(n+1) = size(Q1{n+1}, 1);
24levelStart = [0, cumsum(levelSize)]; % levelStart(n+1) = offset before level n
28levelOf = zeros(1, dim);
30 rows = levelStart(n+1) + (1:levelSize(n+1));
32 Q(rows, rows) = Q1{n+1}; % within-level
34 cols = levelStart(n+2) + (1:levelSize(n+2));
35 Q(rows, cols) = Q0{n+1}; % upward (arrival)
38 cols = levelStart(n) + (1:levelSize(n));
39 Q(rows, cols) = Q2{n}; % downward (departure)