function [alpha] = line_search(fcn,x,ds,finf,sigma,guess,maxit); % LINE_SEARCH: A line search descent method under improved Wolfe-Powell conditions: % it imposes a more stringent two-sided test on the slope, which allows the user to restrict % the set of acceptable points to a small neighbourhood of a local minimizer % by reducing 'sigma'. Moreover, cubic interpolation is applied. Based on: % Wolfe (1968): "Convergence conditions for ascent methods", % Powell (1976): "Some global convergence properties of a variable % metric algorithm for minimization without exact line searches", and % Fletcher (2006): "Practical Methods of Optimization". % % inputs: % required: % fcn: the name of a matlab function that must return the value % of the function to be minimized 'f' and its first-derivative 'df' % evaluated at a given point 'x', a given search direction 'ds', % and a given guess "alpha". % x: a given point of the domain of 'f'. % ds: a given search direction. % finf: a lower bound on f. Any f0 error('descent condition is not satisfied: df>0!'); end f(1)=f0; df(1)=df0; u = (finf-f0)/(ro*df0); % BRACKETING PHASE for i=2:maxit [f(i),df(i)] = feval(fcn,x,ds,alpha(i)); if f(i) <= finf flag=1; break, end % terminate 'line search' if f(i) > f0 + alpha(i)*ro*df0 | f(i) >= f0 a(i) = alpha(i-1); b(i) = alpha(i); break, end % terminate 'bracketing phase' if abs(df(i)) <= -sigma*df0' flag=1; break % terminate 'line search' elseif df(i) >= 0 a(i) = alpha(i); b(i) = alpha(i-1); break, end % terminate 'bracketing phase' if u <= 2*alpha(i) - alpha(i-1) alpha(i+1) = u; else % interval intval = [2*alpha(i)-alpha(i-1), min(u,alpha(i)+t1*(alpha(i)-alpha(i-1)))]; %%% mapping on to [0,1] map = [alpha(i-1) alpha(i)]; dfm(i-1) = (map(2)-map(1))*df(i-1); dfm(i) = (map(2)-map(1))*df(i); % parameters of the Hermite interpolating cubic c1 = f(i-1); c2 = dfm(i-1); c3 = 3*(f(i)-f(i-1)) - 2*dfm(i-1) - dfm(i); c4 = dfm(i-1) + dfm(i) - 2*(f(i)-f(i-1)); % interval: alpha = a + z(b-a); alpha is in intval zmin = (intval(1)-map(1))/(map(2)-map(1)); zmax = (intval(2)-map(1))/(map(2)-map(1)); % min c(z) = c1+c2z+c3z^2+c4z^3, % where z belongs to [zmin,zmax] mincubic = (-c3+sqrt(c3^2-3*c4*dfm(i-1)))/(3*c4); if mincubiczmax, mincubic=zmax; end z=[zmin;zmax;mincubic]; c = c1+c2*z+c3*z.^2+c4.*z.^3; [cmin,indc] = min(c); z = z(indc); % optimal z % New value for alpha alpha(i+1) = map(1) + z*(map(2)-map(1)); end end if flag alpha = alpha (i); return % SECTIONING PHASE else for k=i:maxit % mapping [a,b] on to [0,1] [fa(k),dfa(k)] = feval(fcn,x,ds,a(k)); [fb(k),dfb(k)] = feval(fcn,x,ds,b(k)); intval = [a(k)+t2*(b(k)-a(k)),b(k)-t3*(b(k)-a(k))]; %%% mapping on to [0,1] map = [a(k) b(k)]; dfam(k) = (map(2)-map(1))*dfa(k); dfbm(k) = (map(2)-map(1))*dfb(k); % parameters of the Hermite interpolating cubic c1 = fa(k); c2 = dfam(k); c3 = 3*(fb(k)-fa(k)) - 2*dfam(k) - dfbm(k); c4 = dfam(k) + dfbm(k) - 2*(fb(k)-fa(k)); % interval: alpha = a + z(b-a); alpha is in intval zmin = (intval(1)-map(1))/(map(2)-map(1)); zmax = (intval(2)-map(1))/(map(2)-map(1)); % min c(z) = c1+c2z+c3z^2+c4z^3, % where z belongs to [zmin,zmax] mincubic = (-c3+sqrt(c3^2-3*c4*dfam(k)))/(3*c4); if mincubiczmax, mincubic=zmax; end z=[zmin;zmax;mincubic]; c = c1+c2*z+c3*z.^2+c4.*z.^3; [cmin,indc] = min(c); z = z(indc); % ---> optimal z % New value for alpha alpha(k) = map(1) + z*(map(2)-map(1)); [f(k),df(k)] = feval(fcn,x,ds,alpha(k)); if f(k) > f0+ro*alpha(k)*df0 | f(k) >= fa(k) a(k+1) = a(k); b(k+1) = alpha(k); else if abs(df(k)) <= -sigma*df0 alpha=alpha(k); return, end; % terminate 'line search' a(k+1) = alpha(k); if (b(k)-a(k))*df(k) >= 0 b(k+1)=a(k); else b(k+1)=b(k); end if (a(k)-alpha(k))*dfa(k) <= sqrt(eps) warning('Potential Round-off error, no progress is posible in the line search'); break end end end end