The Black-Box Optimization Solver

Introductory Examples

The following introductory examples illustrate how to get started using the black-box solver.

A Bound-Constrained Problem

Consider the simple example of minimizing the Branin function,

StartLayout 1st Row 1st Column f left-parenthesis x right-parenthesis 2nd Column equals 3rd Column left-parenthesis x 2 minus StartFraction 5.1 Over 4 pi squared EndFraction x 1 squared plus StartFraction 5 Over pi EndFraction x 1 minus 6 right-parenthesis squared plus 10 left-parenthesis 1 minus StartFraction 1 Over 8 pi EndFraction right-parenthesis cosine left-parenthesis x 1 right-parenthesis plus 10 EndLayout

subject to negative 5 less-than-or-equal-to x 1 less-than-or-equal-to 10 and 0 less-than-or-equal-to x 2 less-than-or-equal-to 15 (Jones, Perttunen, and Stuckman 1993). The minimum function value is f left-parenthesis x Superscript asterisk Baseline right-parenthesis equals 0.397887 at x Superscript asterisk Baseline equals left-parenthesis negative pi comma 12.275 right-parenthesis comma left-parenthesis pi comma 2.275 right-parenthesis comma left-parenthesis 9.42478 comma 2.475 right-parenthesis period You can use the following statements to solve this bound-constrained problem:

proc optmodel;
   var x {1..2};
   x[1].lb = -5;
   x[1].ub = 10;
   x[2].lb = 0;
   x[2].ub = 15;
   num pi = constant('PI');
   min f = (x[2]-(5.1/(4*pi^2))*x[1]^2+5*x[1]/pi-6)^2
           + 10*(1-1/(8*pi))*cos(x[1]) + 10;
   solve with blackbox;
   print x;
quit;

The VAR declaration in the PROC OPTMODEL statement declares an array of two decision variables, x[1] and x[2]. Also, lower and upper bounds are set for the variables. The MIN declaration defines the BRANIN function as the objective function to be minimized.

Figure 1 shows the ODS tables that are produced by default.

Figure 1: Bound-Constrained Problem: Output

The OPTMODEL Procedure

Problem Summary
Objective SenseMinimization
Objective Functionf
Objective TypeNonlinear
  
Number of Variables2
Bounded Above0
Bounded Below0
Bounded Below and Above2
Free0
Fixed0
  
Number of Constraints0
  
Constraint Coefficients0

Solution Summary
SolverBlack-Box
Objective Functionf
Solution StatusFunction Convergence
Objective Value0.3978873578
  
Infeasibility0
Random Seed Used1
  
Evaluations1541
Cached Evaluations48
Iterations28
Presolve Time0.00
Solution Time0.05

[1]x
13.1416
22.2750


Adding a Linear Constraint

You can use a CONSTRAINT declaration to specify general equality or inequality constraints. For example, suppose that in addition to the bound constraints on the decision variables, you need to guarantee that the sum x 1 plus x 2 is less than or equal to 0.6. To enforce this, you can add a CON declaration to the PROC OPTMODEL statements, as follows:

title3 'Linear Constraint on the Decision Variables';
/* Linear Constraint on the Decision Variables */
proc optmodel;
   var x {1..2};
   x[1].lb = -5;
   x[1].ub = 10;
   x[2].lb = 0;
   x[2].ub = 15;
   num pi = constant('PI');
   min f = (x[2]-(5.1/(4*pi^2))*x[1]^2+5*x[1]/pi-6)^2
           + 10*(1-1/(8*pi))*cos(x[1]) + 10;
   con a1: x[1] + x[2] <= 0.6;
   solve with blackbox;
quit;

Here the symbol a1 denotes the name of the given linear constraint.

Nonlinear Constraints on the Decision Variables

You can specify general nonlinear equality or inequality constraints by using the same CON declaration as in the preceding code to add the linear constraint a1. Consider the previous problem with the following additional constraint:

x 1 squared minus 2 x 2 greater-than-or-equal-to 14

You can specify this constraint by adding a new CON declaration, as in the following statements:

title3 'Nonlinear Constraints on the Decision Variables';
/* Nonlinear Constraints on the Decision Variables */
proc optmodel;
   var x {1..2};
   x[1].lb = -5;
   x[1].ub = 10;
   x[2].lb = 0;
   x[2].ub = 15;
   num pi = constant('PI');
   min f = (x[2]-(5.1/(4*pi^2))*x[1]^2+5*x[1]/pi-6)^2
           + 10*(1-1/(8*pi))*cos(x[1]) + 10;
   con a1: x[1] + x[2] <= 0.6;
   con c1: x[1]^2 - 2*x[2] >= 14;
   solve with blackbox;
