LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
solver_amvald.m
1function [Q,U,R,T,C,X,lG,totiter] = solver_amvald(sn, Lchain,STchain,Vchain,alpha,Nchain,SCVchain,refstatchain, options)
2totiter = 0;
3
4M = sn.nstations;
5K = sn.nchains;
6Nt = sum(Nchain(isfinite(Nchain)));
7delta = (Nt - 1) / Nt;
8deltaclass = (Nchain - 1) ./ Nchain;
9deltaclass(isinf(Nchain)) = 1;
10tol = options.iter_tol;
11nservers = sn.nservers;
12schedparam = sn.schedparam;
13lldscaling = sn.lldscaling;
14cdscaling = sn.cdscaling;
15ljdscaling = sn.ljdscaling;
16ljdcutoffs = sn.ljdcutoffs;
17ljcdscaling = sn.ljcdscaling;
18ljcdcutoffs = sn.ljcdcutoffs;
19sched = sn.sched;
20classprio = sn.classprio;
21
22Uchain = zeros(M,K);
23Tchain = zeros(M,K);
24Cchain_s = zeros(1,K);
25
26%% initialize Q,X, U
27Qchain = options.init_sol;
28if isempty(Qchain)
29 % balanced initialization
30 Qchain = ones(M,K);
31 Qchain = Qchain ./ repmat(sum(Qchain,1),size(Qchain,1),1) .* repmat(Nchain,size(Qchain,1),1);
32 Qchain(isinf(Qchain))=0; % open classes
33 for r=find(isinf(Nchain)) % open classes
34 Qchain(refstatchain(r),r)=0;
35 end
36end
37
38nnzclasses = find(Nchain>0);
39Xchain = 1./sum(STchain,1);
40for r=find(isinf(Nchain)) % open classes
41 Xchain(r) = 1 ./ STchain(refstatchain(r),r);
42end
43
44for k=1:M
45 for r=nnzclasses
46 if isinf(nservers(k)) % infinite server
47 Uchain(k,r) = Vchain(k,r)*STchain(k,r)*Xchain(r);
48 else
49 Uchain(k,r) = Vchain(k,r)*STchain(k,r)*Xchain(r)/nservers(k);
50 end
51 end
52end
53
54switch options.method
55 case {'lin','qdlin'}
56 gamma = zeros(K,M,K); % class-based customer fraction corrections
57 tau = zeros(K,K); % throughput difference
58 otherwise
59 gamma = zeros(K,M); % total customer fraction corrections
60 tau = zeros(K,K); % throughput difference
61end
62
63%% main loop
64omicron = 0.5; % under-relaxation parameter
65outer_iter = 0;
66while (outer_iter < 2 || max(max(abs(Qchain-QchainOuter_1))) > tol) && outer_iter < sqrt(options.iter_max)
67 outer_iter = outer_iter + 1;
68 QchainOuter_1 = Qchain;
69 XchainOuter_1 = Xchain;
70 UchainOuter_1 = Uchain;
71
72 if isfinite(Nt) && Nt>0
73 switch options.method
74 %case {'aql','qdaql'}
75 %line_error(mfilename,'AQL is currently disabled in SolverMVA, please use the SolverJMT implementation (method jmva.aql).');
76 case {'lin','qdlin'}
77 % iteration at population N-1_s
78 for s=1:K
79 if isfinite(Nchain(s)) % don't recur on open classes
80 iter_s = 0;
81 Nchain_s = oner(Nchain,s);
82 Qchain_s = Qchain * (Nt-1)/Nt;
83 Xchain_s = Xchain * (Nt-1)/Nt;
84 Uchain_s = Uchain * (Nt-1)/Nt;
85 while (iter_s < 2 || max(max(abs(Qchain_s-Qchain_s_1))) > tol) && iter_s <= sqrt(options.iter_max)
86 iter_s = iter_s + 1;
87
88 Qchain_s_1 = Qchain_s;
89 Xchain_s_1 = Xchain_s;
90 Uchain_s_1 = Uchain_s;
91
92 [Wchain_s, STeff_s] = solver_amvald_forward(M, K, nservers, schedparam, lldscaling, cdscaling, ljdscaling, ljdcutoffs, ljcdscaling, ljcdcutoffs, sched, classprio, gamma, tau, Qchain_s_1, Xchain_s_1, Uchain_s_1, STchain, Vchain, Nchain_s, SCVchain, options);
93 totiter = totiter + 1;
94 if totiter > options.iter_max
95 break
96 end
97
98 %% update other metrics
99 for r=nnzclasses
100 if sum(Wchain_s(:,r)) == 0
101 Xchain_s(r) = 0;
102 else
103 if isinf(Nchain_s(r))
104 Cchain_s(r) = Vchain(:,r)' * Wchain_s(:,r);
105 % X(r) remains constant
106 elseif Nchain(r)==0
107 Xchain_s(r) = 0;
108 Cchain_s(r) = 0;
109 else
110 Cchain_s(r) = Vchain(:,r)' * Wchain_s(:,r);
111 Xchain_s(r) = omicron * Nchain_s(r) / Cchain_s(r) + (1-omicron) * Xchain_s_1(r);
112 end
113 end
114 for k=1:M
115 Rchain_s(k,r) = Vchain(k,r) * Wchain_s(k,r);
116 Qchain_s(k,r) = omicron * Xchain_s(r) * Vchain(k,r) * Wchain_s(k,r) + (1-omicron) * Qchain_s_1(k,r);
117 Tchain_s(k,r) = Xchain_s(r) * Vchain(k,r);
118 Uchain_s(k,r) = omicron * Vchain(k,r) * STeff_s(k,r) * Xchain_s(r) + (1-omicron) * Uchain_s_1(k,r);
119 end
120 end
121 end
122
123 switch options.method
124 case {'lin'}
125 for k=1:M
126 for r=nnzclasses
127 if ~isinf(Nchain(r)) && Nchain_s(r)>0
128 gamma(s,k,r) = Qchain_s_1(k,r)./Nchain_s(r) - QchainOuter_1(k,r)./Nchain(r);
129 end
130 end
131 end
132 otherwise
133 for k=1:M
134 gamma(s,k) = sum(Qchain_s_1(k,:),2)/(Nt-1) - sum(QchainOuter_1(k,:),2)/Nt;
135 end
136 end
137
138 for r=nnzclasses
139 tau(s,r) = Xchain_s_1(r) - XchainOuter_1(r); % save throughput for priority AMVA
140 end
141 end
142 end
143 end
144 end
145
146 iter = 0;
147 % iteration at population N
148 while (iter < 2 || max(max(abs(Qchain-Qchain_1))) > tol) && iter <= sqrt(options.iter_max)
149 iter = iter + 1;
150
151 Qchain_1 = Qchain;
152 Xchain_1 = Xchain;
153 Uchain_1 = Uchain;
154
155 [Wchain, STeff] = solver_amvald_forward(M, K, nservers, schedparam, lldscaling, cdscaling, ljdscaling, ljdcutoffs, ljcdscaling, ljcdcutoffs, sched, classprio, gamma, tau, Qchain_1, Xchain_1, Uchain_1, STchain, Vchain, Nchain, SCVchain, options);
156 totiter = totiter + 1;
157 if totiter > options.iter_max
158 break
159 end
160
161
162 %% update other metrics
163 for r=nnzclasses
164 if sum(Wchain(:,r)) == 0
165 Xchain(r) = 0;
166 else
167 if isinf(Nchain(r))
168 Cchain_s(r) = Vchain(:,r)'*Wchain(:,r);
169 % X(r) remains constant
170 elseif Nchain(r)==0
171 Xchain(r) = 0;
172 Cchain_s(r) = 0;
173 else
174 Cchain_s(r) = Vchain(:,r)'*Wchain(:,r);
175 Xchain(r) = omicron * Nchain(r) / Cchain_s(r) + (1-omicron) *Xchain_1(r);
176 end
177 end
178 for k=1:M
179 Rchain(k,r) = Vchain(k,r) * Wchain(k,r);
180 Qchain(k,r) = omicron * Xchain(r) * Vchain(k,r) * Wchain(k,r) + (1-omicron) * Qchain_1(k,r);
181 Tchain(k,r) = Xchain(r) * Vchain(k,r);
182 Uchain(k,r) = omicron * Vchain(k,r) * STeff(k,r) * Xchain(r) + (1-omicron) * Uchain_1(k,r);
183 end
184 end
185 end
186end
187
188
189% the next block is a coarse approximation for LD and CD, would need
190% cdterm and qterm in it but these are hidden within the iteration calls
191for k=1:M
192 for r=1:K
193 if Vchain(k,r) * STeff(k,r) >0
194 switch sn.sched(k)
195 case {SchedStrategy.FCFS, SchedStrategy.SIRO, SchedStrategy.PS, SchedStrategy.LCFSPR, SchedStrategy.DPS, SchedStrategy.HOL}
196 if sum(Uchain(k,:))>1
197 Uchain(k,r) = min(1,sum(Uchain(k,:))) * Vchain(k,r) * STeff(k,r) * Xchain(r) / ((Vchain(k,:) .* STeff(k,:)) * Xchain(:));
198 end
199 end
200 end
201 end
202end
203
204Rchain = Qchain./Tchain;
205Xchain(~isfinite(Xchain))=0;
206Uchain(~isfinite(Uchain))=0;
207%Qchain(~isfinite(Qchain))=0;
208Rchain(~isfinite(Rchain))=0;
209
210Xchain(Nchain==0)=0;
211Uchain(:,Nchain==0)=0;
212%Qchain(:,Nchain==0)=0;
213Rchain(:,Nchain==0)=0;
214Tchain(:,Nchain==0)=0;
215
216if isempty(sn.lldscaling) && isempty(sn.cdscaling) && ~sn_has_joint_dependence(sn)
217 [Q,U,R,T,C,X] = sn_deaggregate_chain_results(sn, Lchain, [], STchain, Vchain, alpha, [], [], Rchain, Tchain, [], Xchain);
218else
219 [Q,U,R,T,C,X] = sn_deaggregate_chain_results(sn, Lchain, [], STchain, Vchain, alpha, [], Uchain, Rchain, Tchain, [], Xchain);
220end
221
222% estimate normalizing constant for closed classes
223ccl = isfinite(Nchain);
224Nclosed = Nchain(ccl);
225Xclosed = Xchain(ccl);
226lG = - Nclosed(Xclosed>options.tol) * log(Xclosed(Xclosed>options.tol))'; % asymptotic approximation
227end