function [xn,fxn,ro,info]=armijo(f,x,d,fx,gfx)
%
% function [xn,fxn,ro,info]=armijo(f,x,d,fx,gfx)
%
%     Copyright: Eduardo Casas (Octubre, 2000)
%
% Funcion que implementa la regla de Armijo
% Variables de Entrada:
%
% f      Funcion a minimizar.
% x      Punto actual de las iteraciones.
% d      Direccion de descenso.
% fx     Valor de f en x.
% gfx    Valor del gradiente de f en x.
%
% Variables de Salida:
%
% xn     Nuevo punto: xn = x + ro*d.
% fxn    Valor de f en xn.
% ro     Valor del paso calculado.
% info   Variable que toma el valor 0 si [xn,fxn]
%        ha sido calculado en el numero maximo de iteraciones
%        previsto y -1 en caso contrario.
%
ro=1;
maxiter=30;
sigma=0.001;      
beta1=0.1;
beta2=0.5;
gfxd=gfx'*d;
r=sigma*gfxd;
for i=1:maxiter
   xn=x+ro*d;
   fxn=feval(f,xn);
   if fxn <= fx+ro*r
      info=0;
      return;
   else
      a=beta1*ro;
      b=beta2*ro;
      if i == 1
         h=[fx;gfxd;fxn];
         t=ro;
         ro=nuevoro(a,b,t,h);
         t=[0;0;t];
         h(2)=fx;
      else
         t=[t(2);t(3);ro];
         h=[h(2);h(3);fxn];
         ro=nuevoro(a,b,t,h);
      end
   end
end
info=-1;
%
%
function ro=nuevoro(a,b,t,h)
%
% function ro=nuevoro(a,b,t,h)
%
% Esta funcion calcula el minimo absoluto tn en [a,b] de un
% polinomio de grado 2. Si t es un escalar, entonces se supone
% que h(1) representa el valor del polinomio en 0, h(2) su
% derivada en el mismo punto y h(3) el valor del polinomio en
% t. Si t es un vector de tres componentes, entonces h es un
% vector que contiene los valores del polinomio en los nodos de
% t:         p(t(i)) = h(i).
%
n=length(t);
if n==1
   c=[(h(3)-h(2)*t-h(1))/t^2;h(2);h(1)];
else
   c=[t.^2,t,ones(3,1)]\h;
end
if c(1) > eps
   ro=-c(2)/(2*c(1));
   ro=min(max(ro,a),b);
else
    pa=polyval(c,a);
    pb=polyval(c,b);
    if pa<pb,
        ro=a;
    else
        ro=b;
    end
end
