# HG changeset patch # User jwe # Date 1183147924 0 # Node ID 40e1255eda0e75c5376642c581b9941238fd4fc3 # Parent a6c8000f113ec4cc84f7eb1ffe17b12c367b953f [project @ 2007-06-29 20:11:58 by jwe] diff -r a6c8000f113e -r 40e1255eda0e scripts/ChangeLog --- a/scripts/ChangeLog Thu Jun 28 19:42:42 2007 +0000 +++ b/scripts/ChangeLog Fri Jun 29 20:12:04 2007 +0000 @@ -1,3 +1,9 @@ +2007-06-29 Marcus W. Reble + + * optimization/sqp.m (sqp): New args, lb, ub, maxiter, and tolerance. + (fdjac): Set nx outside of if block. + (cf_ub_lb, cigrad_ub_lb): New subfunctons. + 2007-06-28 Michael Goffioul * plot/subplot.m: Add 'ishandle' check when parsing the existing axes. diff -r a6c8000f113e -r 40e1255eda0e scripts/optimization/sqp.m --- a/scripts/optimization/sqp.m Thu Jun 28 19:42:42 2007 +0000 +++ b/scripts/optimization/sqp.m Fri Jun 29 20:12:04 2007 +0000 @@ -182,14 +182,16 @@ ## @seealso{qp} ## @end deftypefn -function [x, obj, info, iter, nf, lambda] = sqp (x, objf, cef, cif) +function [x, obj, info, iter, nf, lambda] = sqp (x, objf, cef, cif, lb, ub, maxiter, tolerance) - global nfun; + global __sqp_nfun__; global __sqp_obj_fun__; global __sqp_ce_fun__; global __sqp_ci_fun__; + global __sqp_cif__; + global __sqp_cifcn__; - if (nargin >= 2 && nargin <= 4) + if (nargin >= 2 && nargin <= 8 && nargin != 5) ## Choose an initial NxN symmetric positive definite Hessan ## approximation B. @@ -245,29 +247,84 @@ ci_fun = @empty_cf; ci_grd = @empty_jac; + if (nargin > 3) - ci_grd = @fd_ci_jac; - if (iscell (cif)) - if (length (cif) > 0) - __sqp_ci_fun__ = ci_fun = cif{1}; - if (length (cif) > 1) - ci_grd = cif{2}; + ## constraint function given by user with possibly gradient + __sqp_cif__ = cif; + ## constraint function given by user without gradient + __sqp_cifcn__ = @empty_cf; + if (iscell (__sqp_cif__)) + if (length (__sqp_cif__) > 0) + __sqp_cifcn__ = __sqp_cif__{1}; + endif + elseif (! isempty (__sqp_cif__)) + __sqp_cifcn__ = __sqp_cif__; + endif + + if (nargin < 5) + ci_grd = @fd_ci_jac; + if (iscell (cif)) + if (length (cif) > 0) + __sqp_ci_fun__ = ci_fun = cif{1}; + if (length (cif) > 1) + ci_grd = cif{2}; + endif + else + error ("sqp: invalid equality constraint function"); endif + elseif (! isempty (cif)) + ci_fun = cif; + endif + else + global __sqp_lb__; + if (isvector (lb)) + __sqp_lb__ = lb; + elseif (isempty (lb)) + __sqp_lb__ = -realmax; else - error ("sqp: invalid equality constraint function"); + error ("sqp: invalid lower bound"); endif - elseif (! isempty (cif)) - ci_fun = cif; + + global __sqp_ub__; + if (isvector (ub)) + __sqp_ub__ = ub; + elseif (isempty (lb)) + __sqp_ub__ = realmax; + else + error ("sqp: invalid upper bound"); + endif + + if (lb > ub) + error ("sqp: upper bound smaller than lower bound"); + endif + __sqp_ci_fun__ = ci_fun = @cf_ub_lb; + ci_grd = @cigrad_ub_lb; + endif + __sqp_ci_fun__ = ci_fun; + endif + + iter_max = 100; + if (nargin > 6 && ! isempty (maxiter)) + if (isscalar (maxiter) && maxiter > 0 && round (maxiter) == maxiter)) + iter_max = maxiter; + else + error ("sqp: invalid number of maximum iterations"); endif endif - __sqp_ci_fun__ = ci_fun; - iter_max = 100; + tol = sqrt (eps); + if (nargin > 7 && ! isempty (tolerance)) + if (isscalar (tolerance) && tolerance > 0) + tol = tolerance; + else + error ("sqp: invalid value for tolerance"); + endif + endif iter = 0; obj = feval (obj_fun, x); - nfun = 1; + __sqp_nfun__ = 1; c = feval (obj_grd, x); @@ -294,7 +351,7 @@ ## report (); - ## report (iter, qp_iter, alpha, nfun, obj); + ## report (iter, qp_iter, alpha, __sqp_nfun__, obj); info = 0; @@ -318,8 +375,6 @@ t3 = all (lambda_i >= 0); t4 = norm (lambda .* con); - tol = sqrt (eps); - if (t2 && t3 && max ([t0; t1; t4]) < tol) break; endif @@ -431,7 +486,7 @@ A = A_new; - ## report (iter, qp_iter, alpha, nfun, obj); + ## report (iter, qp_iter, alpha, __sqp_nfun__, obj); endwhile @@ -439,7 +494,7 @@ info = 103; endif - nf = nfun; + nf = __sqp_nfun__; else @@ -452,7 +507,7 @@ function [merit, obj] = phi_L1 (obj, obj_fun, ce_fun, ci_fun, x, mu) - global nfun; + global __sqp_nfun__; ce = feval (ce_fun, x); ci = feval (ci_fun, x); @@ -463,7 +518,7 @@ if (isempty (obj)) obj = feval (obj_fun, x); - nfun++; + __sqp_nfun__++; endif merit = obj; @@ -564,7 +619,7 @@ function jac = fdjac (f, x) - + nx = length (x); if (! isempty (f)) y0 = feval (f, x); nf = length (y0); @@ -618,8 +673,39 @@ function jac = fd_ci_jac (x) - global __sqp_ci_fun__; + global __sqp_cifcn__; + ## __sqp_cifcn__ = constraint function without gradients and lb or ub + jac = fdjac (__sqp_cifcn__, x); + +### endfunction + +function res = cf_ub_lb (x) - jac = fdjac (__sqp_ci_fun__, x); + ## combine constraint function with ub and lb + global __sqp_cifcn__ __sqp_lb__ __sqp_ub__ + + res = [x-__sqp_lb__; __sqp_ub__-x]; + + if (! isempty (__sqp_cifcn__)) + res = [feval(__sqp_cifcn__,x); x-__sqp_lb__; __sqp_ub__-x]; + endif ### endfunction + +function res = cigrad_ub_lb (x) + + global __sqp_cif__ + + res = [eye(numel(x)); -eye(numel(x))]; + + cigradfcn = @fd_ci_jac; + + if (iscell (__sqp_cif__) && length (__sqp_cif__) > 1) + cigradfcn = __sqp_cif__{2}; + endif + + if (! isempty (cigradfcn)) + res = [feval(cigradfcn,x); eye(numel(x)); -eye(numel(x))]; + endif + +### endfunction \ No newline at end of file