comparison 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
comparison
equal deleted inserted replaced
10058:1be07aac495d 10059:665ad34efeed
16 ## You should have received a copy of the GNU General Public License 16 ## You should have received a copy of the GNU General Public License
17 ## along with Octave; see the file COPYING. If not, see 17 ## along with Octave; see the file COPYING. If not, see
18 ## <http://www.gnu.org/licenses/>. 18 ## <http://www.gnu.org/licenses/>.
19 19
20 ## -*- texinfo -*- 20 ## -*- texinfo -*-
21 ## @deftypefn {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}) 21 ## @deftypefn {Function File} {[@var{x}, @var{obj}, @var{info}, @var{lambda}] =} qp (@var{x0}, @var{H})
22 ## @deftypefnx {Function File} {[@var{x}, @var{obj}, @var{info}, @var{lambda}] =} qp (@var{x0}, @var{H}, @var{q})
23 ## @deftypefnx {Function File} {[@var{x}, @var{obj}, @var{info}, @var{lambda}] =} qp (@var{x0}, @var{H}, @var{q}, @var{A}, @var{b})
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})
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})
26 ## @deftypefnx {Function File} {[@var{x}, @var{obj}, @var{info}, @var{lambda}] =} qp (@dots{}, @var{options})
22 ## Solve the quadratic program 27 ## Solve the quadratic program
23 ## @tex 28 ## @tex
24 ## $$ 29 ## $$
25 ## \min_x {1 \over 2} x^T H x + x^T q 30 ## \min_x {1 \over 2} x^T H x + x^T q
26 ## $$ 31 ## $$
56 ## using a null-space active-set method. 61 ## using a null-space active-set method.
57 ## 62 ##
58 ## Any bound (@var{A}, @var{b}, @var{lb}, @var{ub}, @var{A_lb}, 63 ## Any bound (@var{A}, @var{b}, @var{lb}, @var{ub}, @var{A_lb},
59 ## @var{A_ub}) may be set to the empty matrix (@code{[]}) if not 64 ## @var{A_ub}) may be set to the empty matrix (@code{[]}) if not
60 ## present. If the initial guess is feasible the algorithm is faster. 65 ## present. If the initial guess is feasible the algorithm is faster.
66 ##
67 ## @table @var
68 ## @item options
69 ## An optional structure containing the following
70 ## parameter(s) used to define the behavior of the solver. Missing elements
71 ## in the structure take on default values, so you only need to set the
72 ## elements that you wish to change from the default.
73 ##
74 ## @table @code
75 ## @item MaxIter (default: 200)
76 ## Maximum number of iterations.
77 ## @end table
78 ## @end table
61 ## 79 ##
62 ## The value @var{info} is a structure with the following fields: 80 ## The value @var{info} is a structure with the following fields:
63 ## @table @code 81 ## @table @code
64 ## @item solveiter 82 ## @item solveiter
65 ## The number of iterations required to find the solution. 83 ## The number of iterations required to find the solution.
78 ## The problem is infeasible. 96 ## The problem is infeasible.
79 ## @end table 97 ## @end table
80 ## @end table 98 ## @end table
81 ## @end deftypefn 99 ## @end deftypefn
82 100
83 function [x, obj, INFO, lambda] = qp (x0, H, q, A, b, lb, ub, A_lb, A_in, A_ub) 101 function [x, obj, INFO, lambda] = qp (x0, H, varargin)
84 102
85 if (nargin == 5 || nargin == 7 || nargin == 10) 103 nargs = nargin;
104
105 if (nargs > 2 && isstruct (varargin{end}))
106 options = varargin{end};
107 nargs--;
108 else
109 options = struct ();
110 endif
111
112 if (nargs >= 3)
113 q = varargin{1};
114 else
115 q = [];
116 endif
117
118 if (nargs >= 5)
119 A = varargin{2};
120 b = varargin{3};
121 else
122 A = [];
123 b = [];
124 endif
125
126 if (nargs >= 7)
127 lb = varargin{4};
128 ub = varargin{5};
129 else
130 lb = [];
131 ub = [];
132 endif
133
134 if (nargs == 10)
135 A_lb = varargin{6};
136 A_in = varargin{7};
137 A_ub = varargin{8};
138 else
139 A_lb = [];
140 A_in = [];
141 A_ub = [];
142 endif
143
144 if (nargs == 2 || nargs == 3 || nargs == 5 || nargs == 7 || nargs == 10)
145
146 maxit = optimget (options, "MaxIter", 200)
86 147
87 ## Checking the quadratic penalty 148 ## Checking the quadratic penalty
88 if (! issquare (H)) 149 if (! issquare (H))
89 error ("qp: quadratic penalty matrix not square"); 150 error ("qp: quadratic penalty matrix not square");
90 elseif (! ishermitian (H)) 151 elseif (! ishermitian (H))
95 156
96 ## Checking the initial guess (if empty it is resized to the 157 ## Checking the initial guess (if empty it is resized to the
97 ## right dimension and filled with 0) 158 ## right dimension and filled with 0)
98 if (isempty (x0)) 159 if (isempty (x0))
99 x0 = zeros (n, 1); 160 x0 = zeros (n, 1);
100 elseif (length (x0) != n) 161 elseif (numel (x0) != n)
101 error ("qp: the initial guess has incorrect length"); 162 error ("qp: the initial guess has incorrect length");
102 endif 163 endif
103 164
104 ## Linear penalty. 165 ## Linear penalty.
105 if (length (q) != n) 166 if (isempty (q))
167 q = zeros (n, 1);
168 elseif (numel (q) != n)
106 error ("qp: the linear term has incorrect length"); 169 error ("qp: the linear term has incorrect length");
107 endif 170 endif
108 171
109 ## Equality constraint matrices 172 ## Equality constraint matrices
110 if (isempty (A) || isempty(b)) 173 if (isempty (A) || isempty (b))
174 A = zeros (0, n);
175 b = zeros (0, 1);
111 n_eq = 0; 176 n_eq = 0;
112 A = zeros (n_eq, n);
113 b = zeros (n_eq, 1);
114 else 177 else
115 [n_eq, n1] = size (A); 178 [n_eq, n1] = size (A);
116 if (n1 != n) 179 if (n1 != n)
117 error ("qp: equality constraint matrix has incorrect column dimension"); 180 error ("qp: equality constraint matrix has incorrect column dimension");
118 endif 181 endif
119 if (length (b) != n_eq) 182 if (numel (b) != n_eq)
120 error ("qp: equality constraint matrix and vector have inconsistent dimension"); 183 error ("qp: equality constraint matrix and vector have inconsistent dimension");
121 endif 184 endif
122 endif 185 endif
123 186
124 ## Bound constraints 187 ## Bound constraints
125 Ain = zeros (0, n); 188 Ain = zeros (0, n);
126 bin = zeros (0, 1); 189 bin = zeros (0, 1);
127 n_in = 0; 190 n_in = 0;
128 if (nargin > 5) 191 if (nargs > 5)
129 if (! isempty (lb)) 192 if (! isempty (lb))
130 if (length(lb) != n) 193 if (numel (lb) != n)
131 error ("qp: lower bound has incorrect length"); 194 error ("qp: lower bound has incorrect length");
132 elseif (isempty (ub)) 195 elseif (isempty (ub))
133 Ain = [Ain; eye(n)]; 196 Ain = [Ain; eye(n)];
134 bin = [bin; lb]; 197 bin = [bin; lb];
135 endif 198 endif
136 endif 199 endif
137 200
138 if (! isempty (ub)) 201 if (! isempty (ub))
139 if (length (ub) != n) 202 if (numel (ub) != n)
140 error ("qp: upper bound has incorrect length"); 203 error ("qp: upper bound has incorrect length");
141 elseif (isempty (lb)) 204 elseif (isempty (lb))
142 Ain = [Ain; -eye(n)]; 205 Ain = [Ain; -eye(n)];
143 bin = [bin; -ub]; 206 bin = [bin; -ub];
144 endif 207 endif
164 endfor 227 endfor
165 endif 228 endif
166 endif 229 endif
167 230
168 ## Inequality constraints 231 ## Inequality constraints
169 if (nargin > 7) 232 if (nargs > 7)
170 [dimA_in, n1] = size (A_in); 233 [dimA_in, n1] = size (A_in);
171 if (n1 != n) 234 if (n1 != n)
172 error ("qp: inequality constraint matrix has incorrect column dimension"); 235 error ("qp: inequality constraint matrix has incorrect column dimension");
173 else 236 else
174 if (! isempty (A_lb)) 237 if (! isempty (A_lb))
175 if (length (A_lb) != dimA_in) 238 if (numel (A_lb) != dimA_in)
176 error ("qp: inequality constraint matrix and lower bound vector inconsistent"); 239 error ("qp: inequality constraint matrix and lower bound vector inconsistent");
177 elseif (isempty (A_ub)) 240 elseif (isempty (A_ub))
178 Ain = [Ain; A_in]; 241 Ain = [Ain; A_in];
179 bin = [bin; A_lb]; 242 bin = [bin; A_lb];
180 endif 243 endif
181 endif 244 endif
182 if (! isempty (A_ub)) 245 if (! isempty (A_ub))
183 if (length (A_ub) != dimA_in) 246 if (numel (A_ub) != dimA_in)
184 error ("qp: inequality constraint matrix and upper bound vector inconsistent"); 247 error ("qp: inequality constraint matrix and upper bound vector inconsistent");
185 elseif (isempty (A_lb)) 248 elseif (isempty (A_lb))
186 Ain = [Ain; -A_in]; 249 Ain = [Ain; -A_in];
187 bin = [bin; -A_ub]; 250 bin = [bin; -A_ub];
188 endif 251 endif
219 idx = isinf (bin) & bin < 0; 282 idx = isinf (bin) & bin < 0;
220 283
221 bin(idx) = []; 284 bin(idx) = [];
222 Ain(idx,:) = []; 285 Ain(idx,:) = [];
223 286
224 n_in = length (bin); 287 n_in = numel (bin);
225 288
226 ## Check if the initial guess is feasible. 289 ## Check if the initial guess is feasible.
227 if (isa (x0, "single") || isa (H, "single") || isa (q, "single") || isa (A, "single") 290 if (isa (x0, "single") || isa (H, "single") || isa (q, "single") || isa (A, "single")
228 || isa (b, "single")) 291 || isa (b, "single"))
229 rtol = sqrt (eps ("single")); 292 rtol = sqrt (eps ("single"));
305 x0 = xbar; 368 x0 = xbar;
306 endif 369 endif
307 endif 370 endif
308 371
309 if (info == 0) 372 if (info == 0)
310 ## FIXME -- make maxit a user option.
311 ## The initial (or computed) guess is feasible. 373 ## The initial (or computed) guess is feasible.
312 ## We call the solver. 374 ## We call the solver.
313 maxit = 200;
314 [x, lambda, info, iter] = __qp__ (x0, H, q, A, b, Ain, bin, maxit); 375 [x, lambda, info, iter] = __qp__ (x0, H, q, A, b, Ain, bin, maxit);
315 else 376 else
316 iter = 0; 377 iter = 0;
317 x = x0; 378 x = x0;
318 lambda = []; 379 lambda = [];