Help using Base SAS procedures

Passing a macro to an optimizer

Reply
Contributor
Posts: 40

Passing a macro to an optimizer

I have both SAS/OR and SAS/IML and would like to perform nonlinear optimization on the values returned by a macro. This macro takes A and B as input and returns a result specific for the A and B values. There are also lower and upper bounds on both A and B, I have given a pseudo code that explains this:

MACRO returnResult(A, B)

{

  ...................................

  ...................................

  ...................................

  result = function (A, B)

}

The objective function to minimized is the "result" returned by the macro with upper and lower bounds on A and B. Can some please help how we can set it up as a nonlinear optimization problem using SAS/OR or SAS/IML?

Thank you.

Ravi

Contributor
Posts: 40

Re: Passing a macro to an optimizer

Specifically, if I have a macro that contains the following data steps that calculates the objective function, is it possible to use them with in either PROC IML or OPTMODEL (I am new to both). Any help would be appreciated. Thank you.

/*create some test data*/

DATA test (drop=i);

  input X Y Z;

  do i=1 to 2000;

    output;

  end;

cards;

1 10 0

2 20 0

3 30 0

4 40 0

5 50 0

;

data _null_;

if 0 then set test nobs=nobs;

CALL SYMPUT('NUMREC',nobs);      /*** put # of records into NUMREC macro var ***/

stop;                            /*** stop, got number of records ***/

run;

/* now read values of x and y into arrays, and then

   reread test and do calculations*/

data want (drop=_Smiley Happy;

    array _xval(&numrec); /* create two arrays with same number of

                                        elements as there are records in test

                                    */

    array _yval(&numrec);

    i=0;

    do until (eof1);      /* load the array with x and y values */

      set test end=eof1;

      i+1;

      _xval(i)=x;

      _yval(i)=y;

    end;

    _rec=-1;

    do until (eof2);      /* read in each record separately */

      set test end=eof2;

      _rec+1;

      z=0;

      do _i=1 to _rec;

        z+_xval(_i)*_yval(&numrec-_rec+_i);

      end;

      output;

    end;

run;

The above data steps are discussed in : https://communities.sas.com/message/109827#109827

Ravi

Respected Advisor
Posts: 4,654

Re: Passing a macro to an optimizer

I don't think you can pass a macro function to a SAS optimizer. Proc NLP however can accomodate most datastep statements. It can also call your own function defined with proc FCMP. If your dataset was smaller (1k instead of 10k observations, say), I would be almost certain it could work, because you could polulate constant arrays inside NLP or FCMP with macro variables. But 10k floating point numbers cannot be listed within the size limit of a macro string (64k characters).

PG

PG
Contributor
Posts: 40

Re: Passing a macro to an optimizer


Hi PGStats,

Thanks a lot for your reply.

I am trying to use the quasi Newton optimization approach in PROC IML and trying to use submit/endsubmit to define the objective function. However, I am having difficulty passing the values generated within submit/endsubmit outside of it.I have give an example code below:

In this code, SUMM calculated using PROC SQL is added to the objective function (this just for a demo only). This code throws an error "Apparent Symbolic Reference SUMM not resolved".

Can someone help me with how to get the value of SUMM work outside submit/endsubmit?? Also, this procedure seems exteremely slow (since my calculation of objective functin contains several data steps and a few do loops). Is there an alternative way to perform similar optimization more efficiently??

proc iml;

  start F_ROSEN(x);

   submit;

    data test;

     input x;

     datalines;

     1.2

     0.3

     10

      7

     2.9

    ;

    run;

   PROC SQL NOPRINT;

      SELECT SUM(x) into Smiley FrustratedUMM

      FROM test;

   QUIT;

endsubmit;

      y1 = 10 * (x[2] - x[1] * x[1]);

      y2 =  1 - x[1];

      f  = 0.5 * (y1 * y1 + y2 * y2)+&SUMM;

      return(f);

   finish F_ROSEN;

   x = {-1.2 1};

   optn = {0 2 . 2};

   call nlpqn(rc,xr,"F_ROSEN",x,optn);

quit;

Thank you.

Ravi

Contributor
Posts: 40

Re: Passing a macro to an optimizer

I think I understand what the issue is now. SUMM is getting treated as a third decision variable in the optimization since

f  = 0.5 * (y1 * y1 + y2 * y2)+&SUMM;

This works only if I declare x = {-1.2 1 1} i.e. provide the starting point for the third decision variable (SUMM) as well.

However, in my actual problem, I will only define f = &SUMM since SUMM is the result of the objective function (like squared errors) for a specific value of x1 and x2. f will not contain any references to x1 or x2.

Doing this throws an error after the line x = {-1.2 1} that "Undeclared array referenced: x"

Is it possible to call the optimizing function with f defined in this way???

Any help on this would be appreciated.

Thank you.

Ravi

Ask a Question
Discussion stats
  • 4 replies
  • 248 views
  • 0 likes
  • 2 in conversation