Optimization with Linear Equality Constraints#
This GAUSS optimization example demonstrates the use of COMT to perform optimization with linear equality constraints.
Key example features#
The user-defined objective function
fct
for computing the Woods Function.The first case uses
comtControl
linear equality members, c0.A and c0.B, to specify equality constraints.The second case uses a user-defined function
eqp
in combination with the c0.eqProc member of thecomtControl
structure to specify the equality constraints.The c0.bounds member of the
comtControl
stucture is used to set all parameter values between -10 and 10.
There are four linear equality constraints that are implemented in this example:
where \(x_1, x_2, \ldots, x_5\) are the parameters to be estimated.
Case One: Specifying equality constraints with control structure matrices#
In this case, two members of the comtControl
are used to specify equality constraints. These set up the constraints based on the relationship:
The c0.A matrix is used to specify the LHS of the equality constraints:
Each row represents one constraint. In other words, the matrix should have the same number of rows as there are constraints.
Each column reprents one parameter. In other words, the matrix should have the same number of columns as there are parameters.
The c0.B vector is used to specify the RHS of the equality constraints:
Each row represents one constraint. The matrix should have the same number of rows as there are constraints.
Always has one column.
new;
cls;
library comt;
// Nonlinear objective function
proc fct(x, ind);
struct modelResults mm;
if ind[1];
// Calculate objective function value
mm.function = (x[1] - x[2])^2 + (x[2] + x[3]- 2)^2 + (x[4] - 1)^2 + (x[5] - 1)^2;
endif;
// Return modelResults struct
retp(mm);
endp;
// Declare 'c0' to be a comtControl struct
// and fill with default settings
struct comtControl c0;
c0 = comtControlCreate();
/*
** Specify equality constraints
*/
// The c0.A matrix represents represents the LHS
// of the equality constraints.
// Each row represents one constraint.
// Each column represents a parameter.
// The matrix should have:
// - the same number of rows as constraints
// - the same number of columns as parameters
c0.A = {1 3 0 0 0,
0 0 1 1 -2,
0 1 0 0 -1};
c0.B = 0;
// Turn off trust radius
c0.trustRadius = error(0);
// Bound all parameters to be between -10 and +10
c0.bounds = { -10 10 };
// Use Newton descent method
c0.algorithm = 3;
// Starting parameter values
x0 = { 2, 2, 2, 2, 2 };
// Declare 'out' to be a comtResults
// struct to hold optimization results
struct comtResults out;
// Minimize objective function
out = comt(&fct, x0, c0);
// Print optimization results
call comtPrt(out);
There code prints results to the Command Window.
Results#
The first portion of the results provide details about convergence and performance.
Return code = 0
Function value = 4.09302
Convergence : normal convergence
These results indicate that the optimization converged normally, with a return code of 0. Any return Code other than 0 would indicate some issue with the convergence. The exact meaning of the return code can be found in the comt()
documentation.
The next section of the results reports the parameter estimates and the associated gradients.
Parameters Estimates Gradient
---------------------------------------------------------------------
x[1,1] -0.7675 -2.0465
x[2,1] 0.2558 -0.1861
x[3,1] 0.6279 -2.2326
x[4,1] -0.1162 -2.2325
x[5,1] 0.2558 -1.4884
The final section of the results reports the number of iterations and computation time.
Number of iterations 25
Minutes to convergence 0.00028
Case Two: Specifying equality constraints with user-defined equality function#
In this case, the same optimization is performed, using a procedure to define the equality constraints. Whenan equation is used to specify constraints, a pointer to the function must be provided using the c0.eqProc member of the comtControl
structure.
new;
cls;
library comt;
// Nonlinear objective function
proc fct(x, ind);
struct modelResults mm;
if ind[1];
// Calculate objective function value
mm.function = (x[1] - x[2])^2 + (x[2] + x[3] - 2)^2 + (x[4] - 1)^2 + (x[5] - 1)^2;
endif;
// Return modelResults struct
retp(mm);
endp;
// Procedure to compute equality constraints
// this must specify the constraint such that
// eqp(x) = 0
proc eqp(x);
local result;
// This will be returned and
// it should be a vector of zeros
// with the same number of rows as constraints
result = zeros(3, 1);
// Constraint one
result[1] = x[1] + 3*x[2];
// Constraint two
result[2] = x[3] + x[4] - 2 * x[5];
// Constraint three
result[3] = x[2] - x[5];
retp(result);
endp;
// Declare 'c0' to be a comtControl struct
// and fill with default settings
struct comtControl c0;
c0 = comtControlCreate();
// Turn off trust radius
c0.trustRadius = error(0);
// Assign pointer for equality procedure
c0.eqProc = &eqp;
// Bound all parameters to be between -10 and +10
c0.bounds = { -10 10 };
// Use Newton descent method
c0.algorithm = 3;
// Starting parameter values
x0 = { 2, 2, 2, 2, 2 };
// Declare 'out' to be a comtResults
// struct to hold optimization results
struct comtResults out;
// Minimize objective function
out = comt(&fct,x0,c0);
// Print optimization results
call comtPrt(out);
Results#
We can confirm that these results match those from the first case.
Return code = 0
Function value = 4.09302
Convergence : normal convergence
Parameters Estimates Gradient
---------------------------------------------------------------------
x[1,1] -0.7674 -2.0465
x[2,1] 0.2558 -0.1861
x[3,1] 0.6279 -2.2326
x[4,1] -0.1163 -2.2325
x[5,1] 0.2558 -1.4884
Number of iterations 63
Minutes to convergence 0.00050