Alessandro Beretta
Alessandro Beretta

Reputation: 45

Sum of outer products multiplied by a scalar in MATLAB

I would like to vectorize the sum of products hereafter in order to speed up my Matlab code. Would it be possible?

for i=1:N
    A=A+hazard(i)*Z(i,:)'*Z(i,:);
end

where hazard is a vector (N x 1) and Z is a matrix (N x p).

Thanks!

Upvotes: 2

Views: 72

Answers (2)

Luis Mendo
Luis Mendo

Reputation: 112749

With matrix multiplication only:

A = A + Z'*diag(hazard)*Z;

Note, however, that this requires more operations than Divakar's bsxfun approach, because diag(hazard) is an NxN matrix consisting mostly of zeros.

To save some time, you could define the inner matrix as sparse using spdiags, so that multiplication can be optimized:

A = A + full(Z'*spdiags(hazard, 0, zeros(N))*Z);

Benchmarking

Timing code:

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)

With N = 1000; p = 300;

ans =
    0.1423
ans =
    0.0441
ans =
    0.0325

With N = 2000; p = 1000;

ans =
    1.8889
ans =
    0.7110
ans =
    0.6600

With N = 1000; p = 2000;

ans =
    1.8159
ans =
    1.2471
ans =
    1.2264

It is seen that the bsxfun-based approach is consistently faster.

Upvotes: 5

Divakar
Divakar

Reputation: 221664

You can use bsxfun and matrix-multiplication -

A =  bsxfun(@times,Z,hazard).'*Z + A

Upvotes: 5

Related Questions