1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
%MACRO mat_product(libname1 = work
,libname2 = work
,in_test6 =
,in_test7 =
,out_data = );
PROC SQL NOPRINT;
SELECT nobs INTO :obs1 FROM sashelp.vtable
WHERE libname="%upcase(&libname1.)" AND
memname="%upcase(&in_test6.)";
SELECT nobs INTO :obs2 FROM sashelp.vtable
WHERE libname="%upcase(&libname2.)" AND
memname="%upcase(&in_test7.)";
SELECT count(distinct name) INTO :obscol1 FROM sashelp.vcolumn
WHERE libname="%upcase(&libname1.)" AND
memname="%upcase(&in_test6.)";
SELECT count(distinct name) INTO :obscol2 FROM sashelp.vcolumn
WHERE libname="%upcase(&libname2.)" AND
memname="%upcase(&in_test7.)";
QUIT;
%IF &obs2. = &obscol1. %THEN %DO;
PROC TRANSPOSE DATA=&libname2..&in_test7. OUT=_2(DROP=_name_);
RUN;
DATA _1;
SET &libname1..&in_test6.;
RUN;
%DO i = 1 %TO 2;
PROC SQL NOPRINT;
SELECT name INTO :mem&i. separated BY ' ' FROM sashelp.vcolumn
WHERE libname="WORK" AND memname="%upcase(_&i.)";
SELECT count(distinct name) INTO :cntmem&i. FROM sashelp.vcolumn
WHERE libname="WORK" AND memname="%upcase(_&i.)";
QUIT;
DATA _&i.;
SET _&i.;
ind=_n_;
%DO j = 1 %TO &&cntmem&i.;
IF %SCAN(&&mem&i.,&j.)=. THEN %SCAN(&&mem&i.,&j.)=0;
RENAME %SCAN(&&mem&i.,&j.) = col&i.&j.;
%END;
RUN;
%END;
%DO i = 1 %TO &obscol2.;
PROC SQL NOPRINT;
CREATE TABLE __&i. AS SELECT _1.ind,
0 %DO j = 1 %TO &obs1.;
+ (col1&j. * col2&j.)
%END; AS r&i.
FROM _1, (SELECT * FROM _2 WHERE ind=&i.) AS A;
QUIT;
%END;
PROC SQL NOPRINT;
CREATE TABLE &out_data. AS SELECT r1 %DO i = 2 %TO &obscol2.; ,r&i.
%END;
FROM __1(KEEP=ind r1) %DO i = 2 %TO &obscol2.;
LEFT JOIN __&i.(KEEP=ind r&i.) ON __1.ind = __&i..ind
%END;;
QUIT;
DATA &out_data.(DROP=i);
SET &out_data.;
ARRAY row{&obscol2.} r1 - r%CMPRES(&obscol2.);
DO i = 1 TO &obscol2.;
IF row{i} < 0.00000000001 THEN row{i} = 0;
END;
RUN;
PROC DATASETS LIBRARY=work MTYPE=DATA;
DELETE _1 _2 %DO i = 1 %TO &obscol2. ;
__&i.
%END;;
QUIT;
PROC PRINT DATA=&out_data. LABEL;
TITLE "The Product of matrix &in_test6. with &in_test7.";
RUN;
%END;
%ELSE %DO;
%PUT NOTE: The number of rows in the first matrix is not same as the
number of columns in the other matrix, please check the
dimensions and try again;
%END;
%MEND mat_product;
%mat_product(in_test6 = temp
,in_test7 = temp_
,out_data = outprd ); |
Partager