LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
ode_pnorm.m
1function dx = ode_pnorm(x, Phi, Mu, PH, M, K, enabled, q_indices, rt, Kic, nservers, w, sched_id, pstar)
2% DX = ODE_PNORM(X, PHI, MU, PH, M, K, ENABLED, Q_INDICES, RT, KIC, NSERVERS, W, SCHED_ID, PSTAR)
3%
4% ODE derivative function using p-norm smoothing for processor-share constraint.
5% Based on Ruuskanen et al., PEVA 151 (2021).
6%
7% This provides a smoother approximation than softmin, improving ODE stability
8% for stiff problems.
9%
10% @param pstar Smoothing parameter vector (one per station) or scalar
11%
12% Copyright (c) 2012-2026, Imperial College London
13% All rights reserved.
14
15dx = 0*x;
16
17% If pstar is scalar, expand to per-station
18if isscalar(pstar)
19 pstar = pstar * ones(M, 1);
20end
21
22for i = 1:M
23 p = pstar(i); % p-norm parameter for this station
24
25 switch sched_id(i)
26 case SchedStrategy.INF
27 % phase changes
28 for c = 1:K
29 if enabled(i,c)
30 xic = q_indices(i,c);
31 for kic = 1 : (Kic(i,c) - 1)
32 for kic_p = 1:Kic(i,c)
33 if kic ~= kic_p
34 rate = PH{i}{c}{1}(kic,kic_p);
35 dx(xic+kic-1) = dx(xic+kic-1) - x(xic+kic-1)*rate;
36 dx(xic+kic_p-1) = dx(xic+kic_p-1) + x(xic+kic-1)*rate;
37 end
38 end
39 end
40 end
41 end
42 % service completions
43 for c = 1:K
44 if enabled(i,c)
45 xic = q_indices(i,c);
46 for j = 1 : M
47 for l = 1:K
48 xjl = q_indices(j,l);
49 if enabled(j,l)
50 pie = map_pie(PH{j}{l});
51 if rt((i-1)*K+c,(j-1)*K+l) > 0
52 for kic = 1 : Kic(i,c)
53 for kjl = 1 : Kic(j,l)
54 if j~=i
55 rate = Phi{i}{c}(kic) * Mu{i}{c}(kic) * rt((i-1)*K+c,(j-1)*K+l) * pie(kjl);
56 dx(xic+kic-1) = dx(xic+kic-1) - x(xic+kic-1) * rate;
57 dx(xjl+kjl-1) = dx(xjl+kjl-1) + x(xic+kic-1) * rate;
58 end
59 end
60 end
61 end
62 end
63 end
64 end
65 end
66 end
67
68 case SchedStrategy.EXT
69 % Source node with external arrivals - p-norm smoothing not needed
70 % (arrivals are independent of queue state)
71 % Phase changes
72 for c = 1:K
73 if enabled(i,c)
74 xic = q_indices(i,c);
75 for kic = 1 : (Kic(i,c) - 1)
76 for kic_p = 1:Kic(i,c)
77 if kic ~= kic_p
78 rate = PH{i}{c}{1}(kic,kic_p);
79 dx(xic+kic-1) = dx(xic+kic-1) - x(xic+kic-1)*rate;
80 dx(xic+kic_p-1) = dx(xic+kic_p-1) + x(xic+kic-1)*rate;
81 end
82 end
83 end
84 end
85 end
86 % Service completions (departures from source)
87 for c = 1:K
88 if enabled(i,c)
89 xic = q_indices(i,c);
90 for j = 1 : M
91 for l = 1:K
92 xjl = q_indices(j,l);
93 if enabled(j,l)
94 pie = map_pie(PH{j}{l});
95 if rt((i-1)*K+c,(j-1)*K+l) > 0
96 for kic = 1 : Kic(i,c)
97 for kjl = 1 : Kic(j,l)
98 if j~=i
99 rate = Phi{i}{c}(kic) * Mu{i}{c}(kic) * rt((i-1)*K+c,(j-1)*K+l) * pie(kjl);
100 dx(xic+kic-1) = dx(xic+kic-1) - x(xic+kic-1) * rate;
101 dx(xjl+kjl-1) = dx(xjl+kjl-1) + x(xic+kic-1) * rate;
102 end
103 end
104 end
105 end
106 end
107 end
108 end
109 end
110 end
111
112 case SchedStrategy.PS
113 idxIni = q_indices(i,1);
114 idxEnd = q_indices(i,K) + Kic(i,K) - 1;
115 ni = sum( x(idxIni:idxEnd) );
116
117 % Compute p-norm smooth factor: ghat = 1 / (1 + (ni/c)^p)^(1/p)
118 if ni > 0 && nservers(i) > 0
119 ghat = pnorm_smooth(ni, nservers(i), p);
120 else
121 ghat = 1;
122 end
123
124 % phase changes
125 for c = 1:K
126 if enabled(i,c)
127 xic = q_indices(i,c);
128 for kic = 1 : (Kic(i,c) - 1)
129 for kic_p = 1:Kic(i,c)
130 if kic ~= kic_p
131 rate = PH{i}{c}{1}(kic,kic_p) * ghat;
132 dx(xic+kic-1) = dx(xic+kic-1) - x(xic+kic-1)*rate;
133 dx(xic+kic_p-1) = dx(xic+kic_p-1) + x(xic+kic-1)*rate;
134 end
135 end
136 end
137 end
138 end
139 % service completions
140 for c = 1:K
141 if enabled(i,c)
142 xic = q_indices(i,c);
143 for j = 1 : M
144 for l = 1:K
145 xjl = q_indices(j,l);
146 if enabled(j,l)
147 pie = map_pie(PH{j}{l});
148 if rt((i-1)*K+c,(j-1)*K+l) > 0
149 for kic = 1 : Kic(i,c)
150 for kjl = 1 : Kic(j,l)
151 rate = Phi{i}{c}(kic) * Mu{i}{c}(kic) * rt((i-1)*K+c,(j-1)*K+l) * pie(kjl) * ghat;
152 dx(xic+kic-1) = dx(xic+kic-1) - x(xic+kic-1)*rate;
153 dx(xjl+kjl-1) = dx(xjl+kjl-1) + x(xic+kic-1)*rate;
154 end
155 end
156 end
157 end
158 end
159 end
160 end
161 end
162
163 case SchedStrategy.FCFS
164 idxIni = q_indices(i,1);
165 idxEnd = q_indices(i,K) + Kic(i,K) - 1;
166 ni = sum( x(idxIni:idxEnd) );
167 wni = GlobalConstants.FineTol;
168 for c=1:K
169 for kic = 1 : Kic(i,c)
170 if enabled(i,c)
171 xic = q_indices(i,c);
172 w(c,kic) = -1/PH{i}{c}{1}(kic,kic);
173 wni = wni + w(c,kic)*x(xic + kic - 1);
174 end
175 end
176 end
177
178 % Compute p-norm smooth factor
179 if ni > 0 && nservers(i) > 0
180 ghat = pnorm_smooth(ni, nservers(i), p);
181 else
182 ghat = 1;
183 end
184
185 % phase changes
186 for c = 1:K
187 if enabled(i,c)
188 xic = q_indices(i,c);
189 for kic = 1 : (Kic(i,c) - 1)
190 for kic_p = 1:Kic(i,c)
191 if kic ~= kic_p
192 rate = PH{i}{c}{1}(kic,kic_p) * ghat * w(c,kic) / wni;
193 dx(xic+kic-1) = dx(xic+kic-1) - x(xic+kic-1)*rate;
194 dx(xic+kic_p-1) = dx(xic+kic_p-1) + x(xic+kic-1)*rate;
195 end
196 end
197 end
198 end
199 end
200 % service completions
201 for c = 1:K
202 if enabled(i,c)
203 xic = q_indices(i,c);
204 for j = 1 : M
205 for l = 1:K
206 xjl = q_indices(j,l);
207 if enabled(j,l)
208 pie = map_pie(PH{j}{l});
209 if rt((i-1)*K+c,(j-1)*K+l) > 0
210 for kic = 1 : Kic(i,c)
211 for kjl = 1 : Kic(j,l)
212 rate = Phi{i}{c}(kic) * Mu{i}{c}(kic) * rt((i-1)*K+c,(j-1)*K+l) * pie(kjl);
213 rate = rate * ghat * w(c,kic) / wni;
214 dx(xic+kic-1) = dx(xic+kic-1) - x(xic+kic-1)*rate;
215 dx(xjl+kjl-1) = dx(xjl+kjl-1) + x(xic+kic-1)*rate;
216 end
217 end
218 end
219 end
220 end
221 end
222 end
223 end
224
225 case SchedStrategy.DPS
226 w(i,:) = w(i,:)/sum(w(i,:));
227 % Compute weighted queue length for rate normalization
228 wni = GlobalConstants.FineTol;
229 for k=1:K
230 idxIni = q_indices(i,k);
231 idxEnd = q_indices(i,k) + Kic(i,k) - 1;
232 wni = wni + w(i,k) * sum(x(idxIni:idxEnd));
233 end
234 % Compute total queue length for ghat
235 idxIni = q_indices(i,1);
236 idxEnd = q_indices(i,K) + Kic(i,K) - 1;
237 ni = sum( x(idxIni:idxEnd) );
238
239 % Compute p-norm smooth factor using total queue length
240 if ni > 0 && nservers(i) > 0
241 ghat = pnorm_smooth(ni, nservers(i), p);
242 else
243 ghat = 1;
244 end
245
246 % phase changes
247 for c = 1:K
248 if enabled(i,c)
249 xic = q_indices(i,c);
250 for kic = 1 : (Kic(i,c) - 1)
251 for kic_p = 1:Kic(i,c)
252 if kic ~= kic_p
253 rate = PH{i}{c}{1}(kic,kic_p) * ghat * w(i,c) / wni;
254 dx(xic+kic-1) = dx(xic+kic-1) - x(xic+kic-1)*rate;
255 dx(xic+kic_p-1) = dx(xic+kic_p-1) + x(xic+kic-1)*rate;
256 end
257 end
258 end
259 end
260 end
261 % service completions
262 for c = 1:K
263 if enabled(i,c)
264 xic = q_indices(i,c);
265 for j = 1 : M
266 for l = 1:K
267 xjl = q_indices(j,l);
268 if enabled(j,l)
269 pie = map_pie(PH{j}{l});
270 if rt((i-1)*K+c,(j-1)*K+l) > 0
271 for kic = 1 : Kic(i,c)
272 for kjl = 1 : Kic(j,l)
273 rate = Phi{i}{c}(kic) * Mu{i}{c}(kic) * rt((i-1)*K+c,(j-1)*K+l) * pie(kjl);
274 rate = rate * ghat * w(i,c) / wni;
275 dx(xic+kic-1) = dx(xic+kic-1) - x(xic+kic-1)*rate;
276 dx(xjl+kjl-1) = dx(xjl+kjl-1) + x(xic+kic-1)*rate;
277 end
278 end
279 end
280 end
281 end
282 end
283 end
284 end
285 end
286end
287end