This example of using MAD with TOMLAB to solve a constrained nonlinear optimization problem is split over several files listed below. You can download the code as a zip file here.

solvecons.m

Our simple problem is:

$$\max \sum_{i=1}^J log( \theta_i )$$

subject to:

$$\sum_{i=1}^J \theta_i^2 = 1$$

where $\theta$ is a vector of length J and for all i : 0 < $\theta_i$ < 1

This file actually runs Tomlab and computes the solution. We need additional Matlab files to define the objective function and the constraint function.

These extra files are: 'ofunc.m', 'ograd.m', and 'consfunc.m' and 'consjac.m'

J = 200;
theta_guess = ones(J,1);

% Define a lower bound very close to 0, but positive so we don't do log(0)
theta_lbound = zeros(J,1) + 1e-8;
theta_ubound = ones(J,1);


% Define the problem in Tomlab.
% This is a complex function, so refer closely to the 'conAssign'
% documentation when writing your code.
%
prob = conAssign('ofunc',  ...   % Name of function to optimize
                 'ograd', ...    % Name of function for gradient
                 [], ...         % Leave empty to let Tomlab compute Hessian
                 [], ...         % and Hessian pattern
                 theta_lbound, ...
                 theta_ubound, ... % Simple bounds on parameters
                 'Demo Cons', ...  % Problem name
                 theta_guess, ...
                 [], [], ...       % Unused parameters, leave empty
                 [],[],[], ...     % Linear constraints, which we don't have, so
                 ...               % leave empty
                 'consfunc',...    % Name of our constraint function
                 'consjac', ...    % Constraint Jacobian
                 [],...            % We have not implemented the Hessian of our
                 [],...            % constraints, so leave this empty
                 1, 1 ...          % Require constraint == 1
                 ...               % (We set the lower and upper constraint
                 ...               % bounds both to 1 to indicate equality
                 ...               % constraints)
                 );


% Initialize MAD - the Matlab Automatic Differentiation
% toolbox (from Tomlab) to compute derivatives for us
madinitglobals;

% Tell MAD to compute the Hessian of the objective function and the
% constraints. Note that we still need to implement the gradient.
prob.ADObj = -1;
prob.ADCons = -1;

% Actually run the Tomlab solver and print the results
res = tomRun('knitro', ...   % Use the KNITRO nonlinear solver
             prob, ...
             2 ...   % Print some information (change to 0 to print less)
             );

disp('Computed solution:');
disp(res.x_k);

fprintf('Correct answer is: %g\n', 1 / sqrt(J) );

ofunc.m

function f = ofunc(theta, Prob)
% Evaluate the objective function at theta
% Negate the function, because we want to maximize, but TOMLAB minimizes
% by default.
  f = -sum( log(theta) );

ograd.m

function g = ograd(theta, Prob)
% Evaluate the gradient of the objective
  g = -1 ./ theta;

consfunc.m

function c = consfunc(theta, Prob)
% Evalute the constraints at the given theta
  c = sum(theta .^ 2);

consjac.m

function jc = consjac(theta, Prob)
% Evaluate the Jacobian of the constraints.
% The resulting matrix will have one row for each constraint
% and one column for each independent variable.
  jc = 2 * theta';