function [X, fX] = wrap_lbfgsb(X, Xlow, Xupp, f, length, varargin)
% Minimize a differentiable multivariate function using quasi Newton.
%
% Usage: [X, fX, i] = wrap_lbfgsb(X, Xlow, Xupp, f, length, P1, P2, P3, ... )
%
% X initial guess
% Xlow lower bound
% Xupp upper bound
% f the name or pointer to the function to be minimized. The function
% f must return two arguments, the value of the function, and it's
% partial derivatives wrt the elements of X. The partial derivative
% must have the same type as X.
% length absolute value is the number of function evaluations allowed
% if it is positive, only positive X are allowed i.e. X>=0 is enforced
% P1, P2 ... parameters are passed to the function f.
%
% X the returned solution
% fX vector of function values indicating progress made
%
% The function returns when either its length is up, or if no further progress
% can be made (ie, we are at a (local) minimum, or so close that due to
% numerical problems, we cannot get any closer). NOTE: If the function
% terminates within a few iterations, it could be an indication that the
% function values and derivatives are not consistent (ie, there may be a bug in
% the implementation of your "f" function).
%
% (c) by Hannes Nickisch, MPI for Biological Cybernetics, 2010 October 14
% no callback routine used so far
% m is the number of saved vectors used to estimate the Hessian
% factr is the precision 1e-12
X = lbfgsb( X, Xlow, Xupp, 'wrap_lbfgsb_objfun', ...
'wrap_lbfgsb_gradfun', {f,varargin{:}}, [], ...
'maxiter',abs(length), 'm',4, 'factr',1e-12, 'pgtol',1e-5);
fX = feval(f,X,varargin{:});