Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Find a Community

- Home
- /
- SAS Programming
- /
- SAS Procedures
- /
- Passing a macro to an optimizer

Topic Options

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-06-2012 04:04 AM

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

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-06-2012 03:06 PM

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=_;

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

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-06-2012 10:21 PM

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

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-07-2012 12:23 PM

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 UMM

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

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-07-2012 04:44 PM

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