LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
solver_mam_transient_qbd.m
1function [Qt, Ut, Tt] = solver_mam_transient_qbd(sn, options)
2% SOLVER_MAM_TRANSIENT_QBD Transient analysis of a single-class open queue via
3% the Laplace-domain transient QBD method plus numerical inverse Laplace.
4%
5% Supports single-server MAP/MAP/1 (infinite buffer) and MAP/MAP/1/N (finite
6% buffer), where arrival and service are read uniformly as (D0,D1) MAPs from
7% sn.proc; this subsumes M/M/1, M/PH/1 and correlated-MAP arrival/service that
8% the libQBD/expm fast path (solver_mam_ldqbd_transient) cannot represent.
9%
10% The transient level-to-level transform V(s,0,m) is computed by
11% mam_transient2_open (infinite) or mam_transient2 (finite) and inverted with
12% the CME-based matrix inverse Laplace transform. Metrics returned in the
13% [metric, time] layout used by getTranAvg.
14%
15% Copyright (c) 2012-2026, Imperial College London
16% All rights reserved.
17
18M = sn.nstations;
19K = sn.nclasses;
20if K ~= 1
21 line_error(mfilename, 'Transient QBD method requires a single-class model.');
22end
23N = sn.njobs';
24if ~isinf(N)
25 line_error(mfilename, 'Transient QBD method requires an open model.');
26end
27
28sourceIdx = find(sn.sched == SchedStrategy.EXT);
29queueIdx = find(sn.sched == SchedStrategy.FCFS);
30if numel(sourceIdx) ~= 1 || numel(queueIdx) ~= 1
31 line_error(mfilename, 'Transient QBD method requires exactly one Source and one FCFS Queue.');
32end
33if sn.nservers(queueIdx) ~= 1
34 line_error(mfilename, 'Transient QBD (Laplace) method supports single-server queues only.');
35end
36
37%% Arrival and service MAPs (uniform (D0,D1) representation)
38arrProc = sn.proc{sourceIdx}{1};
39svcProc = sn.proc{queueIdx}{1};
40Da0 = arrProc{1}; Da1 = arrProc{2};
41Ds0 = svcProc{1}; Ds1 = svcProc{2};
42na = size(Da0, 1);
43ns = size(Ds0, 1);
44Ina = eye(na); Ins = eye(ns);
45
46% Repeating-level blocks (levels >= 1): matches qbd_rg convention.
47Lrep = krons(Da0, Ds0); % local, both phases evolve
48Frep = kron(Da1, Ins); % arrival, level up
49Brep = kron(Ina, Ds1); % service completion, level down
50
51% Level-0 (empty) block: service phase frozen, only arrival evolves.
52Lv0 = kron(Da0, Ins);
53F0 = kron(Da1, Ins);
54B0 = kron(Ina, Ds1);
55
56% Initial distribution: empty system, stationary arrival and service phases.
57pi_arr = map_prob({Da0, Da1});
58pi_svc = map_prob({Ds0, Ds1});
59pi0 = kron(pi_arr, pi_svc); % 1 x (na*ns), level-0 phase distribution
60
61% Service-completion rate vector over (arrival,service) phases at a busy level.
62sExit = Ds1 * ones(ns, 1);
63wDep = kron(ones(na, 1), sExit); % departure-rate weight, (na*ns) x 1
64wOne = ones(na * ns, 1);
65
66bufCap = sn.cap(queueIdx);
67isFinite = ~isinf(bufCap);
68
69%% Time grid and ILT budget
70T_start = options.timespan(1);
71T_end = options.timespan(2);
72dur = T_end - T_start;
73nTimePoints = min(101, max(11, round(dur * 10)));
74times = linspace(T_start, T_end, nTimePoints)';
75% ILT singular at t=0, fill empty-system IC directly; see _kb/06-solver-catalog.md for rationale
76posMask = times > 0;
77tpos = times(posMask);
78if isfield(options, 'iter_max') && ~isempty(options.iter_max) && options.iter_max > 1
79 maxFnEvals = min(1000, max(11, round(options.iter_max)));
80else
81 maxFnEvals = 100;
82end
83
84if isFinite
85 Ncap = bufCap;
86 % Closed piecewise QBD: T=[0,Ncap], K=1 regime.
87 % Lv{1}=level 0, L{1}=interior repeating, Lv{2}=top level Ncap.
88 LvTop = kron(Da0 + Da1, Ins) + kron(Ina, Ds0); % arrivals blocked (lost) at full buffer
89 Bc = {Brep};
90 Lc = {Lrep};
91 Fc = {Frep};
92 Lvc = {Lv0, LvTop};
93 Tc = [0, Ncap];
94 % Level dimensions: level 0 and levels 1..Ncap all na*ns here.
95 lvsz = na * ns;
96
97 % EN(s), U(s), Dep(s) as scalar Laplace functions inverted per metric.
98 EN = zeros(size(times)); DEP = zeros(size(times)); Uval = zeros(size(times));
99 EN(posMask) = matlab_ilt(@(s) laplace_EN_finite(s, Bc, Lc, Fc, Lvc, Tc, Ncap, pi0), tpos, maxFnEvals);
100 P0 = matlab_ilt(@(s) laplace_P0(s, Bc, Lc, Fc, Lvc, Tc, pi0, wOne, false), tpos, maxFnEvals);
101 DEP(posMask) = matlab_ilt(@(s) laplace_DEP_finite(s, Bc, Lc, Fc, Lvc, Tc, Ncap, pi0, wDep), tpos, maxFnEvals);
102 Uval(posMask) = 1 - P0;
103else
104 % Open piecewise QBD: T=[0,1], K=2 (regime 1 = level 0 boundary; regime 2 repeats).
105 Bo = {B0, Brep};
106 Lo = {[], Lrep};
107 Fo = {F0, Frep};
108 Lvo = {Lv0, Lrep};
109 To = [0, 1];
110
111 % Homogeneous open case: V(s,0,m) = V(s,0,1) * R^(m-1) for m>=1, so the
112 % level sums have exact closed forms (no truncation):
113 % E[N](s) = pi0 * V(s,0,1) * (I-R)^-2 * 1
114 % Tput(s) = pi0 * V(s,0,1) * (I-R)^-1 * wDep
115 % P0(s) = pi0 * V(s,0,0) * 1
116 EN = zeros(size(times)); DEP = zeros(size(times)); Uval = zeros(size(times));
117 EN(posMask) = matlab_ilt(@(s) laplace_EN_open(s, Bo, Lo, Fo, Lvo, To, pi0), tpos, maxFnEvals);
118 P0 = matlab_ilt(@(s) laplace_P0(s, Bo, Lo, Fo, Lvo, To, pi0, wOne, true), tpos, maxFnEvals);
119 DEP(posMask) = matlab_ilt(@(s) laplace_DEP_open(s, Bo, Lo, Fo, Lvo, To, pi0, wDep), tpos, maxFnEvals);
120 Uval(posMask) = 1 - P0;
121end
122
123%% Package results
124Qt = cell(M, K); Ut = cell(M, K); Tt = cell(M, K);
125Qt{queueIdx, 1} = [EN, times];
126Ut{queueIdx, 1} = [Uval, times];
127Tt{queueIdx, 1} = [DEP, times];
128end
129
130% ------------------------------------------------------------------------
131function val = laplace_P0(s, B, L, F, Lv, T, pi0, wOne, isOpen)
132% Laplace transform of P(N(t)=0): pi0 * V(s,0,0) * 1.
133if isOpen
134 V = mam_transient2_open(B, L, F, Lv, T, 0, 0, s);
135else
136 V = mam_transient2(B, L, F, Lv, T, 0, 0, s);
137end
138val = pi0 * V * wOne;
139end
140
141% ------------------------------------------------------------------------
142function val = laplace_EN_finite(s, B, L, F, Lv, T, Ncap, pi0)
143% sum_{m=0}^{Ncap} m * pi0 * V(s,0,m) * 1.
144acc = 0;
145for m = 1:Ncap
146 V = mam_transient2(B, L, F, Lv, T, 0, m, s);
147 acc = acc + m * (pi0 * V * ones(size(V, 2), 1));
148end
149val = acc;
150end
151
152% ------------------------------------------------------------------------
153function val = laplace_DEP_finite(s, B, L, F, Lv, T, Ncap, pi0, wDep)
154% sum_{m=1}^{Ncap} pi0 * V(s,0,m) * wDep (departure rate).
155acc = 0;
156for m = 1:Ncap
157 V = mam_transient2(B, L, F, Lv, T, 0, m, s);
158 acc = acc + pi0 * V * wDep;
159end
160val = acc;
161end
162
163% ------------------------------------------------------------------------
164function val = laplace_EN_open(s, B, L, F, Lv, T, pi0)
165% E[N](s) = pi0 * V(s,0,1) * (I-R)^-2 * 1 (exact geometric first moment).
166K = length(T);
167IK = eye(size(L{K}, 1));
168[~, R] = qbd_fundmat(B{K}, L{K} - s*IK, F{K}, 'GR');
169V1 = mam_transient2_open(B, L, F, Lv, T, 0, 1, s);
170ImR = IK - R;
171val = pi0 * V1 * (ImR \ (ImR \ ones(size(IK, 1), 1)));
172end
173
174% ------------------------------------------------------------------------
175function val = laplace_DEP_open(s, B, L, F, Lv, T, pi0, wDep)
176% Tput(s) = pi0 * V(s,0,1) * (I-R)^-1 * wDep (exact geometric zeroth moment).
177K = length(T);
178IK = eye(size(L{K}, 1));
179[~, R] = qbd_fundmat(B{K}, L{K} - s*IK, F{K}, 'GR');
180V1 = mam_transient2_open(B, L, F, Lv, T, 0, 1, s);
181val = pi0 * V1 * ((IK - R) \ wDep);
182end