LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
solver_mam.m
1function [QN,UN,RN,TN,CN,XN,totiter,method,runtime] = solver_mam(sn, options)
2%[Q,U,R,T,C,X,totiter] = SOLVER_MAM(QN, PH, OPTIONS)
3
4%Copyright (c) 2012-2026, Imperial College London
5%All rights reserved.
6
7method = options.method;
8config = options.config;
9totiter = NaN;
10PH = sn.proc;
11I = sn.nnodes;
12M = sn.nstations;
13K = sn.nclasses;
14C = sn.nchains;
15N = sn.njobs';
16V = cellsum(sn.visits);
17Tstart=tic;
18QN = zeros(M,K);
19UN = zeros(M,K);
20RN = zeros(M,K);
21TN = zeros(M,K);
22CN = zeros(1,K);
23XN = zeros(1,K);
24
25lambda = zeros(1,K);
26for c=1:C
27 inchain = sn.inchain{c};
28 lambdas_inchain = sn.rates(sn.refstat(inchain(1)),inchain);
29 lambdas_inchain = lambdas_inchain(isfinite(lambdas_inchain));
30 lambda(inchain) = sum(lambdas_inchain);
31end
32
33chain = zeros(1,K);
34for k=1:K
35 chain(k) = find(sn.chains(:,k));
36end
37
38for ist=1:sn.nstations
39 switch sn.sched(ist)
40 case SchedStrategy.EXT
41 % no-op
42 case {SchedStrategy.FCFS, SchedStrategy.HOL, SchedStrategy.FCFSPRPRIO}
43 % no-op
44 otherwise
45 if options.verbose
46 line_warning(mfilename,'The dec.mmap method does not support non-FCFS queues.\n');
47 end
48 [QN,UN,RN,TN,CN,XN] = deal([],[],[],[],[],[]);
49 totiter = 0;
50 method = '';
51 runtime = toc(Tstart);
52 return
53 end
54end
55
56if all(isinf(sn.njobs)) % is open
57 % open queueing system (one node is the external world)
58 pie = {};
59 D0 = {};
60 for ist=1:M
61 switch sn.sched(ist)
62 case SchedStrategy.EXT
63 TN(ist,:) = sn.rates(ist,:);
64 TN(ist,isnan(TN(ist,:)))=0;
65 case {SchedStrategy.FCFS, SchedStrategy.HOL, SchedStrategy.FCFSPRPRIO}
66 for k=1:K
67 % divide service time by number of servers and put
68 % later a surrogate delay server in tandem to compensate
69 PH{ist}{k} = map_scale(PH{ist}{k}, map_mean(PH{ist}{k})/sn.nservers(ist));
70 pie{ist}{k} = map_pie(PH{ist}{k});
71 D0{ist,k} = PH{ist}{k}{1};
72 if any(isnan(D0{ist,k}))
73 D0{ist,k} = -GlobalConstants.Immediate;
74 pie{ist}{k} = 1;
75 PH{ist}{k} = map_exponential(GlobalConstants.Immediate);
76 end
77 end
78 end
79 end
80
81 it_max = options.iter_max;
82 for it=1:it_max
83 %it
84 % now estimate arrival processes
85 if it == 1
86 % initially form departure processes using scaled service
87 DEP = PH;
88 for ind=1:M
89 for r=1:K
90 ist = sn.nodeToStation(ind);
91 DEP{ind,r} = map_scale(PH{ist}{r}, 1 / (lambda(r) * V(ind,r)) );
92 end
93 end
94 end
95
96 ARV = solver_mam_traffic(sn, DEP, config);
97
98 QN_1 = QN;
99 for ist=1:M
100 ind = sn.stationToNode(ist);
101 switch sn.nodetype(ind)
102 case NodeType.Queue
103 if length(ARV{ind}{1}) > config.space_max
104 line_printf('\nArrival process at node %d is now at %d states. Compressing.',ind,length(ARV{ind}{1}));
105 ARV{ind} = mmap_compress(ARV{ind});
106 end
107 [Qret{1:K}, ~] = MMAPPH1FCFS({ARV{ind}{[1,3:end]}}, {pie{ist}{:}}, {D0{ist,:}}, 'ncMoms', 1, 'ncDistr',2);
108 for k=1:K
109 QN(ist,k) = sum(Qret{k});
110 end
111 TN(ist,:) = mmap_lambda(ARV{ind});
112 end
113 for k=1:K
114 UN(ist,k) = TN(ist,k) * map_mean(PH{ist}{k});
115 %add number of jobs at the surrogate delay server
116 QN(ist,k) = QN(ist,k) + TN(ist,k)*(map_mean(PH{ist}{k})*sn.nservers(ist)) * (sn.nservers(ist)-1)/sn.nservers(ist);
117 RN(ist,k) = QN(ist,k) ./ TN(ist,k);
118 end
119 end
120
121 if it >=3 && max(abs(QN(:)-QN_1(:))./QN_1(:)) < options.iter_tol
122 break;
123 end
124
125 for ist=1:M
126 ind = sn.stationToNode(ist);
127 switch sn.nodetype(ind)
128 case NodeType.Queue
129 [Ret{1:2*K}] = MMAPPH1FCFS({ARV{ind}{[1,3:end]}}, {pie{ist}{:}}, {D0{ist,:}}, 'stDistrPH');
130 for r=1:K
131 %obtain response time distribution for class r
132 %alpha = Ret{(r-1)*2+1}; T0 = Ret{(r-1)*2+2};
133 %RD = {T0,(-T0)*ones(length(alpha),1)*alpha(:)'}; %PH to MAP
134 %tRD = sum(RD{2},2);
135 %pieRD = map_pie(RD);
136
137 %define a ph for the arrival process of class r
138 A = mmap_hide(ARV{ind},setdiff(1:K,r));
139 tA = sum(A{2},2);
140 pieA = map_pie(A);
141
142 %define a ph for the service process of class r
143 S = PH{ist}{r};
144 pieS = map_pie(S);
145 tS = sum(S{2},2);
146
147 %with probability rho the output is the
148 %inter-arrival time+service time, with probability 1-rho is the
149 %response time
150 rho = sum(UN(ist,:));
151 AQ = sum(QN(ist,:)); % queue seen upon arrival with PASTA
152 Afull = AQ/rho; % from AQ = (1-rho)*0 + rho*AQfull
153 pfullonarrival = 1 - (Afull)/(1+Afull);
154
155 A = mmap_scale(A,map_mean(A)-map_mean(S));
156
157 zAS = 0*tA*pieS;
158 zSA = 0*tS*pieA;
159 zA = 0*A{2};
160
161 % this is only for single-class
162 DEP0ir = [S{1}, sum(rho)*tS*pieA;
163 zAS, A{1}];
164
165 DEP1ir = [(1-sum(rho))*S{2}, zSA;
166 tA*pieS, zA];
167
168 DEP{ind,r} = map_normalize({DEP0ir,DEP1ir});
169
170 DEP{ind,r} = map_scale(DEP{ind,r}, 1 / (lambda(r) * V(ind,r)) );
171 SCVd(ind,r) = map_scv(DEP{ind,r});
172 IDCd(ind,r) = map_idc(DEP{ind,r});
173 end
174 end
175 end
176 end
177 totiter = it;
178 if options.verbose
179 line_printf('\nMAM parametric decomposition completed in %d iterations.',it);
180 end
181else
182 if options.verbose
183 line_warning(mfilename,'This model is not supported by SolverMAM yet. Returning with no result.\n');
184 end
185end
186runtime = toc(Tstart);
187end