Reputation: 45
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
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 N
xN
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);
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