1function result = qsys_phm1(alpha, T, mu)
2% QSYS_PHM1 Exact PH/M/1 (GI/M/1 with phase-type inter-arrivals).
4% RESULT = QSYS_PHM1(ALPHA, T, MU) solves the GI/M/1 sigma-root
5% sigma = psi_A(mu*(1 - sigma)), psi_A(s) = ALPHA*(s*I - T)\(-T*1)
6% and returns time-average performance metrics.
9% ALPHA - PH entry probability row vector (1 x k)
10% T - PH sub-generator (k x k)
11% MU - Exponential service rate (positive scalar)
13% RESULT
struct fields:
14% meanQueueLength - L = rho/(1 - sigma)
15% meanWaitingQueue - Lq = rho*sigma/(1 - sigma)
16% meanWaitingTime - Wq = Lq/lambda
17% meanSojournTime - W = Wq + 1/MU
18% utilization - rho = lambda/MU
19% sigma - GI/M/1 root in (0, 1)
20% analyzer - identifier string
22% See also qsys_gm1, qsys_dmc
25 line_error(mfilename, 'Service rate MU must be positive');
27alpha = alpha(:)'; % row vector
30 line_error(mfilename, 'T must be square');
33 line_error(mfilename, 'ALPHA length must match T dimension');
37t_vec = -T * ones_k; % column
39% Mean inter-arrival = alpha * (-T)\1
40mean_ia = alpha * ((-T) \ ones_k);
42 line_error(mfilename, sprintf('Non-positive mean inter-arrival: %g', mean_ia));
44lambda = 1.0 / mean_ia;
47 line_error(mfilename, sprintf('Load rho=%g must be strictly less than 1', rho));
51lst = @(s) alpha * ((s*I - T) \ t_vec);
52f = @(sigma) sigma - lst(mu*(1 - sigma));
55 sigma = fzero(f, [1e-12, 1 - 1e-12]);
57 % Fall back to fixed-point iteration if bracket fails
60 sNew = lst(mu*(1 - sigma));
61 if abs(sNew - sigma) < 1e-13
70Lq = rho * sigma / (1 - sigma);
75result.meanQueueLength = L;
76result.meanWaitingQueue = Lq;
77result.meanWaitingTime = Wq;
78result.meanSojournTime = W;
79result.utilization = rho;
81result.analyzer = 'PHM1:fzero';