LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
map_m1ps_sojourn.m
1function [W_bar, W_bar_n] = map_m1ps_sojourn(C, D, mu, x, varargin)
2% MAP_M1PS_SOJOURN Compute sojourn time distribution in MAP/M/1-PS queue
3%
4% W_bar = MAP_M1PS_SOJOURN(C, D, mu, x) computes the complementary
5% distribution function of the sojourn time in a MAP/M/1 processor-sharing
6% queue at the points specified in x.
7%
8% [W_bar, W_bar_n] = MAP_M1PS_SOJOURN(C, D, mu, x) also returns the
9% conditional complementary distributions W_bar_n{i} for customers finding
10% i-1 customers in the system on arrival.
11%
12% [...] = MAP_M1PS_SOJOURN(C, D, mu, x, 'Param', Value) specifies optional
13% parameters:
14% 'Epsilon' - Truncation parameter for queue length (default: 1e-11)
15% 'EpsilonPrime' - Truncation parameter for uniformization (default: 1e-10)
16% 'Verbose' - Display computation progress (default: false)
17%
18% Input:
19% C - M x M matrix governing MAP transitions without arrivals
20% D - M x M matrix governing MAP transitions with arrivals
21% mu - Service rate (scalar, mu > 0)
22% x - Vector of time points at which to evaluate W_bar(x) = Pr[W > x]
23%
24% Output:
25% W_bar - Vector of same size as x, containing Pr[W > x]
26% W_bar_n - Cell array of conditional distributions (optional)
27%
28% The processor-sharing (PS) discipline shares the server equally among
29% all customers. When n customers are present, each receives service at
30% rate 1/n.
31%
32% The algorithm implements Theorem 1 from:
33% Masuyama, H., & Takine, T. (2003). Sojourn time distribution in a
34% MAP/M/1 processor-sharing queue. Operations Research Letters, 31(6),
35% 406-412.
36%
37% Example:
38% % M/M/1-PS queue with lambda=0.8, mu=1
39% lambda = 0.8; mu = 1;
40% C = -lambda; D = lambda; % Poisson arrivals
41% x = linspace(0, 10, 100);
42% W_bar = map_m1ps_sojourn(C, D, mu, x);
43% plot(x, W_bar);
44% xlabel('x'); ylabel('Pr[W > x]');
45% title('Sojourn time distribution for M/M/1-PS');
46%
47% See also: MAP_M1PS_H_RECURSIVE, MAP_COMPUTE_R
48
49% Copyright (c) 2012-2025, Imperial College London
50% All rights reserved.
51
52%% Parse input arguments
53p = inputParser;
54addRequired(p, 'C', @(x) ismatrix(x) && size(x,1) == size(x,2));
55addRequired(p, 'D', @(x) ismatrix(x) && size(x,1) == size(x,2));
56addRequired(p, 'mu', @(x) isscalar(x) && x > 0);
57addRequired(p, 'x', @(x) isnumeric(x) && all(x >= 0));
58addParameter(p, 'Epsilon', 1e-11, @(x) isscalar(x) && x > 0 && x < 1);
59addParameter(p, 'EpsilonPrime', 1e-10, @(x) isscalar(x) && x > 0 && x < 1);
60addParameter(p, 'Verbose', false, @islogical);
61
62parse(p, C, D, mu, x, varargin{:});
63epsilon = p.Results.Epsilon;
64epsilon_prime = p.Results.EpsilonPrime;
65verbose = p.Results.Verbose;
66
67%% Validate inputs
68M = size(C, 1);
69if size(D, 1) ~= M || size(D, 2) ~= M
70 error('MAP_M1PS_SOJOURN:DimensionMismatch', 'C and D must have the same size');
71end
72
73I = eye(M);
74e = ones(M, 1);
75
76%% Compute MAP parameters
77% Stationary probability vector pi of the underlying Markov chain
78% Solve: pi*(C + D) = 0, pi*e = 1
79Q = C + D;
80A = [Q; e'];
81b = [zeros(M, 1); 1];
82pi = (A \ b)';
83
84% Mean arrival rate
85lambda = pi * D * e;
86
87if verbose
88 fprintf('MAP/M/1-PS Sojourn Time Computation\n');
89 fprintf(' M (states): %d\n', M);
90 fprintf(' lambda (arrival rate): %.4f\n', lambda);
91 fprintf(' mu (service rate): %.4f\n', mu);
92 fprintf(' rho (utilization): %.4f\n', lambda/mu);
93end
94
95% Check stability condition
96rho = lambda / mu;
97if rho >= 1
98 error('MAP_M1PS_SOJOURN:Unstable', ...
99 'System is unstable (rho = %.4f >= 1)', rho);
100end
101
102%% Compute R matrix
103if verbose
104 fprintf('Computing R matrix...\n');
105end
106R = map_compute_R(C, D, mu);
107
108%% Determine truncation point N(epsilon) for queue length
109% Find minimum N such that: (1/lambda) * sum_{n=0}^N pi_0 * R^n * D * e > 1 - epsilon
110% where pi_0 = pi * (I - R)
111pi_0 = pi * (I - R);
112
113cumsum_prob = 0;
114N_epsilon = 0;
115for n = 0:1000
116 cumsum_prob = cumsum_prob + (1/lambda) * pi_0 * (R^n) * D * e;
117 if cumsum_prob > 1 - epsilon
118 N_epsilon = n;
119 break;
120 end
121end
122
123if N_epsilon == 0
124 N_epsilon = 100; % Default fallback
125 warning('MAP_M1PS_SOJOURN:TruncationDefault', ...
126 'Could not determine N(epsilon), using default N=%d', N_epsilon);
127end
128
129if verbose
130 fprintf(' N(epsilon): %d (queue length truncation)\n', N_epsilon);
131end
132
133%% Compute uniformization parameter theta
134theta = max(abs(diag(C)));
135
136%% Initialize output
137x = x(:)'; % Ensure row vector
138num_points = length(x);
139W_bar = zeros(1, num_points);
140
141if nargout > 1
142 W_bar_n = cell(N_epsilon + 1, 1);
143 for n = 0:N_epsilon
144 W_bar_n{n+1} = zeros(1, num_points);
145 end
146end
147
148%% Compute sojourn time distribution for each x
149for idx = 1:num_points
150 x_val = x(idx);
151
152 % Determine truncation points L and R for uniformization
153 % Find L and R such that: sum_{k=L}^R Poisson(theta+mu, x_val) > 1 - epsilon_prime
154 mean_val = (theta + mu) * x_val;
155
156 % Use Poisson quantiles to find L and R
157 if mean_val > 0
158 L = max(0, floor(mean_val - 10*sqrt(mean_val)));
159 R = ceil(mean_val + 10*sqrt(mean_val));
160
161 % Refine to meet epsilon_prime requirement
162 pmf = poisspdf(L:R, mean_val);
163 cumsum_pmf = sum(pmf);
164 while cumsum_pmf < 1 - epsilon_prime && R < 10000
165 R = R + 10;
166 pmf = poisspdf(L:R, mean_val);
167 cumsum_pmf = sum(pmf);
168 end
169 else
170 L = 0;
171 R = 0;
172 end
173
174 K_max = R;
175
176 if verbose && idx == 1
177 fprintf(' K(epsilon_prime): %d (uniformization truncation)\n', K_max);
178 end
179
180 % Compute h_{n,k} for n=0,...,N_epsilon and k=0,...,K_max
181 if verbose && idx == 1
182 fprintf('Computing h_{n,k} recursion...\n');
183 end
184 h = map_m1ps_h_recursive(C, D, mu, N_epsilon, K_max);
185
186 % Compute W_bar(x) using equation (8)
187 % W_bar(x) = (1/lambda) * sum_{n=0}^{N} pi_0 * R^n * D * sum_{k=L}^{R} ...
188 % [(theta+mu)^k * x^k / k!] * exp(-(theta+mu)*x) * h_{n,k}
189
190 theta_plus_mu = theta + mu;
191 exp_factor = exp(-theta_plus_mu * x_val);
192
193 for n = 0:N_epsilon
194 % Compute pi_0 * R^n * D
195 if n == 0
196 weight = pi_0 * D;
197 else
198 weight = pi_0 * (R^n) * D;
199 end
200
201 % Compute sum over k
202 sum_k = zeros(M, 1);
203 for k = L:K_max
204 poisson_term = ((theta_plus_mu * x_val)^k / factorial(k)) * exp_factor;
205 sum_k = sum_k + poisson_term * h{n+1, k+1};
206 end
207
208 W_bar(idx) = W_bar(idx) + (1/lambda) * weight * sum_k;
209
210 % Store conditional distribution if requested
211 if nargout > 1
212 W_bar_n{n+1}(idx) = sum(sum_k) / M; % Average over states
213 end
214 end
215end
216
217if verbose
218 fprintf('Computation complete.\n');
219end
220
221end