quit;

Here the symbol c1 has been added to denote the name of the given nonlinear constraint.

A Simple Maximum Likelihood Example

The following is a very simple example of a maximum likelihood estimation problem that uses the log-likelihood function:

l left-parenthesis mu comma sigma right-parenthesis equals minus log left-parenthesis sigma right-parenthesis minus one-half left-parenthesis StartFraction x minus mu Over sigma EndFraction right-parenthesis squared

The maximum likelihood estimates of the parameters mu and sigma form the solution to

max Underscript mu comma sigma Endscripts sigma-summation Underscript i Endscripts l Subscript i Baseline left-parenthesis mu comma sigma right-parenthesis

where sigma greater-than 0 and

l Subscript i Baseline left-parenthesis mu comma sigma right-parenthesis equals minus log left-parenthesis sigma right-parenthesis minus one-half left-parenthesis StartFraction x Subscript i Baseline minus mu Over sigma EndFraction right-parenthesis squared

In addition to specifying objective and constraint functions directly with PROC OPTMODEL syntax as shown in the first example, you can also specify these functions by using the FCMP procedure. In PROC FCMP, you specify the objective and constraint functions by using SAS statements that are similar to syntax in the SAS DATA step; these functions are then compiled into function libraries for subsequent use. The SAS CMPLIB= system option specifies where to look for previously compiled functions and subroutines. All procedures (including PROC FCMP) that support the use of FCMP functions and subroutines use this system option. After you specify your objective and constraint functions in a library, PROC OPTMODEL requires the names and context of the functions within this library that are relevant to the current optimization problem. You can provide this information to PROC OPTMODEL by using the same function names that you used in the PROC FCMP statements.

The following sets of statements use PROC FCMP functions and demonstrate two ways to formulate this example problem. In the first example, the FCMP function is "stand-alone" because all the necessary data are defined within the function itself. Notice how the values of left-parenthesis 1 comma 3 comma 4 comma 5 comma 7 right-parenthesis are assigned directly to X within the FCMP function.

title3 'Maximum Likelihood Example';
/* Maximum Likelihood Example */
proc fcmp outlib=work.myfuncs.mypkg;
   function loglkh1(mu, sigma);
      array x[5] / nosym (1 3 4 5 7);
      s=0;
      do j=1 to 5;
         s = s - log(sigma) - 0.5*((x[j]-mu)/sigma)**2;
      end;
      return (s);
   endsub;
run;

options cmplib = work.myfuncs;
proc optmodel;
   var mu, sigma >= 0;
   max f = loglkh1(mu, sigma);
   solve with blackbox;
quit;

The second example shows how you can use an external data set to store the necessary observations and run PROC OPTMODEL to feed each observation to an FCMP function that processes a single line of data. In this case, the objective definition in PROC OPTMODEL is the sum of the individual observation results. This mode is particularly useful when the data set is large and therefore cumbersome to enter directly into a function definition. The following statements demonstrate how to store the necessary observations in an external data set for use with PROC FCMP:

data logdata;
   input x @@;
   datalines;
1 3 4 5 7
;

proc fcmp outlib=work.myfuncs.mypkg;
   function loglkh2(mu, sigma, x);
      return (-log(sigma) -0.5*((x-mu)/sigma)**2);
   endsub;
run;

options cmplib = work.myfuncs;
proc optmodel;
   var mu, sigma >= 0;
   set OBS;
   num x {OBS};
   read data logdata into OBS=[_N_] x;
   max f = sum {j in OBS} loglkh2(mu, sigma, x[j]);
   solve with blackbox;
quit;

In this case, for each line of data in the data set LogData, the FCMP function LOGLKH2 is called.

Another variation of this same problem involves bypassing the use of PROC FCMP altogether and defining your objective function directly in PROC OPTMODEL as a function of the LogData data read into X:

proc optmodel;
   var mu, sigma >= 0;
   set OBS;
   num x {OBS};
   read data logdata into OBS=[_N_] x;
   max f = sum {j in OBS} (-log(sigma) - 0.5*((x[j]-mu)/sigma)**2);
   solve with blackbox;
quit;
Last updated: September 09, 2026