The OPTLSO Procedure

Example 3.9 Discontinuous Function with a Lookup Table

This example illustrates the ability of PROC OPTLSO to optimize a discontinuous function. The example generates a data set of discrete values that approximate a given smooth nonlinear function. The function being optimized is simply using that data set as a lookup table to find the appropriate discretized value.

%let N = 100;
%let L = 0;
%let U = 10;

options cmplib = sasuser.myfuncs;
proc fcmp outlib=sasuser.myfuncs.mypkg;
   function SmoothFunc(x);
      y = x*sin(x) + x*x*cos(x);
      return (y);
   endsub;

   function DiscretizedFunc(x);
      array lookup[&N, 2] / nosymbols;
      rc = read_array('f_discrete', lookup);
      do i = 1 to %eval(&N-1);
         if x >= lookup[i,1] and x < lookup[i+1,1] then
         do;
            /* lookup value at nearest smaller discretized point */
            y = lookup[i,2];
            i = %eval(&N-1);
         end;
      end;
      return (y);
   endsub;
run;

The previous statements define PROC FCMP functions for both the smooth and discretized versions of the objective function. The smooth version is used as follows to generate the discrete points in the lookup table data set f_discrete for x values at 100 ($N$) points between 0 ($L$) and 10 ($U$). The values in the following data set created are used in the discretized version of the function that will be used in PROC OPTLSO for optimization. That discretized version of the function performs a simple lookup of the point data that are contained in the f_discrete data set. For a specified x value, the function finds the two discrete values in the data set that are closest to x. Then the smaller of the two nearest points is returned as the function value.

data f_discrete;
   a=&L; b=&U; n=&N;
   drop i a b n;
   do i = 1 to n;
      x = a + (i/n)*(b-a);
      y = SmoothFunc(x);
      output;
   end;
run;

data vardata;
   input _id_ $ _lb_ _ub_;
   datalines;
x   0   10
;

/* Use the discretized function as the objective */
data objdata;
   length _function_ $16;
   input _id_ $ _function_ $ _sense_ $;
   datalines;
f    DiscretizedFunc    min
;

options cmplib = sasuser.myfuncs;
proc optlso
   primaluut = finalsol
   variables = vardata
   objective = objdata;
   readarray f_discrete;
run;

proc print data=finalsol;
run;

Output 3.9.1 shows the ODS tables that are produced.

Output 3.9.1: Discontinuous Function: ODS Tables

The OPTLSO Procedure

Performance Information
Execution Mode Single-Machine
Number of Threads 4

Data Access Information
Data Engine Role Path
WORK.F_DISCRETE V9 Input On Client

Problem Summary
Problem Type NLP
   
Objective Definition Set OBJDATA
Variables VARDATA
   
Number of Variables 1
Integer Variables 0
Continuous Variables 1
   
Number of Constraints 0
Linear Constraints 0
Nonlinear Constraints 0
   
Objective Definition Source OBJDATA
Objective Sense Minimize

Solution Summary
Solution Status Function convergence
Objective -93.18498962
Infeasibility 0
Iterations 12
Evaluations 306
Cached Evaluations 57
Global Searches 1
Population Size 40
Seed 1

Obs _sol_ _id_ _value_
1 0 _obj_ -93.1850
2 0 _inf_ 0.0000
3 0 x 9.7087
4 0 f -93.1850



The following code optimizes the smooth version of the same function to demonstrate that virtually the same result is achieved in both cases:

%let N = 100;
%let L = 0;
%let U = 10;

options cmplib = sasuser.myfuncs;
proc fcmp outlib=sasuser.myfuncs.mypkg;
   function SmoothFunc(x);
      y = x*sin(x) + x*x*cos(x);
      return (y);
   endsub;
run;

data vardata;
   input _id_ $ _lb_ _ub_;
   datalines;
x   0   10
;

/* Use the smooth function as the objective */
data objdata;
   length _function_ $16;
   input _id_ $ _function_ $ _sense_ $;
   datalines;
f    SmoothFunc    min
;

options cmplib = sasuser.myfuncs;
proc optlso
   primaluut = finalsol
   variables = vardata
   objective = objdata;
run;

proc print data=finalsol;
run;

Output 3.9.2 shows the ODS tables that are produced.

Output 3.9.2: Smooth Function: ODS Tables

The OPTLSO Procedure

Performance Information
Execution Mode Single-Machine
Number of Threads 4

Problem Summary
Problem Type NLP
   
Objective Definition Set OBJDATA
Variables VARDATA
   
Number of Variables 1
Integer Variables 0
Continuous Variables 1
   
Number of Constraints 0
Linear Constraints 0
Nonlinear Constraints 0
   
Objective Definition Source OBJDATA
Objective Sense Minimize

Solution Summary
Solution Status Function convergence
Objective -93.22152602
Infeasibility 0
Iterations 19
Evaluations 475
Cached Evaluations 80
Global Searches 1
Population Size 40
Seed 1

Obs _sol_ _id_ _value_
1 0 _obj_ -93.2215
2 0 _inf_ 0.0000
3 0 x 9.7269
4 0 f -93.2215