Mercurial > octave
comparison scripts/optimization/sqp.m @ 6768:40e1255eda0e
[project @ 2007-06-29 20:11:58 by jwe]
author | jwe |
---|---|
date | Fri, 29 Jun 2007 20:12:04 +0000 |
parents | 00116015904d |
children | 2ae5d4353d0b |
comparison
equal
deleted
inserted
replaced
6767:a6c8000f113e | 6768:40e1255eda0e |
---|---|
180 ## increase this value). | 180 ## increase this value). |
181 ## @end table | 181 ## @end table |
182 ## @seealso{qp} | 182 ## @seealso{qp} |
183 ## @end deftypefn | 183 ## @end deftypefn |
184 | 184 |
185 function [x, obj, info, iter, nf, lambda] = sqp (x, objf, cef, cif) | 185 function [x, obj, info, iter, nf, lambda] = sqp (x, objf, cef, cif, lb, ub, maxiter, tolerance) |
186 | 186 |
187 global nfun; | 187 global __sqp_nfun__; |
188 global __sqp_obj_fun__; | 188 global __sqp_obj_fun__; |
189 global __sqp_ce_fun__; | 189 global __sqp_ce_fun__; |
190 global __sqp_ci_fun__; | 190 global __sqp_ci_fun__; |
191 | 191 global __sqp_cif__; |
192 if (nargin >= 2 && nargin <= 4) | 192 global __sqp_cifcn__; |
193 | |
194 if (nargin >= 2 && nargin <= 8 && nargin != 5) | |
193 | 195 |
194 ## Choose an initial NxN symmetric positive definite Hessan | 196 ## Choose an initial NxN symmetric positive definite Hessan |
195 ## approximation B. | 197 ## approximation B. |
196 | 198 |
197 n = length (x); | 199 n = length (x); |
243 endif | 245 endif |
244 __sqp_ce_fun__ = ce_fun; | 246 __sqp_ce_fun__ = ce_fun; |
245 | 247 |
246 ci_fun = @empty_cf; | 248 ci_fun = @empty_cf; |
247 ci_grd = @empty_jac; | 249 ci_grd = @empty_jac; |
250 | |
248 if (nargin > 3) | 251 if (nargin > 3) |
249 ci_grd = @fd_ci_jac; | 252 ## constraint function given by user with possibly gradient |
250 if (iscell (cif)) | 253 __sqp_cif__ = cif; |
251 if (length (cif) > 0) | 254 ## constraint function given by user without gradient |
252 __sqp_ci_fun__ = ci_fun = cif{1}; | 255 __sqp_cifcn__ = @empty_cf; |
253 if (length (cif) > 1) | 256 if (iscell (__sqp_cif__)) |
254 ci_grd = cif{2}; | 257 if (length (__sqp_cif__) > 0) |
258 __sqp_cifcn__ = __sqp_cif__{1}; | |
259 endif | |
260 elseif (! isempty (__sqp_cif__)) | |
261 __sqp_cifcn__ = __sqp_cif__; | |
262 endif | |
263 | |
264 if (nargin < 5) | |
265 ci_grd = @fd_ci_jac; | |
266 if (iscell (cif)) | |
267 if (length (cif) > 0) | |
268 __sqp_ci_fun__ = ci_fun = cif{1}; | |
269 if (length (cif) > 1) | |
270 ci_grd = cif{2}; | |
271 endif | |
272 else | |
273 error ("sqp: invalid equality constraint function"); | |
255 endif | 274 endif |
275 elseif (! isempty (cif)) | |
276 ci_fun = cif; | |
277 endif | |
278 else | |
279 global __sqp_lb__; | |
280 if (isvector (lb)) | |
281 __sqp_lb__ = lb; | |
282 elseif (isempty (lb)) | |
283 __sqp_lb__ = -realmax; | |
256 else | 284 else |
257 error ("sqp: invalid equality constraint function"); | 285 error ("sqp: invalid lower bound"); |
258 endif | 286 endif |
259 elseif (! isempty (cif)) | 287 |
260 ci_fun = cif; | 288 global __sqp_ub__; |
261 endif | 289 if (isvector (ub)) |
290 __sqp_ub__ = ub; | |
291 elseif (isempty (lb)) | |
292 __sqp_ub__ = realmax; | |
293 else | |
294 error ("sqp: invalid upper bound"); | |
295 endif | |
296 | |
297 if (lb > ub) | |
298 error ("sqp: upper bound smaller than lower bound"); | |
299 endif | |
300 __sqp_ci_fun__ = ci_fun = @cf_ub_lb; | |
301 ci_grd = @cigrad_ub_lb; | |
302 endif | |
303 __sqp_ci_fun__ = ci_fun; | |
262 endif | 304 endif |
263 __sqp_ci_fun__ = ci_fun; | |
264 | 305 |
265 iter_max = 100; | 306 iter_max = 100; |
307 if (nargin > 6 && ! isempty (maxiter)) | |
308 if (isscalar (maxiter) && maxiter > 0 && round (maxiter) == maxiter)) | |
309 iter_max = maxiter; | |
310 else | |
311 error ("sqp: invalid number of maximum iterations"); | |
312 endif | |
313 endif | |
314 | |
315 tol = sqrt (eps); | |
316 if (nargin > 7 && ! isempty (tolerance)) | |
317 if (isscalar (tolerance) && tolerance > 0) | |
318 tol = tolerance; | |
319 else | |
320 error ("sqp: invalid value for tolerance"); | |
321 endif | |
322 endif | |
266 | 323 |
267 iter = 0; | 324 iter = 0; |
268 | 325 |
269 obj = feval (obj_fun, x); | 326 obj = feval (obj_fun, x); |
270 nfun = 1; | 327 __sqp_nfun__ = 1; |
271 | 328 |
272 c = feval (obj_grd, x); | 329 c = feval (obj_grd, x); |
273 | 330 |
274 if (have_hess) | 331 if (have_hess) |
275 B = feval (obj_hess, x); | 332 B = feval (obj_hess, x); |
292 qp_iter = 1; | 349 qp_iter = 1; |
293 alpha = 1; | 350 alpha = 1; |
294 | 351 |
295 ## report (); | 352 ## report (); |
296 | 353 |
297 ## report (iter, qp_iter, alpha, nfun, obj); | 354 ## report (iter, qp_iter, alpha, __sqp_nfun__, obj); |
298 | 355 |
299 info = 0; | 356 info = 0; |
300 | 357 |
301 while (++iter < iter_max) | 358 while (++iter < iter_max) |
302 | 359 |
316 t1 = norm (ce); | 373 t1 = norm (ce); |
317 t2 = all (ci >= 0); | 374 t2 = all (ci >= 0); |
318 t3 = all (lambda_i >= 0); | 375 t3 = all (lambda_i >= 0); |
319 t4 = norm (lambda .* con); | 376 t4 = norm (lambda .* con); |
320 | 377 |
321 tol = sqrt (eps); | |
322 | |
323 if (t2 && t3 && max ([t0; t1; t4]) < tol) | 378 if (t2 && t3 && max ([t0; t1; t4]) < tol) |
324 break; | 379 break; |
325 endif | 380 endif |
326 | 381 |
327 ## Compute search direction p by solving QP. | 382 ## Compute search direction p by solving QP. |
429 ci = ci_new; | 484 ci = ci_new; |
430 C = C_new; | 485 C = C_new; |
431 | 486 |
432 A = A_new; | 487 A = A_new; |
433 | 488 |
434 ## report (iter, qp_iter, alpha, nfun, obj); | 489 ## report (iter, qp_iter, alpha, __sqp_nfun__, obj); |
435 | 490 |
436 endwhile | 491 endwhile |
437 | 492 |
438 if (iter >= iter_max) | 493 if (iter >= iter_max) |
439 info = 103; | 494 info = 103; |
440 endif | 495 endif |
441 | 496 |
442 nf = nfun; | 497 nf = __sqp_nfun__; |
443 | 498 |
444 else | 499 else |
445 | 500 |
446 print_usage (); | 501 print_usage (); |
447 | 502 |
450 ### endfunction | 505 ### endfunction |
451 | 506 |
452 | 507 |
453 function [merit, obj] = phi_L1 (obj, obj_fun, ce_fun, ci_fun, x, mu) | 508 function [merit, obj] = phi_L1 (obj, obj_fun, ce_fun, ci_fun, x, mu) |
454 | 509 |
455 global nfun; | 510 global __sqp_nfun__; |
456 | 511 |
457 ce = feval (ce_fun, x); | 512 ce = feval (ce_fun, x); |
458 ci = feval (ci_fun, x); | 513 ci = feval (ci_fun, x); |
459 | 514 |
460 idx = ci < 0; | 515 idx = ci < 0; |
461 | 516 |
462 con = [ce; ci(idx)]; | 517 con = [ce; ci(idx)]; |
463 | 518 |
464 if (isempty (obj)) | 519 if (isempty (obj)) |
465 obj = feval (obj_fun, x); | 520 obj = feval (obj_fun, x); |
466 nfun++; | 521 __sqp_nfun__++; |
467 endif | 522 endif |
468 | 523 |
469 merit = obj; | 524 merit = obj; |
470 t = norm (con, 1) / mu; | 525 t = norm (con, 1) / mu; |
471 | 526 |
562 | 617 |
563 ### endfunction | 618 ### endfunction |
564 | 619 |
565 | 620 |
566 function jac = fdjac (f, x) | 621 function jac = fdjac (f, x) |
567 | 622 nx = length (x); |
568 if (! isempty (f)) | 623 if (! isempty (f)) |
569 y0 = feval (f, x); | 624 y0 = feval (f, x); |
570 nf = length (y0); | 625 nf = length (y0); |
571 nx = length (x); | 626 nx = length (x); |
572 jac = zeros (nf, nx); | 627 jac = zeros (nf, nx); |
616 ### endfunction | 671 ### endfunction |
617 | 672 |
618 | 673 |
619 function jac = fd_ci_jac (x) | 674 function jac = fd_ci_jac (x) |
620 | 675 |
621 global __sqp_ci_fun__; | 676 global __sqp_cifcn__; |
622 | 677 ## __sqp_cifcn__ = constraint function without gradients and lb or ub |
623 jac = fdjac (__sqp_ci_fun__, x); | 678 jac = fdjac (__sqp_cifcn__, x); |
624 | 679 |
625 ### endfunction | 680 ### endfunction |
681 | |
682 function res = cf_ub_lb (x) | |
683 | |
684 ## combine constraint function with ub and lb | |
685 global __sqp_cifcn__ __sqp_lb__ __sqp_ub__ | |
686 | |
687 res = [x-__sqp_lb__; __sqp_ub__-x]; | |
688 | |
689 if (! isempty (__sqp_cifcn__)) | |
690 res = [feval(__sqp_cifcn__,x); x-__sqp_lb__; __sqp_ub__-x]; | |
691 endif | |
692 | |
693 ### endfunction | |
694 | |
695 function res = cigrad_ub_lb (x) | |
696 | |
697 global __sqp_cif__ | |
698 | |
699 res = [eye(numel(x)); -eye(numel(x))]; | |
700 | |
701 cigradfcn = @fd_ci_jac; | |
702 | |
703 if (iscell (__sqp_cif__) && length (__sqp_cif__) > 1) | |
704 cigradfcn = __sqp_cif__{2}; | |
705 endif | |
706 | |
707 if (! isempty (cigradfcn)) | |
708 res = [feval(cigradfcn,x); eye(numel(x)); -eye(numel(x))]; | |
709 endif | |
710 | |
711 ### endfunction |