LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
test_mapqn_bnd.m
1%% test_mapqn_bnd - Test suite for mapqn_bnd_* functions
2% Tests the 6 newly created MATLAB ports against known reference values.
3
4clear;
5clc;
6fprintf('=== Testing mapqn_bnd_* functions ===\n\n');
7
8nPass = 0;
9nFail = 0;
10
11%% Test 1: mapqn_bnd_lr_pf - Symmetric 2-queue tandem
12fprintf('--- Test 1: mapqn_bnd_lr_pf (symmetric 2-queue tandem) ---\n');
13try
14 params = struct();
15 params.M = 2;
16 params.N = 3;
17 params.mu = [1.0; 1.0];
18 params.r = [0, 1; 1, 0];
19 params.verbose = false;
20
21 % MVA reference: U = 0.75 for symmetric tandem N=3
22 [result_min] = mapqn_bnd_lr_pf(params, 1, 'min');
23 [result_max] = mapqn_bnd_lr_pf(params, 1, 'max');
24
25 fprintf(' U1 bounds: [%.6f, %.6f] (MVA ref: 0.7500)\n', result_min.objective, result_max.objective);
26 if result_min.exitflag > 0 && result_max.exitflag > 0 && ...
27 abs(result_min.objective - 0.75) < 0.01 && abs(result_max.objective - 0.75) < 0.01
28 fprintf(' PASS (tight bounds match MVA)\n');
29 nPass = nPass + 1;
30 else
31 fprintf(' FAIL (exitflags: %d, %d)\n', result_min.exitflag, result_max.exitflag);
32 nFail = nFail + 1;
33 end
34catch e
35 fprintf(' FAIL (error: %s)\n', e.message);
36 nFail = nFail + 1;
37end
38
39%% Test 2: mapqn_bnd_lr_pf - 3-queue asymmetric
40fprintf('\n--- Test 2: mapqn_bnd_lr_pf (3-queue asymmetric) ---\n');
41try
42 params = struct();
43 params.M = 3;
44 params.N = 3;
45 params.mu = [1.0; 2.0; 0.5];
46 params.r = [0.1, 0.6, 0.3; 1.0, 0, 0; 1.0, 0, 0];
47 params.verbose = false;
48
49 [r1] = mapqn_bnd_lr_pf(params, 1, 'min');
50 [r2] = mapqn_bnd_lr_pf(params, 2, 'min');
51 [r3] = mapqn_bnd_lr_pf(params, 3, 'min');
52
53 fprintf(' U1 min: %.6f, U2 min: %.6f, U3 min: %.6f\n', r1.objective, r2.objective, r3.objective);
54 if r1.exitflag > 0 && r2.exitflag > 0 && r3.exitflag > 0
55 fprintf(' PASS (feasible)\n');
56 nPass = nPass + 1;
57 else
58 fprintf(' FAIL\n');
59 nFail = nFail + 1;
60 end
61catch e
62 fprintf(' FAIL (error: %s)\n', e.message);
63 nFail = nFail + 1;
64end
65
66%% Test 3: mapqn_bnd_lr - 2-phase MAP queue
67fprintf('\n--- Test 3: mapqn_bnd_lr (2-phase MAP queue) ---\n');
68try
69 params = struct();
70 params.M = 2;
71 params.N = 3;
72 params.K = [1; 2];
73 params.mu = {1.0; [0.5, 0.3; 0.2, 0.8]};
74 params.v = {0.0; [0, 0.1; 0.05, 0]};
75 params.r = [0, 1; 1, 0];
76 params.verbose = false;
77
78 [result_max] = mapqn_bnd_lr(params, 1, 1, 'max');
79 [result_min] = mapqn_bnd_lr(params, 1, 1, 'min');
80
81 fprintf(' U1(phase 1) bounds: [%.6f, %.6f]\n', result_min.objective, result_max.objective);
82 if result_max.exitflag > 0 && result_min.exitflag > 0 && ...
83 result_max.objective > 0 && result_max.objective <= 1
84 fprintf(' PASS (feasible, valid bounds)\n');
85 nPass = nPass + 1;
86 else
87 fprintf(' FAIL (exitflags: %d, %d)\n', result_min.exitflag, result_max.exitflag);
88 nFail = nFail + 1;
89 end
90catch e
91 fprintf(' FAIL (error: %s)\n', e.message);
92 nFail = nFail + 1;
93end
94
95%% Test 4: mapqn_bnd_lr_mva - MVA version
96fprintf('\n--- Test 4: mapqn_bnd_lr_mva (MVA 3-queue) ---\n');
97try
98 params = struct();
99 params.M = 3;
100 params.N = 5;
101 params.K = 2;
102 params.muM = [2.0; 1.5];
103 params.muMAP = [0.5, 0.1; 0.2, 0.8];
104 params.r = [0, 0.5, 0.5; 1, 0, 0; 1, 0, 0];
105 params.v = [0, 0.05; 0.03, 0];
106 params.verbose = false;
107
108 [result] = mapqn_bnd_lr_mva(params, 1, 1, 'max');
109
110 fprintf(' UN(1,1) max: %.6f\n', result.objective);
111 if result.exitflag > 0 && result.objective > 0 && result.objective <= 1
112 fprintf(' PASS (feasible, valid bound)\n');
113 nPass = nPass + 1;
114 else
115 fprintf(' FAIL (exitflag: %d)\n', result.exitflag);
116 nFail = nFail + 1;
117 end
118catch e
119 fprintf(' FAIL (error: %s)\n', e.message);
120 nFail = nFail + 1;
121end
122
123%% Test 5: mapqn_bnd_qr - Quadratic reduction with 2-phase
124fprintf('\n--- Test 5: mapqn_bnd_qr (2-queue 2-phase) ---\n');
125try
126 params = struct();
127 params.M = 2;
128 params.N = 2; % small N to keep problem size manageable
129 params.K = [2; 2];
130 params.mu = {[0.8, 0.2; 0.1, 0.6]; [0.5, 0.1; 0.2, 0.7]};
131 params.v = {[0, 0.1; 0.05, 0]; [0, 0.05; 0.1, 0]};
132 params.r = [0, 1; 1, 0];
133 params.verbose = false;
134
135 [result_max] = mapqn_bnd_qr(params, 1, 1, 'max');
136 [result_min] = mapqn_bnd_qr(params, 1, 1, 'min');
137
138 fprintf(' U(1,1) bounds: [%.6f, %.6f]\n', result_min.objective, result_max.objective);
139 if result_max.exitflag > 0 && result_min.exitflag > 0 && ...
140 result_min.objective >= 0 && result_max.objective <= 1 && ...
141 result_min.objective <= result_max.objective
142 fprintf(' PASS (feasible, valid bounds)\n');
143 nPass = nPass + 1;
144 else
145 fprintf(' FAIL (exitflags: %d, %d)\n', result_min.exitflag, result_max.exitflag);
146 nFail = nFail + 1;
147 end
148catch e
149 fprintf(' FAIL (error: %s)\n', e.message);
150 nFail = nFail + 1;
151end
152
153%% Test 6: mapqn_bnd_qr_ld - Load-dependent with 2-phase
154fprintf('\n--- Test 6: mapqn_bnd_qr_ld (2-queue 2-phase LD) ---\n');
155try
156 params = struct();
157 params.M = 2;
158 params.N = 2;
159 params.K = [2; 2];
160 params.mu = {[0.8, 0.2; 0.1, 0.6]; [0.5, 0.1; 0.2, 0.7]};
161 params.v = {[0, 0.1; 0.05, 0]; [0, 0.05; 0.1, 0]};
162 params.alpha = ones(2, 2); % no load-dependence
163 params.r = [0, 1; 1, 0];
164 params.verbose = false;
165
166 [result] = mapqn_bnd_qr_ld(params, 1, 1, 1, 'max');
167
168 fprintf(' p2(1,1,1,1,1,1) max: %.6f\n', result.objective);
169 if result.exitflag > 0 && result.objective >= 0 && result.objective <= 1
170 fprintf(' PASS (feasible, valid bound)\n');
171 nPass = nPass + 1;
172 else
173 fprintf(' FAIL (exitflag: %d)\n', result.exitflag);
174 nFail = nFail + 1;
175 end
176catch e
177 fprintf(' FAIL (error: %s)\n', e.message);
178 nFail = nFail + 1;
179end
180
181%% Test 7: mapqn_bnd_qr_delay - Delay system with IS alpha
182% Note: delay model requires alpha(M,n) = n for IS (infinite server) behavior
183fprintf('\n--- Test 7: mapqn_bnd_qr_delay (2-queue delay with IS alpha) ---\n');
184try
185 params = struct();
186 params.M = 2;
187 params.N = 3;
188 params.K = [1; 1];
189 params.Z = 2.0; % Z = 1/mu_delay = 1/0.5 = 2.0
190 params.D1 = 1.0; % D1 = 1/mu_server = 1/1.0 = 1.0
191 params.mu = {1.0; 0.5};
192 params.v = {0; 0};
193 params.alpha = [ones(1,3); 1:3]; % IS: alpha(M,n) = n
194 params.r = [0, 1; 1, 0];
195 params.verbose = false;
196
197 [result_max] = mapqn_bnd_qr_delay(params, 1, 1, 1, 'max');
198 [result_min] = mapqn_bnd_qr_delay(params, 1, 1, 1, 'min');
199
200 fprintf(' p2(1,1,1,1,1,1) bounds: [%.6f, %.6f]\n', result_min.objective, result_max.objective);
201 if result_max.exitflag > 0 && result_min.exitflag > 0 && ...
202 result_min.objective >= 0 && result_max.objective <= 1
203 fprintf(' PASS (feasible, valid bounds)\n');
204 nPass = nPass + 1;
205 else
206 fprintf(' FAIL (exitflags: %d, %d)\n', result_min.exitflag, result_max.exitflag);
207 nFail = nFail + 1;
208 end
209catch e
210 fprintf(' FAIL (error: %s)\n', e.message);
211 nFail = nFail + 1;
212end
213
214%% Test 8: Cross-validation - bnd_lr_pf min == bnd_lr_pf max for exact case
215fprintf('\n--- Test 8: mapqn_bnd_lr_pf (exact bounds for N=2, 2-queue) ---\n');
216try
217 params = struct();
218 params.M = 2;
219 params.N = 2;
220 params.mu = [1.0; 1.0];
221 params.r = [0, 1; 1, 0];
222 params.verbose = false;
223
224 % MVA reference: N=2, U = 2/3 = 0.6667
225 [result_min] = mapqn_bnd_lr_pf(params, 1, 'min');
226 [result_max] = mapqn_bnd_lr_pf(params, 1, 'max');
227
228 fprintf(' U1 bounds: [%.6f, %.6f] (MVA ref: 0.6667)\n', result_min.objective, result_max.objective);
229 if result_min.exitflag > 0 && result_max.exitflag > 0 && ...
230 abs(result_min.objective - 2/3) < 0.01 && abs(result_max.objective - 2/3) < 0.01
231 fprintf(' PASS (tight bounds)\n');
232 nPass = nPass + 1;
233 else
234 fprintf(' FAIL\n');
235 nFail = nFail + 1;
236 end
237catch e
238 fprintf(' FAIL (error: %s)\n', e.message);
239 nFail = nFail + 1;
240end
241
242%% Summary
243fprintf('\n====================================\n');
244fprintf('RESULTS: %d PASS, %d FAIL out of %d tests\n', nPass, nFail, nPass + nFail);
245fprintf('====================================\n');