% IPOPT Call the IPOPT constrained, nonlinear solver.
% The basic function call is
%
% [x, info] = IPOPT(x0,funcs,options)
%
% The first input is either a matrix or a cell array of matrices. It
% declares the starting point for the solver.
%
% CALLBACK FUNCTIONS
%
% The second input must be struct containing function handles for various
% MATLAB routines. For more information on using functions and function
% handles in MATLAB, type HELP FUNCTION and HELP FUNCTION_HANDLE in the
% MATLAB prompt.
%
% funcs.objective (required)
%
% Calculates the objective function at the current point. It takes one
% point, the current iterate x. For example, the definition of the
% objective function for the Hock & Schittkowski (H&S) test problem #71
% (with 4 optimization variables) would be
%
% function f = objective (x)
% f = x(1)*x(4)*sum(x(1:3)) + x(3);
%
% funcs.gradient (required)
%
% Computes the gradient of the objective at the current point. It takes
% one input, the current iterate x. For H&S test problem #71, the
% definition of the gradient callback would be
%
% function g = gradient (x)
% g = [ x(1)*x(4) + x(4)*sum(x(1:3))
% x(1)*x(4)
% x(1)*x(4) + 1
% x(1)*sum(x(1:3)) ];
%
% funcs.constraints (optional)
%
% This function is only required if there are constraints on your
% variables. It evaluates the constraint functions at the current
% point. It takes one input, x. The return value is a vector of length
% equal to the number of constraints (it must be of the same length as
% options.cl and options.cu). For H&S test problem #71, the
% callback definition would be
%
% function c = constraints (x)
% c = [ prod(x); sum(x.^2) ];
%
% funcs.jacobian (optional)
%
% This function is only required if there are constraints on your
% variables. Evaluates the Jacobian of the constraints at the current
% point. It takes one input, x. The output must always be an M x N
% sparse matrix, where M is the number of constraints and N is the
% number of variables. Type HELP SPARSE for more information on
% constructing sparse matrices in MATLAB. The definition of the
% callback function for H&S test problem #71 would be
%
% function J = jacobian (x)
% sparse([ prod(x)./x; 2*x ]);
%
% Notice that the return value is a sparse matrix.
%
% funcs.jacobianstructure (optional)
%
% This function is only required if there are constraints on your
% variables. It takes no inputs. The return value is a sparse
% matrix whereby an entry is nonzero if and only if the Jacobian of
% the constraints is nonzero at ANY point. The callback function for
% the H&S test problem #71 simply returns a 2 x 4 matrix of ones in
% the sparse matrix format:
%
% function J = jacobianstructure()
% J = sparse(ones(2,4));
%
% funcs.hessian (optional)
%
% Evaluates the Hessian of the Lagrangian at the current point. It
% must be specified unless you choose to use the limited-memory
% quasi-Newton approximation to the Hessian (see below).
%
% The callback function has three inputs: the current point (x), a
% scalar factor on the objective (sigma), and the Lagrange multipliers
% (lambda), a vector of length equal to the number of constraints. The
% function should compute
%
% sigma*H + lambda(1)*G1 + ... + lambda(M)*GM
%
% where M is the number of constraints, H is the Hessian of the
% objective and the G's are the Hessians of the constraint
% functions. The output must always be an N x N sparse, lower triangular
% matrix, where N is the number of variables. In other words, if X is
% the output value, then X must be the same as TRIL(X).
%
% Here is an implementation of the Hessian callback routine for the
% H&S test problem #71:
%
% function H = hessian (x, sigma, lambda)
% H = sigma*[ 2*x(4) 0 0 0;
% x(4) 0 0 0;
% x(4) 0 0 0;
% 2*x(1)+x(2)+x(3) x(1) x(1) 0 ];
% H = H + lambda(1)*[ 0 0 0 0;
% x(3)*x(4) 0 0 0;
% x(2)*x(4) x(1)*x(4) 0 0;
% x(2)*x(3) x(1)*x(3) x(1)*x(2) 0 ];
% H = sparse(H + lambda(2)*diag([2 2 2 2]));
%
% funcs.hessianstructure (optional)
%
% This function serves the same purpose as funcs.jacobianstructure, but
% for the Hessian matrix. Again, it is not needed if you are using the
% limited-memory quasi-Newton approximation to the Hessian. It takes no
% inputs, and must return a sparse, lower triangular matrix. For H&S
% test problem #71, the MATLAB callback routine is fairly
% straightforward:
%
% function H = hessianstructure()
% H = sparse(tril(ones(4)));
%
% funcs.iterfunc (optional)
%
% An additional callback routine that is called once per algorithm
% iteration. It takes three inputs: the first is the current iteration
% of the algorithm, the second is the current value of the objective,
% and the third is a structure containing fields x, inf_pr, inf_du, mu,
% d_norm, regularization_size, alpha_du, alpha_pr, and ls_trials. This
% function should always return true unless you want IPOPT to terminate
% prematurely for whatever reason. If you would like to use the third
% input to iterfunc along with auxdata functionality, you will need to
% modify the appropriate section of ipopt_auxdata.m.
%
% OPTIONS
%
% The options are passed through the third input. What follows is a
% description of the fields you may optionally specify.
%
% options.lb
%
% Specify lower bounds on the variables. It must have the same number
% of elements as x0. Set an entry to -Inf to specify no lower bound.
%
% options.ub
%
% Specify upper bounds on the variables. It must have the same number
% of elements as x0. Set an entry to Inf to specify no upper bound.
%
% options.cl, options.cu
%
% Set lower and upper bounds on the constraints. Each should be a
% vector of length equal to the number of constraints. As before, a
% bound is removed by setting the entry to -Inf or +Inf. An equality
% constraint is achieved by setting cl(i) = cu(i).
%
% options.auxdata
%
% Optionally, one may choose to pass additional auxiliary data to the
% MATLAB callback routines listed above through the function call. For
% instance, the objective callback function now takes two inputs, x and
% auxdata. The auxiliary data may not change through the course of the
% IPOPT optimization. The auxiliary data keep the same values as they
% possessed in the initial call. If you need variables that change over
% time, you may want to consider global variables (type HELP
% GLOBAL). See the lasso.m file in the examples subdirectory for an
% illustration of how the auxiliary data is passed to the various
% callback functions. Starting with Ipopt version 3.11, you must call
% ipopt_auxdata(x0,funcs,options) to use auxdata functionality.
%
% options.zl, options.zu, options.lambda
%
% These fields specify the initial value for the Lagrange multipliers,
% which is especially useful for "warm starting" the interior-point
% solver. They specify the Lagrange multipliers corresponding to the
% lower bounds on the variables, upper bounds on the variables, and
% constraints, respectively.
%
% options.ipopt
%
% Finally, you may also change the settings of IPOPT through this
% field. For instance, to turn off the IPOPT output, use the
% limited-memory BFGS approximation to the Hessian, and turn on the
% derivative checker, do the following:
%
% options.ipopt.print_level = 0;
% options.ipopt.hessian_approximation = 'limited-memory';
% options.ipopt.derivative_test = 'first-order';
%
% For more details, see the documentation on the IPOPT website.
%
% OUTPUTS
%
% If the solver successfully converges to a stationary point or terminated
% without an unrecoverable error, the function IPOPT outputs the candidate
% solution x. In all other cases, an error is thrown. It also outputs some
% additional information:
%
% info.zl, info.zu, info.lambda
%
% The value of the Lagrange multipliers at the solution. See the
% "options" for more information on the Lagrange multipliers.
%
% info.status
%
% Upon termination, this field will take on one of these following
% values (for a more up-to-date listing, see the IpReturnCodes.h header
% file in the IPOPT C++ source directory):
%
% 0 solved
% 1 solved to acceptable level
% 2 infeasible problem detected
% 3 search direction becomes too small
% 4 diverging iterates
% 5 user requested stop
%
% -1 maximum number of iterations exceeded
% -2 restoration phase failed
% -3 error in step computation
% -10 not enough degrees of freedom
% -11 invalid problem definition
% -12 invalid option
% -13 invalid number detected
%
% -100 unrecoverable exception
% -101 non-IPOPT exception thrown
% -102 insufficient memory
% -199 internal error
%
% info.iter, info.cpu
%
% Number of iterations and CPU time (in seconds) taken by the Ipopt run
%
% Finally, for more information, please consult the following webpages:
%
% http://www.cs.ubc.ca/~pcarbo/ipopt-for-matlab
% http://projects.coin-or.org/Ipopt
%
% Copyright (C) 2008 Peter Carbonetto. All Rights Reserved.
% This code is published under the Eclipse Public License.
%
% Author: Peter Carbonetto
% Dept. of Computer Science
% University of British Columbia
% September 19, 2008