function [ x, it ] = gradient_descent2 ( f, df, x, r, dxtol, dftol, itmax )

  print_out = true;

  if ( print_out )
    fprintf ( 1, '\n' )
    fprintf ( 1, '   it      ||x||               f(x)         ||f''(x)||\n' )
    fprintf ( 1, '\n' )
  end

  it = 0;
  if ( print_out )
    fprintf ( 1, '  %3d  %12.8g  %12.8g  %12.8g\n', it, norm(x), f ( x ), norm ( df ( x ) ) )
  end

  while ( true )

    if ( norm ( df ( x ) ) < dftol )
      if ( print_out )
        fprintf ( 1, '\n' )
        fprintf ( 1, '  Success: ||f''(x)|| = %g < dftol = %g\n', ...
          norm ( df ( x ) ), dftol );
      end
      return
    end

    xold = x;
    beta = 1.0;

    while ( true )

      it = it + 1;
      if ( itmax < it )
        if ( print_out )
          fprintf ( 1, '\n' )
          fprintf ( 1, '  Failure: Step limit exceeded!\n' )
        end
        return
      end

      dx = - beta * r * df ( xold );
      if ( norm ( dx ) < dxtol )
        if ( print_out )
          fprintf ( 1, '\n' )
          fprintf ( 1, '  Success: Step size very small!\n' )
        end
        return
      end

      x = xold + dx;
      if ( f ( x ) < f ( xold ) )
        break
      end

      beta = beta / 2.0;
      if ( beta < 1.0 / 1024.0 ) then
        if ( print_out )
          fprintf ( 1, '\n' )
          fprintf ( 1, '  Failure: Beta too small!\n' )
        end
        return
      end

    end

    if ( print_out )
      fprintf ( 1, '  %3d  %12.8g  %12.8g  %12.8g\n', it, norm(x), f ( x ), norm ( df ( x ) ) )
    end

  end

  return
end


