外部产品的总和乘以MATLAB中的标量

Ale*_*tta 2 performance matlab product vectorization outer-join

我想在此后对产品的总和进行矢量化,以加快我的Matlab代码.可能吗?

for i=1:N
    A=A+hazard(i)*Z(i,:)'*Z(i,:);
end
Run Code Online (Sandbox Code Playgroud)

其中hazard是向量(N x 1)并且Z是矩阵(N xp).

谢谢!

Div*_*kar 5

你可以使用bsxfunmatrix-multiplication-

A =  bsxfun(@times,Z,hazard).'*Z + A
Run Code Online (Sandbox Code Playgroud)

  • @AlessandroBeretta您可以使用repmat:`repmat(hazard,1,p).*Z`,但是对于`bsxfun`有什么不情愿? (2认同)

Lui*_*ndo 5

仅使用矩阵乘法:

A = A + Z'*diag(hazard)*Z;
Run Code Online (Sandbox Code Playgroud)

但是请注意,这不仅仅需要操作Divakar的bsxfun做法,因为diag(hazard)是一个NX N主要由零点矩阵.

为了节省一些时间,您可以将内部矩阵定义为sparse使用spdiags,以便可以优化乘法:

A = A + full(Z'*spdiags(hazard, 0, zeros(N))*Z);
Run Code Online (Sandbox Code Playgroud)

标杆

时间码:

Z = rand(N,p);
hazard = rand(N,1);
timeit(@() Z'*diag(hazard)*Z)
timeit(@() full(Z'*spdiags(hazard, 0, zeros(N))*Z))
timeit(@() bsxfun(@times,Z,hazard)'*Z)
Run Code Online (Sandbox Code Playgroud)

N = 1000; p = 300;

ans =
    0.1423
ans =
    0.0441
ans =
    0.0325
Run Code Online (Sandbox Code Playgroud)

N = 2000; p = 1000;

ans =
    1.8889
ans =
    0.7110
ans =
    0.6600
Run Code Online (Sandbox Code Playgroud)

N = 1000; p = 2000;

ans =
    1.8159
ans =
    1.2471
ans =
    1.2264
Run Code Online (Sandbox Code Playgroud)

可以看出,bsxfun基于方法的方法始终更快.