function [xnew,gradnew,alpha,p] = bfgs(searchmtd,fnhess,fngrad,fn,gradold,xold) % usage: [xnew,gradnew,alpha,p] = bfgs(searchmtd,fnhess,fngrad,fn,gradold,xold) % description: does a single step of BFGS method with input parameters: % searchmtd: line search method % fnhess: function hessian name % fngrad: function grad name % fn: function name % gradold: gradient at starting point % xold: starting point % global variables: global parms; global H; % inverse of current Hessian approx % local variables: % xold,xnew: old,new x values % gradold,gradnew: gradf(x*) % alpha: step length used % p: descent direction used p = -H*gradold; n = length(xold); if (p'*gradold >= 0) % not a descent direction? disp('Restart due to non-descent direction') H = eye(n); p = -gradold; end alpha = feval(searchmtd,fngrad,fn,xold,p); xnew = xold + alpha*p; gradnew = feval(fngrad,xnew); s = xnew-xold; y = gradnew - gradold; rho = y'*s; % update H for next iteration if (rho <= 0) % rho negative? shouldn't happen disp('Did a matrix restart due to negative rho') H = eye(n); % do a restart else mtmp = eye(n)-s*y'/rho; H = mtmp*H*mtmp + s*s'/rho; end