LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
solver_mam_passage_time.m
1function [RD] = solver_mam_passage_time(sn, PH, options)
2% [RD] = SOLVER_MAM_PASSAGE_TIME(QN, PH, OPTIONS)
3
4% Copyright (c) 2012-2026, Imperial College London
5% All rights reserved.
6
7%% generate local state spaces
8M = sn.nstations;
9K = sn.nclasses;
10N = sn.njobs';
11rt = sn.rt;
12V = sn.visits;
13
14% Get number of CDF points from options
15if isfield(options, 'config') && isfield(options.config, 'num_cdf_pts')
16 n_cdf_pts = options.config.num_cdf_pts;
17else
18 n_cdf_pts = 100;
19end
20
21Q = zeros(M,K);
22U = zeros(M,K);
23R = zeros(M,K);
24T = zeros(M,K);
25C = zeros(1,K);
26X = zeros(1,K);
27
28if M==2 && all(isinf(N))
29 % open queueing system (one node is the external world)
30 pie = {};
31 S = {};
32 for ist=1:M
33 switch sn.sched(ist)
34 case SchedStrategy.EXT
35 na = cellfun(@(x) length(x{1}),{PH{ist}{:}});
36 A = {PH{ist}{1}{1},PH{ist}{1}{2},PH{ist}{1}{2}};
37 for k=2:K
38 A = mmap_super(A,{PH{ist}{k}{1},PH{ist}{k}{2},PH{ist}{k}{2}});
39 end
40 idx_arv = ist;
41 case {SchedStrategy.FCFS, SchedStrategy.HOL, SchedStrategy.FCFSPRPRIO}
42 row = size(S,1) + 1;
43 for k=1:K
44 PH{ist}{k} = map_scale(PH{ist}{k}, map_mean(PH{ist}{k})/sn.nservers(ist));
45 pie{k} = map_pie(PH{ist}{k});
46 S{k} = PH{ist}{k}{1};
47 end
48 idx_q = ist;
49 is_ps = false;
50 case SchedStrategy.PS
51 % Processor-sharing queue
52 row = size(S,1) + 1;
53 for k=1:K
54 % For PS, service times remain exponential (no scaling needed for distribution)
55 S{k} = PH{ist}{k}{1}; % Service process subgenerator
56 pie{k} = map_pie(PH{ist}{k});
57 end
58 idx_q = ist;
59 is_ps = true;
60 otherwise
61 line_error(mfilename,'Unsupported scheduling strategy');
62 end
63 end
64
65 if any(sn.classprio ~= sn.classprio(1)) % if priorities are not identical
66 [uK,iK] = unique(sn.classprio);
67 if length(uK) == length(sn.classprio) % if all priorities are different
68 if sn.sched(ist)==SchedStrategy.FCFSPRPRIO
69 [Ret{1:2*K}] = MMAPPH1PRPR({A{[1,3:end]}}, {pie{:}}, {S{:}}, 'stDistrPH');
70 else % HOL (non-preemptive)
71 [Ret{1:2*K}] = MMAPPH1NPPR({A{[1,3:end]}}, {pie{:}}, {S{:}}, 'stDistrPH');
72 end
73 else
74 line_error(mfilename,'SolverMAM requires either identical priorities or all distinct priorities');
75 end
76 else
77 RD = cell(M,K);
78
79 if is_ps
80 % MAP/M/1-PS queue: use specialized sojourn time distribution algorithm
81 % Check that service processes are exponential (M)
82 for k=1:K
83 if size(S{k},1) ~= 1
84 line_error(mfilename,'PS queue requires exponential (Markovian) service times');
85 end
86 end
87
88 % For single-class case, directly compute sojourn time CDF
89 if K == 1
90 % Extract MAP arrival parameters
91 C_map = A{1}; % MAP C matrix
92 D_map = A{2}; % MAP D matrix
93
94 % Extract exponential service rate
95 mu = -S{1}(1,1); % Service rate (S is negative generator)
96
97 % Estimate CDF range
98 % First get approximate mean from steady-state
99 lambda = map_lambda({C_map, D_map});
100 rho = lambda / mu;
101 approx_mean = 1 / (mu * (1 - rho)); % Approximate M/M/1-PS mean
102
103 % Generate x points (use similar range as FCFS case)
104 x_max = approx_mean * 10; % Conservative upper bound
105 x_vals = linspace(0, x_max, n_cdf_pts);
106
107 % Call MAP/M/1-PS sojourn time CDF function
108 W_bar = map_m1ps_cdfrespt(C_map, D_map, mu, x_vals);
109
110 % Convert to CDF format (currently W_bar is complementary CDF)
111 F = 1 - W_bar(:);
112
113 % Store results
114 RD{idx_arv,1} = [];
115 RD{idx_q,1} = [F, x_vals(:)];
116 else
117 % Multi-class PS: aggregate arrivals into single MAP
118 % Extract individual service rates
119 mu_vec = zeros(1,K);
120 for k=1:K
121 mu_vec(k) = -S{k}(1,1);
122 end
123
124 % Check if all service rates are equal (required for current implementation)
125 if any(abs(mu_vec - mu_vec(1)) > GlobalConstants.FineTol)
126 line_error(mfilename,'Multi-class PS currently requires identical service rates');
127 end
128 mu = mu_vec(1);
129
130 % Compute aggregated MAP parameters
131 C_map = A{1};
132 D_map_sum = sum(cat(3, A{2:end}), 3); % Sum all class arrival matrices
133
134 % Estimate CDF range using aggregated arrival rate
135 lambda = map_lambda({C_map, D_map_sum});
136 rho = lambda / mu;
137 approx_mean = 1 / (mu * (1 - rho));
138
139 x_max = approx_mean * 10;
140 x_vals = linspace(0, x_max, n_cdf_pts);
141
142 % Compute sojourn time for aggregated system
143 W_bar = map_m1ps_cdfrespt(C_map, D_map_sum, mu, x_vals);
144 F = 1 - W_bar(:);
145
146 % Assign same CDF to all classes (approximation)
147 for k=1:K
148 RD{idx_arv,k} = [];
149 RD{idx_q,k} = [F, x_vals(:)];
150 end
151 end
152 else
153 % FCFS/HOL queue: use existing MMAPPH1FCFS method
154 [Ret{1:2*K}] = MMAPPH1FCFS({A{[1,3:end]}}, {pie{:}}, {S{:}}, 'stDistrPH');
155
156 for k=1:K
157 alpha{k} = Ret{(k-1)*2+1};
158 D0{k} = Ret{(k-1)*2+2};
159 RDph{k}={D0{k},(-D0{k})*ones(length(alpha{k}),1)*alpha{k}(:)'};
160 % now estimate the range of the CDF
161 sigma(k) = sqrt(map_var(RDph{k}));
162 mean(k) = map_mean(RDph{k});
163 n = 5;
164 while map_cdf(RDph{k},mean(k)+n*sigma(k)) < 1-GlobalConstants.FineTol
165 n = n+1;
166 end
167 % generate CDF points
168 X = linspace(0,(mean(k)+n*sigma(k)),n_cdf_pts);
169 F = map_cdf(RDph{k},X);
170 RD{idx_arv,k} = [];
171 RD{idx_q,k} = [F(:),X(:)];
172 end
173 end
174 end
175else
176 line_warning(mfilename,'This model is not supported by SolverMAM yet. Returning with no result.\n');
177end
178
179end