% function [f,g,H] = Frosenbrock(X[,a]) Rosenbrock's function
%
% Rosenbrock's function is an optimization benchmark. In n variables (where
% n must be even and a is a parameter):
%
%   f(x) = sum^{n/2}_{i=1}{ a.(x_{2i}-x²_{2i-1})² + (1 - x_{2i-1})² }
%
% For a>0, f has a unique minimiser at x=ones(1,n) where f=0. In 2D:
%
%   f(x) = a.(x2-x1²)² + (1-x1)²
%
% In:
%   X: Nxn list of row vectors.
%   a: real number. Default: 100.
% Out:
%   f: Nx1 list of function values.
%   g: N x n list of gradient vectors.
%   H: n x n x N list of Hessian matrices.
%
% Any non-mandatory argument can be given the value [] to force it to take
% its default value.

% Copyright (c) 2010 by Miguel A. Carreira-Perpinan

function [f,g,H] = Frosenbrock(X,a)

% ---------- Argument defaults ----------
if ~exist('a','var') | isempty(a) a = 100; end;
% ---------- End of "argument defaults" ----------

[N,n] = size(X); X1 = X(:,1:2:n); X2 = X(:,2:2:n);

f = sum(a*(X2-X1.^2).^2 + (1-X1).^2,2);

if nargout > 1
  ind = [1:n/2;n/2+1:n]; ind = ind(:);
  g = [-4*a*X1.*(X2-X1.^2)-2*(1-X1) 2*a*(X2-X1.^2)]; g = g(:,ind);
  if nargout > 2
    H = zeros(n,n,N);
    j=0;
    for i=1:2:n
      j=j+1;
      H(i,i,:) = -4*a*(-3*X1(:,j).^2+X2(:,j))+2;
      H(i,i+1,:) = -4*a*X1(:,j); H(i+1,i,:) = H(i,i+1,:);
      H(i+1,i+1,:) = 2*a;
    end
  end
end

