Date: Mon, 3 Jun 2002 03:00:46 -0700
Reply-To: Ivan Bos <ivanlooptstage@HOTMAIL.COM>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Ivan Bos <ivanlooptstage@HOTMAIL.COM>
Organization: http://groups.google.com/
Subject: Re: Matrix multiplication without PROC IML
Content-Type: text/plain; charset=ISO-8859-1
Dear Armin,
I tried to use your macro, but a multiplication of a 4*4000 vs a
4000*4 matrix gave some problems:
>>>>>>>
WARNING: Argument 1 to function ATTRN referenced by the %SYSFUNC or
%QSYSFUNC macro function is missing or out of range.
ERROR: File WORK.XTRANS.DATA does not exist.
>>>>>>>
Do you know how to handle that problem?
Regards,
Ivan Bos
Free University Amsterdam
The Netherlands
Armin.Gemperli@UNIBAS.CH (Armin Gemperli) wrote in message news:<3CF4A421.8332576E@unibas.ch>...
> Dear Ivan,
>
> I can see, you have the same Problem with your Boss as I have: It is
> cheaper for him to let you program tedious matrix computation solutions
> yourself, than buying IML. For the matrix-multiplication, I have added a
> macro, but for the inversion stuff I should have more information about
> the matrix to invert: Has it full rank/Generalized Inverse/Is it
> positive-definite/symmetric etc. Because to programm your own solution
> it helps a lot to use this ancillary information.
> Cheers
> Armin Gemperli
>
>
> %MACRO MATMUL(A, B, C, COLNAME=COL);
> /* ********************************************************* */
> /* Matrix multiplication A*B=C without using SAS/IML */
> /* ********************************************************* */
> /* */
> /* Parameters: */
> /* 1. First Matrix (A) */
> /* 2. Second Matrix (B), where the second dimension of A */
> /* and the first dimesnio of B must match (not checked)*/
> /* 3. Resulting Matrix (C) */
> /* 4. Colum Names of the resulting Matrix C. */
> /* Optional Argument, Default=COL */
> /* */
> /* ********************************************************* */
> OPTION NONOTES NOMPRINT;
> %LET DATA=%sysfunc(OPEN(&A));
> %LET DIMLEFT=%sysfunc(ATTRN(&DATA,NOBS));
> %LET DIMJOIN=%sysfunc(ATTRN(&DATA,NVARS));
> %LET RC=%sysfunc(CLOSE(&DATA));
> %LET DATA=%sysfunc(OPEN(&B));
> %LET DIMCHECK=%sysfunc(ATTRN(&DATA,NOBS));
> %LET DIMRIGHT=%sysfunc(ATTRN(&DATA,NVARS));
> %LET MAT2VAR1=%SYSFUNC(VARNAME(&DATA,1));
> %LET MAT2VARN=%SYSFUNC(VARNAME(&DATA,&DIMRIGHT));
> %LET RC=%sysfunc(CLOSE(&DATA));
> %IF &DIMJOIN NE &DIMCHECK %THEN %DO;
> %PUT ERROR: Dimensions do not match. Processing interrupted;
> %GOTO EXIT;
> %END;
> PROC TRANSPOSE DATA=&A OUT=&C PREFIX=_AVAR_;
> DATA &C (DROP=i j _AVAR_1-_AVAR_&DIMLEFT &MAT2VAR1--&MAT2VARN);
> SET &C(DROP=_NAME_);
> SET &B;
> ARRAY _AARRAY {&DIMLEFT} _AVAR_1-_AVAR_&DIMLEFT;
> ARRAY _BARRAY {&DIMRIGHT} &MAT2VAR1--&MAT2VARN;
> ARRAY _CVAR_ {%EVAL(&DIMLEFT * &DIMRIGHT)};
> RETAIN _CVAR_;
> IF _N_ EQ 1 THEN DO;
> DO i=1 TO &DIMLEFT;
> DO j=1 TO &DIMRIGHT;
> _CVAR_((i-1)*&DIMRIGHT+j)=_AARRAY(i)*_BARRAY(j);
> END;
> END;
> END;
> ELSE DO;
> DO i=1 TO &DIMLEFT;
> DO j=1 TO &DIMRIGHT;
>
> _CVAR_((i-1)*&DIMRIGHT+j)=_CVAR_((i-1)*&DIMRIGHT+j)+_AARRAY(i)*_BARRAY(j);
> END;
> END;
> END;
> IF _N_ EQ &DIMJOIN THEN OUTPUT;
> PROC TRANSPOSE DATA=&C OUT=&C PREFIX=_CVAR_;
> DATA &C (DROP=i _CVAR_1);
> SET &C(DROP=_NAME_);
> ARRAY &COLNAME {&DIMRIGHT};
> RETAIN &COLNAME i 1;
> &COLNAME(i)=_CVAR_1;
> IF MOD(_N_,&DIMRIGHT) EQ 0 THEN DO;
> OUTPUT;
> i=1;
> END;
> ELSE i+1;
> RUN;
> /* *************** */
> /* ** EXAMPLES ** */
> /* *************** */
> /*
> * _1_;
> DATA A;
> INPUT F G Z O Z65 R TTT;
> datalines;
> 1 2 0 4 66 11 8
> ;
> DATA B;
> INPUT R TTT;
> DATALINES;
> 6 6
> 0 1
> 1 0
> 8 345
> 9 5
> 0 88
> 111 9
> ;
> RUN;
> %MATMUL(A=A, B=B, C=C, COLNAME=V);
>
> * _2_;
> DATA A;
> INPUT A B C D ;
> datalines;
> 1 2 0 4
> 66 88 99 100
> 21 45 65 0
> 4 3 1 0.1
> ;
> DATA B;
> INPUT A B C;
> DATALINES;
> 0.1 0.1 0.11
> 99 0.9 0.0001
> 0.2 0 0.00001
> 100000 10.001 1.01
> ;
> RUN;
> %MATMUL(A,B,C);
> */
> %EXIT:
> OPTION NOTES;
> %MEND MATMUL;
|