LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
qrf_noblo_start.m
1function x0 = qrf_noblo_start(nonlcon, n)
2% QRF_NOBLO_START A point of the QRF no-blocking polytope, for fmincon's start.
3%
4% X0 = QRF_NOBLO_START(NONLCON, N) recovers the affine form of the
5% constraint callback NONLCON (which returns [C, CEQ] with C <= 0 and
6% CEQ == 0 for a decision vector of length N) and returns a point of the
7% polytope obtained by a phase-1 LP.
8%
9% The all-zero vector that these methods used as a start violates ONE
10% (normalization) by a full unit and COR1 by N^2. fmincon then spends its
11% iteration budget restoring feasibility and terminates at a point that is
12% still infeasible: on a 2-station cyclic MAP/MAP network at N=2 it returned
13% a utilization ABOVE the LP maximum of the same polytope, and the queue
14% lengths did not conserve the population. Every constraint of this model is
15% linear, so a phase-1 LP lands on the polytope exactly and costs a fraction
16% of one fmincon iteration.
17%
18% The phase 1 minimises 0.5*||x||^2 over the polytope rather than a null
19% objective, so the returned point is the unique minimum-norm feasible point
20% instead of an arbitrary vertex. (It is solved with QUADPROG, not LINPROG:
21% LINPROG errors with "Unrecognized field name optimstatus" on R2025a even
22% for a two-variable problem.)
23%
24% The polytope is nonempty for every well-posed instance, so infeasibility
25% here is a modelling error and is raised rather than replaced by an
26% arbitrary point.
27
28[c0, ceq0] = nonlcon(zeros(n,1));
29c0 = full(c0(:));
30ceq0 = full(ceq0(:));
31A = zeros(numel(c0), n);
32Aeq = zeros(numel(ceq0), n);
33for col = 1:n
34 e = zeros(n,1);
35 e(col) = 1;
36 [c1, ceq1] = nonlcon(e);
37 A(:,col) = full(c1(:)) - c0;
38 Aeq(:,col) = full(ceq1(:)) - ceq0;
39end
40b = -c0;
41beq = -ceq0;
42
43% Drop linearly dependent equality rows before the phase 1. The block is
44% heavily redundant (SYMMETRY states every station pair twice, and the ZERO,
45% MARGINALS and UEFF families overlap), carrying roughly twice as many rows as
46% its rank, and quadprog stalls on the rank-deficient system: on a 2-station
47% Erlang-2/Erlang-2 network at N=3 it stops at an equality residual of 2e-5
48% instead of machine precision. Dropping dependent rows changes no feasible
49% point, since they are exact linear combinations of the retained ones.
50keep = qrf_independent_rows(Aeq);
51AeqR = Aeq(keep,:);
52beqR = beq(keep);
53if rank([AeqR beqR]) > numel(keep)
54 error('qrf_noblo_start:inconsistent', ...
55 'QRF no-blocking equality system is inconsistent');
56end
57
58opts = optimset('Display','off','MaxIter',1000,'TolFun',1e-12,'TolCon',1e-12);
59x0 = quadprog(speye(n), zeros(n,1), A, b, AeqR, beqR, ...
60 zeros(n,1), ones(n,1), [], opts);
61
62% Judge the phase 1 by the residual of the point it returned, not by the
63% exit flag: quadprog reports flag 0 (iteration limit) on instances where it
64% has nevertheless landed on the polytope to machine precision.
65if isempty(x0)
66 error('qrf_noblo_start:infeasible', ...
67 'QRF no-blocking polytope phase 1 returned no point');
68end
69x0 = x0(:);
70req = 0; rub = 0;
71if ~isempty(Aeq), req = max(abs(Aeq*x0 - beq)); end
72if ~isempty(A), rub = max(A*x0 - b); end
73if req > 1e-8 || rub > 1e-8
74 error('qrf_noblo_start:infeasible', ...
75 ['QRF no-blocking polytope phase 1 did not reach feasibility ' ...
76 '(max equality residual %.3e, max inequality residual %.3e)'], req, rub);
77end
78end
Definition Station.m:245