nlobj.m#

function nlobj()
% Copyright 2026, Gurobi Optimization, LLC
%
% This example formulates and solves the following simple nonlinear model
% using the nonlinear objective API:
%
%  minimize
%      sin(x) * x + x^2 * y
%  subject to
%      x + y >= 1
%      -1 <= x <= 2
%       0 <= y <= 2
%
% The nonlinear objective is set through the model.nlobj field, which holds
% the expression tree of the objective function.

model.varnames = {'x', 'y'};

% Bounds: -1 <= x <= 2, 0 <= y <= 2
model.lb = [-1; 0];
model.ub = [ 2; 2];

% Add constraint: x + y >= 1
model.A     = sparse([1 1]);
model.rhs   = 1;
model.sense = '>';

% Set nonlinear objective: sin(x) * x + x^2 * y
%
% The objective is given as an expression tree with 10 nodes. Every node has
% an opcode, a data value, and the index of its parent node. Nodes are
% 1-based, and the root node is marked by a parent of 0. The data value of a
% VARIABLE node is the 1-based index of that variable, the data value of a
% CONSTANT node is the constant itself, and all other nodes use -1.
%
%   node  1: PLUS        (root)
%   node  2: MULTIPLY    (child of 1)  ->  sin(x) * x
%   node  3: SIN         (child of 2)
%   node  4: VARIABLE x  (child of 3)
%   node  5: VARIABLE x  (child of 2)
%   node  6: MULTIPLY    (child of 1)  ->  x^2 * y
%   node  7: POW         (child of 6)
%   node  8: VARIABLE x  (child of 7)
%   node  9: CONSTANT 2  (child of 7)
%   node 10: VARIABLE y  (child of 6)
model.nlobj.opcode = [ ...
    GRB.OPCODE_PLUS, ...      %  1: root
    GRB.OPCODE_MULTIPLY, ...  %  2: sin(x) * x
    GRB.OPCODE_SIN, ...       %  3: sin(...)
    GRB.OPCODE_VARIABLE, ...  %  4: x
    GRB.OPCODE_VARIABLE, ...  %  5: x
    GRB.OPCODE_MULTIPLY, ...  %  6: x^2 * y
    GRB.OPCODE_POW, ...       %  7: x^2
    GRB.OPCODE_VARIABLE, ...  %  8: x
    GRB.OPCODE_CONSTANT, ...  %  9: 2
    GRB.OPCODE_VARIABLE, ...  % 10: y
];
model.nlobj.data   = [-1, -1, -1, 1, 1, -1, -1, 1, 2, 2];
model.nlobj.parent = [ 0,  1,  2, 3, 2,  1,  6, 7, 7, 6];

% Optimize
params.logfile = 'nlobj.log';
result = gurobi(model, params);

if strcmp(result.status, 'OPTIMAL')
    for j = 1:2
        fprintf('%s %e\n', model.varnames{j}, result.x(j));
    end
    fprintf('Obj: %e\n', result.objval);
else
    fprintf('Optimization did not produce an optimal solution\n');
end
end