Matrix 在基本sas中计算矩阵积(不使用IML)
为了计算两个矩阵的乘积,我使用以下方法:Matrix 在基本sas中计算矩阵积(不使用IML),matrix,sas,Matrix,Sas,为了计算两个矩阵的乘积,我使用以下方法: 首先,我将矩阵放在长格式中(列、行、值) 我使用procsql计算两个矩阵的乘积 我使用proc转置将前一步的结果转换为宽格式 我的问题是有更简单的方法吗?或者至少我如何简化我的代码 这是我的代码: /* macro to put a matrix in the long format*/ %macro reshape(in_A = , ou_A= ); data &ou_A.; set &in_A.; array
/* macro to put a matrix in the long format*/
%macro reshape(in_A = , ou_A= );
data &ou_A.;
set &in_A.;
array arr_A{*} _numeric_;
row = _n_;
do col = 1 to dim(arr_A);
value = arr_A{col};
output;
end;
keep row col value;
run;
%mend;
%macro prod_mat( in_A = , in_B= ,ou_AB =);
/* put the matrix in the long format */
%reshape(in_A=&in_A.,ou_A=lA);
%reshape(in_A=&in_B.,ou_A=lB);
/* compute product */
PROC SQL ;
CREATE TABLE PAB AS
SELECT lA.row, lB.col, SUM(lA.value * lB.value) as value
FROM lA JOIN lB ON lA.col = lB.row
GROUP BY lA.row, lB.col;
QUIT;
/* reshape the output to the wide format */
proc transpose data=PAB out=&ou_AB.(DROP=_name_) prefix=x;
by row ;
id col;
var value;
run;
%mend;
data A ;
input x1 x2 x3;
datalines ;
1 2 3
3 4 4
5 6 9
;
data B ;
input x1 x2;
datalines ;
1 2
3 4
4 5
;
%prod_mat(in_A =A,in_B=B,ou_AB=AB)
这是我的变体。并不是代码本身比您的短,而是对于大型矩阵,它的工作速度更快,因为它避免了使用SQL join和所有元素的笛卡尔积。 其主要思想是将A的行与转置B的行完全连接(笛卡尔积),然后乘以相应的列。例如,对于3x3和3x2矩阵,我们需要: 1) 在合并数据集column1*column4+column2*column5+column3*column6的每一行中相乘求和 2) 在第二排重复这个步骤 3) 在一行中输出这两个值
%macro prod_mat_merge(in_A =,in_B=,ou_AB=);
/*determine number of rows and columns in the 2nd matrix*/
%let B_id=%sysfunc(open(&in_B));
%let B_rows=%sysfunc(attrn(&B_id,nobs));
%let B_cols=%sysfunc(attrn(&B_id,nvars));
%let rc=%sysfunc(close(&B_id));
/*transpose the 2nd matrix*/
proc transpose data=&in_B out=t&in_B(drop=_:);run;
/*making Cartesian product of the 1st and transposed 2nd matrices*/
data &ou_AB;
do until(eofA);
set &in_A end=eofA;
do i=1 to n;
set t&in_B nobs=n point=i;
output;
end;
end;
run;
/*multiplication*/
data &ou_AB;
/*new columns for products, equal to number of columns in the 2nd matrix*/
array p[&B_cols];
do j=1 to &B_cols;
p[j]=0;
set &ou_AB;
array col _ALL_;
/*multiply corresponding pairs of columns*/
do i=&B_cols+2 to &B_cols+1+&B_rows;
p[j]+col[i]*col[i+&B_rows];
end;
end;
output;
keep p:;
run;
%mend prod_mat_merge;
我已经测试了两种方法,分别乘以两个随机矩阵100x100。使用整形和SQL连接的方法需要约1.5秒,而使用合并的方法需要约0.2秒。谢谢!看起来很有希望!我是一个SAS新手(有时),我需要一些时间来消化这一点!您使用了许多内置函数%sysfunc、eofA、attrn等等,。。!再次感谢!