LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
qsys_mm1_dps.m
1function [T,rho] = qsys_mm1_dps(lambda, mu, w, tol, maxCutoff)
2% [T,RHO] = QSYS_MM1_DPS(LAMBDA, MU, W, TOL, MAXCUTOFF)
3%
4% Numerically exact M/M/1 Discriminatory Processor Sharing (DPS) queue.
5%
6% Solves the multiclass DPS continuous-time Markov chain on the per-class
7% population vector (n_1..n_K): arrivals lambda(k), class-k completion rate
8% mu(k)*n_k*w(k)/sum_j n_j*w(j). The state space is truncated at a total
9% population level chosen from the geometric tail bound and doubled until the
10% per-class mean counts are stable, so the result is exact to solver precision
11% and conserves the M/M/1 total for equal service rates by construction.
12%
13% Input:
14% lambda - per-class Poisson arrival rates (1,K)
15% mu - per-class exponential service rates (1,K)
16% w - per-class DPS weights (1,K), positive
17% tol - convergence tolerance on the mean counts (default 1e-10)
18% maxCutoff - hard bound on the truncation level (default 2048)
19%
20% Output:
21% T - per-class mean response times (1,K) via Little's law
22% rho - total utilization sum_k lambda(k)/mu(k)
23%
24% Copyright (c) 2012-2026, Imperial College London
25% All rights reserved.
26
27if nargin < 4 || isempty(tol), tol = 1e-10; end
28if nargin < 5 || isempty(maxCutoff), maxCutoff = 2048; end
29
30lambda = lambda(:)'; mu = mu(:)'; w = w(:)';
31K = length(lambda);
32if any(lambda <= 0) || any(mu <= 0) || any(w <= 0)
33 line_error(mfilename,'lambda, mu, w must all be positive');
34end
35rho = sum(lambda ./ mu);
36if rho >= 1
37 line_error(mfilename,'System is unstable: utilization rho >= 1');
38end
39
40N = max(16, ceil(log(tol)/log(rho)));
41N = min(N, maxCutoff);
42ENprev = solveTrunc(N);
43while N < maxCutoff
44 N2 = min(2*N, maxCutoff);
45 EN = solveTrunc(N2);
46 if max(abs(EN - ENprev)) < tol
47 ENprev = EN;
48 break
49 end
50 ENprev = EN; N = N2;
51 if N2 == maxCutoff, break; end
52end
53T = ENprev ./ lambda;
54
55 function EN = solveTrunc(Ncut)
56 % enumerate states with total population <= Ncut
57 grids = cell(1,K);
58 [grids{:}] = ndgrid(0:Ncut);
59 S = zeros(numel(grids{1}), K);
60 for kk=1:K, S(:,kk) = grids{kk}(:); end
61 S = S(sum(S,2) <= Ncut, :);
62 n = size(S,1);
63 keys = S * ((Ncut+1).^(0:K-1))';
64 idx = sparse(keys+1, 1, 1:n);
65 rows = []; cols = []; vals = [];
66 tot = sum(S,2);
67 den = S * w';
68 for kk=1:K
69 % arrivals in class kk (blocked at the truncation level)
70 en = tot < Ncut;
71 src = find(en);
72 dstKeys = keys(src) + (Ncut+1)^(kk-1);
73 dst = full(idx(dstKeys+1));
74 rows = [rows; src]; cols = [cols; dst]; vals = [vals; repmat(lambda(kk), numel(src), 1)]; %#ok<AGROW>
75 % departures in class kk (DPS capacity split)
76 en = S(:,kk) > 0;
77 src = find(en);
78 r = mu(kk) .* S(src,kk) .* w(kk) ./ den(src);
79 dstKeys = keys(src) - (Ncut+1)^(kk-1);
80 dst = full(idx(dstKeys+1));
81 rows = [rows; src]; cols = [cols; dst]; vals = [vals; r]; %#ok<AGROW>
82 end
83 Q = sparse(rows, cols, vals, n, n);
84 Q = Q - diag(sum(Q,2));
85 A = Q';
86 A(1,:) = 1;
87 b = zeros(n,1); b(1) = 1;
88 pi = A \ b;
89 EN = pi' * S;
90 end
91end
Definition Station.m:245