1function tf = mam_transient_qbd_applicable(sn)
2% MAM_TRANSIENT_QBD_APPLICABLE True when transient analysis of
the model should
3% use
the Laplace-domain transient QBD solver (solver_mam_transient_qbd) rather
4% than
the libQBD/expm fast path (solver_mam_ldqbd_transient).
6% The Laplace solver
is selected
for single-server open queues whose arrival
is
7% non-Poisson (correlated/PH-renewal MAP with >1 phase) or whose service
is a
8% correlated MAP (non-renewal), which
the fast path cannot represent exactly.
9% Poisson arrival with PH/exp service (M/M/1, M/PH/1) and M/M/c stay on
the fast
12% Copyright (c) 2012-2026, Imperial College London
16if sn.nclasses ~= 1 || ~isinf(sn.njobs')
17 return; % Laplace solver handles single-class open models only
20sourceIdx = find(sn.sched == SchedStrategy.EXT);
21queueIdx = find(sn.sched == SchedStrategy.FCFS);
22if numel(sourceIdx) ~= 1 || numel(queueIdx) ~= 1
25if sn.nservers(queueIdx) ~= 1
26 return; % Laplace solver
is single-server; multiserver stays on fast path
29arrProc = sn.proc{sourceIdx}{1};
30svcProc = sn.proc{queueIdx}{1};
31Da0 = arrProc{1}; Da1 = arrProc{2};
32Ds0 = svcProc{1}; Ds1 = svcProc{2};
34arrivalIsPoisson = (size(Da0, 1) == 1);
35serviceIsRenewal = is_renewal_map(Ds0, Ds1);
37tf = ~arrivalIsPoisson || ~serviceIsRenewal;
40function tf = is_renewal_map(D0, D1)
41% A PH/renewal service, embedded as a MAP, has D1 = t * alpha (rank one):
the
42% post-completion phase does not depend on
the completing phase.
48tExit = D1 * ones(ns, 1);
49alpha = map_pie({D0, D1});
50tf = norm(D1 - tExit * alpha,
'fro') < 1e-9 * max(1, norm(D1,
'fro'));