I am new to SAS. I am trying to write a simple function using proc fcmp to return the scalar product of two matrices
proc fcmp;
function ReturnTheta(a{*},b{*});
ScalarProductOfAandB=a`*b;
return ScalarProductOfAandB;
endsub;
I am unable to perform transpose of matrix 'a' because ` is not a recognized operator. I realize i need to be inside proc iml or use built in matrix functions to do matrix operation, but is there a way to create a simple function which accept matrix arguments , perform some matrix operation and return result ?
Is it possible to open the built in programs and view its source code? If so , where do i find them?
Thanks,
Praveen
Hi:
IML and matrix questions are probably better posted in the IML forum:
https://communities.sas.com/community/support-communities/sas_iml_and_sas_iml_studio
But, I am not sure whether a PROC FCMP function can be used in IML. That would probably be either a search in the FCMP doc or a question for Tech Support (or the IML forum).
cynthia
Thank you Cynthia . I am moving the discussion to the appropriate forum.
The SAS version 9.2 documentation for PROC FCMP describes several matrix CALL routines including CALL TRANSPOSE.
PROC IML supports "natural" syntax for linear algebraic operations.
PROC FCMP and other SAS procedures support a small number of function calls for simple matrix computations.
The call routines built for proc fcmp are extremely constraining because array size must be predefined AND you cannot use variables to set array sizes unless using macro variables. At compilation, values in the brackets for array name{ } must be numeric constants. Here is a way around
proc fcmp outlib=sasuser.funcs.temp;
subroutine returntheta(a[*,*],b[*,*], transa[*,*], result[1,1]);
outargs transa, result;
call transpose(a, transa);
call mult(transa, b, result);
endsub;
quit;
options cmplib=sasuser.funcs;
data _null_;
array a{6,1} _temporary_ (1,2,3,4,5,6);
array b{6,1} _temporary_ (1,2,3,4,5,6);
array transa{1,6} _temporary_;
array test{1,1} _temporary_;
call returntheta(a,b,transa, test);
put test[1,1]=;
run;
I'm no expert but from what I picked up on reviewing programs I made 2-3 months ago,
The matrix call routine mult requires an array output hence test{1,1} instead of a simple numeric variable. You could make it a numeric variable but since you need to pass array transa and modify it inside, it requires outargs statement and thus a call routine regardless. Still, you could define the 1*1 array directly inside the subroutine and use an actual numeric variable output if you don't want to have to reference test[1,1] in your data step.
proc iml will give you a much prettier result and far more flexibility if you ever need any somewhat more complex matrix manipulation and supports matrix dimension input as variables and not only numeric constants.
Because of the limitation on array definition, even if you wanted to move towards using macro variables and dim1 & dim2 functions, your subroutine would need to be re-compiled each time the array size changes so it's not really a good option.
Hope this helps.
Vincent
*Edited the code to reflect the message below, fixing the 2 errors.
Vincent-
Got an error running your code. Here's the log
1
2 proc fcmp outlib=sasuser.funcs.temp;
3 subroutine returntheta(a[*,*],b[*,*], transa[*,*], result[1,1]);
4 outargs transa, result;
5 call transpose(a, transa);
6 call mult(transa, b, result);
7 endsub;
8 quit;
NOTE: Function returntheta saved to sasuser.funcs.temp.
NOTE: PROCEDURE FCMP used (Total process time):
real time 3.51 seconds
cpu time 0.70 seconds
9
10 options cmplib=sasuser.funcs;
11 data _null_;
12 array a{6,1} _temporary_ (1,2,3,4,5,6);
13 array b{6,1} _temporary_ (1,2,3,4,5,6);
14 array transa{6,1} _temporary_;
15 array test{1,1} _temporary_;
16 call returntheta(a,b,transa, test);
ERROR: Illegal reference to the array test.
ERROR: Illegal variable type for I/O statement.
17 put test=;
18 run;
NOTE: The SAS System stopped processing this step because of errors.
NOTE: DATA statement used (Total process time):
real time 1.07 seconds
cpu time 0.26 seconds
Jim
Hi, I've made an error when I copied my code from SAS to the forum.
Change the dimensions of
array transa{6,1} _temporary_;
to
array transa{1,6} _temporary_;
and change
put test=;
to
put test[1,1]=;
*Edited second fix
*Edit - Updated my original post code segment. It should work as is now.
Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.
Register today!Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.
Find more tutorials on the SAS Users YouTube channel.