BookmarkSubscribeRSS Feed
PraveenRavichandran
Calcite | Level 5

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

7 REPLIES 7
Cynthia_sas
SAS Super FREQ

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

PraveenRavichandran
Calcite | Level 5

Thank you Cynthia . I am moving the discussion to the appropriate forum.

1zmm
Quartz | Level 8

The SAS version 9.2 documentation for PROC FCMP describes several matrix CALL routines including CALL TRANSPOSE.

Rick_SAS
SAS Super FREQ

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.

Vince28_Statcan
Quartz | Level 8

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.

JimLoughlin
Quartz | Level 8

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

Vince28_Statcan
Quartz | Level 8

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.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

Multiple Linear Regression in SAS

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.

From The DO Loop
Want more? Visit our blog for more articles like these.
Discussion stats
  • 7 replies
  • 1594 views
  • 1 like
  • 6 in conversation