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
- /
- General Programming
- /
- Proc Optmodel inside Macro calling FCMP function?

- 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
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

08-08-2013 04:50 PM

Question/ Help with symbolic interpretation of Proc Optmodel optimization variable not being a number when being passed to FCMP function from within a Macro.

I have a data set that I want to loop through (10+ groups) and optimize a solution by using the min f = myfunc(x1, x2).

My dataset comprises of three variables, character, number, number (grouping, var1 and var2).

Example Code:

%Macro mymacro (dataset); /* Macro set up to loop over the group variable and solve using custom function */

Proc SQL NoPrint; /* defining the distinct group to loop over */

Select Distinct Group

into :Grouping Sperated by ","

From &Dataset;

Quit;

%let i = 1;

%Do %While (%Scan(%bquote(&Grouping), &i, %Str(,)) ne);

%let Group = "%Scan(%bquote(&Grouping), &i, %Str(,))";

Proc SQL; /* subsetting the original dataset down to the various groups, only need to pass the var1 and var2 to the function */

Create Table work.subset AS

Select var1,

var2

From &Dataset

Where grouping = &Grouping;

Quit;

Proc SQL Noprint;

Select count(var1) into :arraySize

From work..subset;

Quit;

Proc fcmp outlib=work.myfuncs.test; /* setup myfunction (this is not the actual function but used to show what I am trying to do) */

function test(x1, x2);

array var1[&arraySize.] /nosymbols;

array var2[&arraySize.] /nosymbols;

rc = read_array(work.subset, var1, 'var1');

rc = read_array(work.subset, var2, 'var2');

do i = 1 to &arraySize;

calc = calc + var1**2 + var2 *3;*

end;

return (calc);

endsub;

run;

quit;

options cmplib = work.myfuncs;

proc optmodel;

var x1 >= 0.5 <= 8 init 1,

x2 >= 1 <= 100 init 50;

min f = %sysfunc(test(x1, x2));

Solve with NLPC;

print f x1 x2;

quit;

%let i = %eval(&i+1);

%end;

%mend mymacro;

run;

%mymacro(work.mydata);

When I run the example of this code the macro will loop through the different groups of data, the function is created and compiled and the proc optmodel calls the function. The error that I get is "argument to function test referenced by %sysfunc or %Qsysfunc macro function is not a number". I do not know how to resolve the symbolic representation of the optimization variable to a number and pass it to the function.

If I hard code the inputs to the function (min f = %sysfunc(test(1, 5)) everything works fine so I know it is not the macro, function or the optmodel structure but how to get the optimization variable to be represented as a number before passing to the function.

Is there a way to represent the optimization variable as a number and not a symbolic local variable within the optmodel structure?

Any help would be great...

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

Posted in reply to sporerma

09-08-2015 12:06 PM

Questions about PROC OPTMODEL in SAS/OR are better suited for the Mathematical Optimization and Operations Research Community. If you still need help, please post there.

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

Posted in reply to sporerma

09-08-2015 04:03 PM

I think you are seeing a result from using a macro function where not needed. Please run these two pieces of code and see if you get similar behavior from them.

```
data _null_;
x=3; y=5;
j = %sysfunc(min(x,y));
put j=;
run;
data _null_;
x=3; y=5;
j = %sysfunc(min(3,5));
put j=;
run;
```

The specific message looks like you may be using a call to %SYSFUNC when inappropriate. %SYSFUNC being a macro function is not able to see the data step variables x and y in my example.