1%% test_mapqn_bnd - Test suite
for mapqn_bnd_* functions
2% Tests the 6 newly created MATLAB ports against known reference values.
6fprintf(
'=== Testing mapqn_bnd_* functions ===\n\n');
11%% Test 1: mapqn_bnd_lr_pf - Symmetric 2-queue tandem
12fprintf(
'--- Test 1: mapqn_bnd_lr_pf (symmetric 2-queue tandem) ---\n');
17 params.mu = [1.0; 1.0];
18 params.r = [0, 1; 1, 0];
19 params.verbose =
false;
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');
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');
31 fprintf(
' FAIL (exitflags: %d, %d)\n', result_min.exitflag, result_max.exitflag);
35 fprintf(
' FAIL (error: %s)\n', e.message);
39%% Test 2: mapqn_bnd_lr_pf - 3-queue asymmetric
40fprintf(
'\n--- Test 2: mapqn_bnd_lr_pf (3-queue asymmetric) ---\n');
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;
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');
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');
62 fprintf(
' FAIL (error: %s)\n', e.message);
66%% Test 3: mapqn_bnd_lr - 2-phase MAP queue
67fprintf(
'\n--- Test 3: mapqn_bnd_lr (2-phase MAP queue) ---\n');
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;
78 [result_max] = mapqn_bnd_lr(params, 1, 1,
'max');
79 [result_min] = mapqn_bnd_lr(params, 1, 1,
'min');
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');
87 fprintf(
' FAIL (exitflags: %d, %d)\n', result_min.exitflag, result_max.exitflag);
91 fprintf(
' FAIL (error: %s)\n', e.message);
95%% Test 4: mapqn_bnd_lr_mva - MVA version
96fprintf(
'\n--- Test 4: mapqn_bnd_lr_mva (MVA 3-queue) ---\n');
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;
108 [result] = mapqn_bnd_lr_mva(params, 1, 1,
'max');
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');
115 fprintf(
' FAIL (exitflag: %d)\n', result.exitflag);
119 fprintf(
' FAIL (error: %s)\n', e.message);
123%% Test 5: mapqn_bnd_qr - Quadratic reduction with 2-phase
124fprintf(
'\n--- Test 5: mapqn_bnd_qr (2-queue 2-phase) ---\n');
128 params.N = 2; % small N to keep problem size manageable
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;
135 [result_max] = mapqn_bnd_qr(params, 1, 1,
'max');
136 [result_min] = mapqn_bnd_qr(params, 1, 1,
'min');
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');
145 fprintf(
' FAIL (exitflags: %d, %d)\n', result_min.exitflag, result_max.exitflag);
149 fprintf(
' FAIL (error: %s)\n', e.message);
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');
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;
166 [result] = mapqn_bnd_qr_ld(params, 1, 1, 1,
'max');
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');
173 fprintf(
' FAIL (exitflag: %d)\n', result.exitflag);
177 fprintf(
' FAIL (error: %s)\n', e.message);
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');
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};
193 params.alpha = [ones(1,3); 1:3]; % IS: alpha(M,n) = n
194 params.r = [0, 1; 1, 0];
195 params.verbose =
false;
197 [result_max] = mapqn_bnd_qr_delay(params, 1, 1, 1,
'max');
198 [result_min] = mapqn_bnd_qr_delay(params, 1, 1, 1,
'min');
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');
206 fprintf(
' FAIL (exitflags: %d, %d)\n', result_min.exitflag, result_max.exitflag);
210 fprintf(
' FAIL (error: %s)\n', e.message);
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');
220 params.mu = [1.0; 1.0];
221 params.r = [0, 1; 1, 0];
222 params.verbose =
false;
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');
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');
238 fprintf(
' FAIL (error: %s)\n', e.message);
243fprintf(
'\n====================================\n');
244fprintf(
'RESULTS: %d PASS, %d FAIL out of %d tests\n', nPass, nFail, nPass + nFail);
245fprintf(
'====================================\n');