proc fcmp

Accepted Solution Solved
Reply
Contributor
Posts: 50
Accepted Solution

proc fcmp

Heey,

Is it possible using sas proc fcmp, to get a 2 dimensional output like this:

 

do i = 1 to n;
do j = 1 to p; mat[i,j]= i**j; end; end; return(mat); endsub;

It can be done using array statements in a simple data step, but proc fcmp allows portable fonctions.

 

Regards

 


Accepted Solutions
Solution
2 weeks ago
Super Contributor
Posts: 254

Re: proc fcmp

[ Edited ]

You need to pass a two-dimensional _temporary_ array, n by p which at the time of compilation, will be be filled with missing values by default. Pass the array, n and p to Proc FCMP SUBROUTINE with OUTARG option to return the filled array. But there are painless ways of using FCMP to dynamically allocate arrays and write out the filled array as a data set. Your requirement is not sufficient to provide such easy ways.

 

Here is one indirect way:

proc fcmp outlib = work.cmpds.lib;
   subroutine fillmat(mat[*,*], n, p);
   outargs mat;
   do i = 1 to n;   
      do j = 1 to p;
         mat[i,j]= i**j;
      end;
   end;
endsub;
quit;

options cmplib = work.cmpds;
%let n = 4;
%let p = 3; data _null_; array k[&n,&p] _temporary_; call fillmat(k,&n,&p); do i = 1 to &n; do j = 1 to &p; put k[i,j] =; end; end; run;

.

View solution in original post


All Replies
Super User
Posts: 6,942

Re: proc fcmp

User-defined functions can only return one value of type numeric or character. A return of a compound value (array or matrix) is not possible, AFAIK.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super User
Super User
Posts: 7,403

Re: proc fcmp

Personally I would avoid fcmp as its just obfuscation to the nth degree.  

These are compiled functions and so can have any number of paramters, but only one return type and array is not a type but a collection.  From what you posted there, what would be the benefit of hiding that code?  It seems to be a simple do loop and array statement, so just use plain base SAS code, or if you really have to, put it in a macro.

Contributor
Posts: 50

Re: proc fcmp

Yes. As i said previously, it can be easily done using a data step with array.

 

data want;
array x{5};
do j= 1 to 3;
do i= 1 to 5; x[i]= i**j; end; output; end; run;

 

But such i want to handle it with many kind of data and return an output data...

 

Regards

Super User
Super User
Posts: 7,403

Re: proc fcmp

[ Edited ]

If you want to have code that changes depenging on parameters and data then you use Macro Language.  This is a code generation facililty which generates code based on these factors.  

Compiled functions are there to do very specific small data manipulations, not to do large data manipulation tasks.

Not sure what you mean by "but proc fcmp allows portable fonctions"

SAS code is all text files, Macro is text files or compiled macro libraries just like fcmp.  For portability plain text files are ideal as they can be copied to any system and used in many ways.  FCMP and compiled macros hide the code and not as compatible across systems, protected ones even less so.

 

As you are creating general code, you would need to have more description, something like a functional design specifications which shows inputs/outputs etc.  From what you have posted code-wise, what do you want to be general, is it just the j/i variables if so:

%macro Do_Calc (multiplier=,elements=);
data want;
array x{&elements.};
do j= 1 to &multiplier.;
do i= 1 to &elements.;
x[i]= i**j;
end;
output;
end;
run;
%mend Do_Calc;

%Do_Calc (multiplier=3,elements=5);

 

Solution
2 weeks ago
Super Contributor
Posts: 254

Re: proc fcmp

[ Edited ]

You need to pass a two-dimensional _temporary_ array, n by p which at the time of compilation, will be be filled with missing values by default. Pass the array, n and p to Proc FCMP SUBROUTINE with OUTARG option to return the filled array. But there are painless ways of using FCMP to dynamically allocate arrays and write out the filled array as a data set. Your requirement is not sufficient to provide such easy ways.

 

Here is one indirect way:

proc fcmp outlib = work.cmpds.lib;
   subroutine fillmat(mat[*,*], n, p);
   outargs mat;
   do i = 1 to n;   
      do j = 1 to p;
         mat[i,j]= i**j;
      end;
   end;
endsub;
quit;

options cmplib = work.cmpds;
%let n = 4;
%let p = 3; data _null_; array k[&n,&p] _temporary_; call fillmat(k,&n,&p); do i = 1 to &n; do j = 1 to &p; put k[i,j] =; end; end; run;

.

Contributor
Posts: 50

Re: proc fcmp

Yes absolutly, i don't say enough... Thanks to everyone. Your ideas are brilliant

 

Best Regards

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 6 replies
  • 144 views
  • 3 likes
  • 4 in conversation