Discontinuous Function With a Lookup Table (lsoe09)

/**********************************************************************/
/*                                                                    */
/*               S A S   S A M P L E   L I B R A R Y                  */
/*                                                                    */
/*    NAME: lsoe09                                                    */
/*   TITLE: Discontinuous Function With a Lookup Table (lsoe09)       */
/* PRODUCT: OR                                                        */
/*  SYSTEM: ALL                                                       */
/*    KEYS: OR                                                        */
/*   PROCS: OPTLSO, FCMP, PRINT                                       */
/*    DATA:                                                           */
/*                                                                    */
/* SUPPORT:                             UPDATE:                       */
/*     REF:                                                           */
/*    MISC: Example 9 from the OPTLSO chapter of the                  */
/*          Local Search Optimization book.                           */
/*                                                                    */
/**********************************************************************/

%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;

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
   primalout = finalsol
   variables = vardata
   objective = objdata;
   readarray f_discrete;
run;

proc print data=finalsol;
run;

%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
   primalout = finalsol
   variables = vardata
   objective = objdata;
run;

proc print data=finalsol;
run;