Mercurial > octave
annotate scripts/optimization/qp.m @ 10059:665ad34efeed
qp.m: handle optimset options
author | Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 05 Jan 2010 01:18:50 -0500 |
parents | 72d6e0de76c7 |
children | 8f51a90eb8d1 |
rev | line source |
---|---|
8920 | 1 ## Copyright (C) 2000, 2001, 2004, 2005, 2006, 2007, 2008, |
2 ## 2009 Gabriele Pannocchia. | |
5289 | 3 ## |
4 ## This file is part of Octave. | |
5 ## | |
6 ## Octave is free software; you can redistribute it and/or modify it | |
7 ## under the terms of the GNU General Public License as published by | |
7016 | 8 ## the Free Software Foundation; either version 3 of the License, or (at |
9 ## your option) any later version. | |
5289 | 10 ## |
11 ## Octave is distributed in the hope that it will be useful, but | |
12 ## WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 ## General Public License for more details. | |
15 ## | |
16 ## You should have received a copy of the GNU General Public License | |
7016 | 17 ## along with Octave; see the file COPYING. If not, see |
18 ## <http://www.gnu.org/licenses/>. | |
5289 | 19 |
20 ## -*- texinfo -*- | |
10059
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
21 ## @deftypefn {Function File} {[@var{x}, @var{obj}, @var{info}, @var{lambda}] =} qp (@var{x0}, @var{H}) |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
22 ## @deftypefnx {Function File} {[@var{x}, @var{obj}, @var{info}, @var{lambda}] =} qp (@var{x0}, @var{H}, @var{q}) |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
23 ## @deftypefnx {Function File} {[@var{x}, @var{obj}, @var{info}, @var{lambda}] =} qp (@var{x0}, @var{H}, @var{q}, @var{A}, @var{b}) |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
24 ## @deftypefnx {Function File} {[@var{x}, @var{obj}, @var{info}, @var{lambda}] =} qp (@var{x0}, @var{H}, @var{q}, @var{A}, @var{b}, @var{lb}, @var{ub}) |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
25 ## @deftypefnx {Function File} {[@var{x}, @var{obj}, @var{info}, @var{lambda}] =} qp (@var{x0}, @var{H}, @var{q}, @var{A}, @var{b}, @var{lb}, @var{ub}, @var{A_lb}, @var{A_in}, @var{A_ub}) |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
26 ## @deftypefnx {Function File} {[@var{x}, @var{obj}, @var{info}, @var{lambda}] =} qp (@dots{}, @var{options}) |
5289 | 27 ## Solve the quadratic program |
6741 | 28 ## @tex |
29 ## $$ | |
30 ## \min_x {1 \over 2} x^T H x + x^T q | |
31 ## $$ | |
32 ## @end tex | |
33 ## @ifnottex | |
5289 | 34 ## |
35 ## @example | |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
36 ## @group |
5289 | 37 ## min 0.5 x'*H*x + x'*q |
38 ## x | |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
39 ## @end group |
5289 | 40 ## @end example |
41 ## | |
6741 | 42 ## @end ifnottex |
43 ## subject to | |
5289 | 44 ## @tex |
6741 | 45 ## $$ |
46 ## Ax = b \qquad lb \leq x \leq ub \qquad A_{lb} \leq A_{in} \leq A_{ub} | |
47 ## $$ | |
5289 | 48 ## @end tex |
6741 | 49 ## @ifnottex |
5289 | 50 ## |
51 ## @example | |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
52 ## @group |
5289 | 53 ## A*x = b |
54 ## lb <= x <= ub | |
6741 | 55 ## A_lb <= A_in*x <= A_ub |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
56 ## @end group |
5289 | 57 ## @end example |
6741 | 58 ## @end ifnottex |
5289 | 59 ## |
60 ## @noindent | |
61 ## using a null-space active-set method. | |
62 ## | |
63 ## Any bound (@var{A}, @var{b}, @var{lb}, @var{ub}, @var{A_lb}, | |
64 ## @var{A_ub}) may be set to the empty matrix (@code{[]}) if not | |
65 ## present. If the initial guess is feasible the algorithm is faster. | |
66 ## | |
10059
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
67 ## @table @var |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
68 ## @item options |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
69 ## An optional structure containing the following |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
70 ## parameter(s) used to define the behavior of the solver. Missing elements |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
71 ## in the structure take on default values, so you only need to set the |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
72 ## elements that you wish to change from the default. |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
73 ## |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
74 ## @table @code |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
75 ## @item MaxIter (default: 200) |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
76 ## Maximum number of iterations. |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
77 ## @end table |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
78 ## @end table |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
79 ## |
5289 | 80 ## The value @var{info} is a structure with the following fields: |
81 ## @table @code | |
82 ## @item solveiter | |
83 ## The number of iterations required to find the solution. | |
84 ## @item info | |
85 ## An integer indicating the status of the solution, as follows: | |
86 ## @table @asis | |
87 ## @item 0 | |
88 ## The problem is feasible and convex. Global solution found. | |
89 ## @item 1 | |
90 ## The problem is not convex. Local solution found. | |
91 ## @item 2 | |
92 ## The problem is not convex and unbounded. | |
93 ## @item 3 | |
94 ## Maximum number of iterations reached. | |
95 ## @item 6 | |
96 ## The problem is infeasible. | |
97 ## @end table | |
98 ## @end table | |
99 ## @end deftypefn | |
100 | |
10059
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
101 function [x, obj, INFO, lambda] = qp (x0, H, varargin) |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
102 |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
103 nargs = nargin; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
104 |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
105 if (nargs > 2 && isstruct (varargin{end})) |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
106 options = varargin{end}; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
107 nargs--; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
108 else |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
109 options = struct (); |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
110 endif |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
111 |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
112 if (nargs >= 3) |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
113 q = varargin{1}; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
114 else |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
115 q = []; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
116 endif |
5289 | 117 |
10059
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
118 if (nargs >= 5) |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
119 A = varargin{2}; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
120 b = varargin{3}; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
121 else |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
122 A = []; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
123 b = []; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
124 endif |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
125 |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
126 if (nargs >= 7) |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
127 lb = varargin{4}; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
128 ub = varargin{5}; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
129 else |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
130 lb = []; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
131 ub = []; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
132 endif |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
133 |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
134 if (nargs == 10) |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
135 A_lb = varargin{6}; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
136 A_in = varargin{7}; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
137 A_ub = varargin{8}; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
138 else |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
139 A_lb = []; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
140 A_in = []; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
141 A_ub = []; |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
142 endif |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
143 |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
144 if (nargs == 2 || nargs == 3 || nargs == 5 || nargs == 7 || nargs == 10) |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
145 |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
146 maxit = optimget (options, "MaxIter", 200) |
5289 | 147 |
148 ## Checking the quadratic penalty | |
9872
72d6e0de76c7
fix qp, condest and krylov
Jaroslav Hajek <highegg@gmail.com>
parents:
9211
diff
changeset
|
149 if (! issquare (H)) |
5289 | 150 error ("qp: quadratic penalty matrix not square"); |
9872
72d6e0de76c7
fix qp, condest and krylov
Jaroslav Hajek <highegg@gmail.com>
parents:
9211
diff
changeset
|
151 elseif (! ishermitian (H)) |
72d6e0de76c7
fix qp, condest and krylov
Jaroslav Hajek <highegg@gmail.com>
parents:
9211
diff
changeset
|
152 ## warning ("qp: quadratic penalty matrix not hermitian"); |
5289 | 153 H = (H + H')/2; |
154 endif | |
9872
72d6e0de76c7
fix qp, condest and krylov
Jaroslav Hajek <highegg@gmail.com>
parents:
9211
diff
changeset
|
155 n = rows (H); |
5289 | 156 |
157 ## Checking the initial guess (if empty it is resized to the | |
158 ## right dimension and filled with 0) | |
159 if (isempty (x0)) | |
160 x0 = zeros (n, 1); | |
10059
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
161 elseif (numel (x0) != n) |
5289 | 162 error ("qp: the initial guess has incorrect length"); |
163 endif | |
164 | |
165 ## Linear penalty. | |
10059
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
166 if (isempty (q)) |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
167 q = zeros (n, 1); |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
168 elseif (numel (q) != n) |
5289 | 169 error ("qp: the linear term has incorrect length"); |
170 endif | |
171 | |
172 ## Equality constraint matrices | |
10059
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
173 if (isempty (A) || isempty (b)) |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
174 A = zeros (0, n); |
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
175 b = zeros (0, 1); |
5289 | 176 n_eq = 0; |
177 else | |
178 [n_eq, n1] = size (A); | |
179 if (n1 != n) | |
180 error ("qp: equality constraint matrix has incorrect column dimension"); | |
181 endif | |
10059
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
182 if (numel (b) != n_eq) |
5289 | 183 error ("qp: equality constraint matrix and vector have inconsistent dimension"); |
184 endif | |
185 endif | |
186 | |
187 ## Bound constraints | |
188 Ain = zeros (0, n); | |
189 bin = zeros (0, 1); | |
190 n_in = 0; | |
10059
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
191 if (nargs > 5) |
5289 | 192 if (! isempty (lb)) |
10059
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
193 if (numel (lb) != n) |
5289 | 194 error ("qp: lower bound has incorrect length"); |
8280
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
195 elseif (isempty (ub)) |
5289 | 196 Ain = [Ain; eye(n)]; |
197 bin = [bin; lb]; | |
198 endif | |
199 endif | |
200 | |
201 if (! isempty (ub)) | |
10059
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
202 if (numel (ub) != n) |
5289 | 203 error ("qp: upper bound has incorrect length"); |
8280
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
204 elseif (isempty (lb)) |
5289 | 205 Ain = [Ain; -eye(n)]; |
206 bin = [bin; -ub]; | |
207 endif | |
208 endif | |
8280
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
209 |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
210 if (! isempty (lb) && ! isempty (ub)) |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
211 rtol = sqrt (eps); |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
212 for i = 1:n |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
213 if (abs(lb (i) - ub(i)) < rtol*(1 + max (abs (lb(i) + ub(i))))) |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
214 ## These are actually an equality constraint |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
215 tmprow = zeros(1,n); |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
216 tmprow(i) = 1; |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
217 A = [A;tmprow]; |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
218 b = [b; 0.5*(lb(i) + ub(i))]; |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
219 n_eq = n_eq + 1; |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
220 else |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
221 tmprow = zeros(1,n); |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
222 tmprow(i) = 1; |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
223 Ain = [Ain; tmprow; -tmprow]; |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
224 bin = [bin; lb(i); -ub(i)]; |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
225 n_in = n_in + 2; |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
226 endif |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
227 endfor |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
228 endif |
5289 | 229 endif |
230 | |
231 ## Inequality constraints | |
10059
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
232 if (nargs > 7) |
5289 | 233 [dimA_in, n1] = size (A_in); |
234 if (n1 != n) | |
235 error ("qp: inequality constraint matrix has incorrect column dimension"); | |
236 else | |
237 if (! isempty (A_lb)) | |
10059
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
238 if (numel (A_lb) != dimA_in) |
5289 | 239 error ("qp: inequality constraint matrix and lower bound vector inconsistent"); |
8280
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
240 elseif (isempty (A_ub)) |
5289 | 241 Ain = [Ain; A_in]; |
242 bin = [bin; A_lb]; | |
243 endif | |
244 endif | |
245 if (! isempty (A_ub)) | |
10059
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
246 if (numel (A_ub) != dimA_in) |
5289 | 247 error ("qp: inequality constraint matrix and upper bound vector inconsistent"); |
8280
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
248 elseif (isempty (A_lb)) |
5289 | 249 Ain = [Ain; -A_in]; |
250 bin = [bin; -A_ub]; | |
251 endif | |
252 endif | |
8280
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
253 |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
254 if (! isempty (A_lb) && ! isempty (A_ub)) |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
255 rtol = sqrt (eps); |
8507 | 256 for i = 1:dimA_in |
8280
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
257 if (abs (A_lb(i) - A_ub(i)) < rtol*(1 + max (abs (A_lb(i) + A_ub(i))))) |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
258 ## These are actually an equality constraint |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
259 tmprow = A_in(i,:); |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
260 A = [A;tmprow]; |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
261 b = [b; 0.5*(A_lb(i) + A_ub(i))]; |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
262 n_eq = n_eq + 1; |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
263 else |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
264 tmprow = A_in(i,:); |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
265 Ain = [Ain; tmprow; -tmprow]; |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
266 bin = [bin; A_lb(i); -A_ub(i)]; |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
267 n_in = n_in + 2; |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
268 endif |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
269 endfor |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
270 endif |
5289 | 271 endif |
272 endif | |
273 | |
274 ## Now we should have the following QP: | |
275 ## | |
276 ## min_x 0.5*x'*H*x + x'*q | |
277 ## s.t. A*x = b | |
278 ## Ain*x >= bin | |
279 | |
280 ## Discard inequality constraints that have -Inf bounds since those | |
281 ## will never be active. | |
282 idx = isinf (bin) & bin < 0; | |
6523 | 283 |
6526 | 284 bin(idx) = []; |
285 Ain(idx,:) = []; | |
5289 | 286 |
10059
665ad34efeed
qp.m: handle optimset options
Joshua Redstone <redstone@gmail.com>, John W. Eaton <jwe@octave.org>
parents:
9872
diff
changeset
|
287 n_in = numel (bin); |
5310 | 288 |
5289 | 289 ## Check if the initial guess is feasible. |
7795
df9519e9990c
Handle single precision eps values
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
290 if (isa (x0, "single") || isa (H, "single") || isa (q, "single") || isa (A, "single") |
df9519e9990c
Handle single precision eps values
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
291 || isa (b, "single")) |
df9519e9990c
Handle single precision eps values
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
292 rtol = sqrt (eps ("single")); |
df9519e9990c
Handle single precision eps values
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
293 else |
df9519e9990c
Handle single precision eps values
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
294 rtol = sqrt (eps); |
df9519e9990c
Handle single precision eps values
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
295 endif |
5289 | 296 |
8280
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
297 eq_infeasible = (n_eq > 0 && norm (A*x0-b) > rtol*(1+abs (b))); |
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
298 in_infeasible = (n_in > 0 && any (Ain*x0-bin < -rtol*(1+abs (bin)))); |
5289 | 299 |
300 info = 0; | |
301 if (eq_infeasible || in_infeasible) | |
302 ## The initial guess is not feasible. | |
303 ## First define xbar that is feasible with respect to the equality | |
304 ## constraints. | |
305 if (eq_infeasible) | |
306 if (rank (A) < n_eq) | |
307 error ("qp: equality constraint matrix must be full row rank") | |
308 endif | |
309 xbar = pinv (A) * b; | |
310 else | |
311 xbar = x0; | |
312 endif | |
313 | |
314 ## Check if xbar is feasible with respect to the inequality | |
315 ## constraints also. | |
316 if (n_in > 0) | |
317 res = Ain * xbar - bin; | |
8280
5ee11a81688e
qp.m: convert b <= x <= b and b <= A*x <= b to equality constraints
Gabriele Pannocchia <g.pannocchia@ing.unipi.it>
parents:
7795
diff
changeset
|
318 if (any (res < -rtol * (1 + abs (bin)))) |
5289 | 319 ## xbar is not feasible with respect to the inequality |
320 ## constraints. Compute a step in the null space of the | |
321 ## equality constraints, by solving a QP. If the slack is | |
322 ## small, we have a feasible initial guess. Otherwise, the | |
323 ## problem is infeasible. | |
324 if (n_eq > 0) | |
325 Z = null (A); | |
326 if (isempty (Z)) | |
327 ## The problem is infeasible because A is square and full | |
328 ## rank, but xbar is not feasible. | |
329 info = 6; | |
330 endif | |
331 endif | |
332 | |
333 if (info != 6) | |
334 ## Solve an LP with additional slack variables to find | |
335 ## a feasible starting point. | |
336 gamma = eye (n_in); | |
337 if (n_eq > 0) | |
338 Atmp = [Ain*Z, gamma]; | |
339 btmp = -res; | |
340 else | |
341 Atmp = [Ain, gamma]; | |
342 btmp = bin; | |
343 endif | |
344 ctmp = [zeros(n-n_eq, 1); ones(n_in, 1)]; | |
345 lb = [-Inf*ones(n-n_eq,1); zeros(n_in,1)]; | |
346 ub = []; | |
347 ctype = repmat ("L", n_in, 1); | |
348 [P, dummy, status] = glpk (ctmp, Atmp, btmp, lb, ub, ctype); | |
349 if ((status == 180 || status == 181 || status == 151) | |
350 && all (abs (P(n-n_eq+1:end)) < rtol * (1 + norm (btmp)))) | |
351 ## We found a feasible starting point | |
352 if (n_eq > 0) | |
5306 | 353 x0 = xbar + Z*P(1:n-n_eq); |
5289 | 354 else |
355 x0 = P(1:n); | |
356 endif | |
357 else | |
358 ## The problem is infeasible | |
359 info = 6; | |
360 endif | |
361 endif | |
362 else | |
363 ## xbar is feasible. We use it a starting point. | |
364 x0 = xbar; | |
365 endif | |
366 else | |
367 ## xbar is feasible. We use it a starting point. | |
368 x0 = xbar; | |
369 endif | |
370 endif | |
371 | |
372 if (info == 0) | |
373 ## The initial (or computed) guess is feasible. | |
374 ## We call the solver. | |
375 [x, lambda, info, iter] = __qp__ (x0, H, q, A, b, Ain, bin, maxit); | |
376 else | |
377 iter = 0; | |
378 x = x0; | |
379 lambda = []; | |
380 endif | |
381 obj = 0.5 * x' * H * x + q' * x; | |
382 INFO.solveiter = iter; | |
383 INFO.info = info; | |
384 | |
385 else | |
6046 | 386 print_usage (); |
5289 | 387 endif |
388 | |
389 endfunction |