2

Suppose I have 2 vectors and I want to do an outer product. I could use:

A=x*y';

Or I could use bsxfun like that:

bsxfun(@times,x,y')

But I want to batch outer products. I have 2 matrices, each holds p vectors:

n=1000;  p=6;
A=rand(n,p);
D=rand(n,p);

And I want to calculate all the outer products and sum the results like so:

AA=zeros(n,n);

for j=1:p
    AA = AA + A(:,j) * D(:,j).';
end

I want to do this more efficiently but I can't figure out how.

Adriaan
  • 17,741
  • 7
  • 42
  • 75
alonhzn
  • 150
  • 1
  • 7

2 Answers2

4

Just multiply the two matrices together:

n=1000;  p=6;
A=rand(n,p);
D=rand(n,p);

way1=zeros(n,n);

for j=1:p
    way1 = way1 + A(:,j) * D(:,j).';
end

way2 = A * D.';

any(way1(:) ~= way2(:))
Tokkot
  • 1,215
  • 7
  • 22
  • good solution, though I'd not use `j` as a [variable](http://stackoverflow.com/questions/14790740/using-i-and-j-as-variables-in-matlab). I'll do a `timeit` tonight to see which is faster. – Adriaan Sep 21 '15 at 11:27
3

You can use bsxfun after all:

C = bsxfun(@times,A,permute(D,[3 2 1]));
result = sum(C,2);

The first line computes all the outer products between A and D, the second sums your results together, as requested.

Tested as follows:

kk = 1e3;
times1 = zeros(kk,1);
n=1000;  p=6;
A=rand(n,p);
D=rand(n,p);
for ii = 1:kk
    tic
    C = bsxfun(@times,A,permute(D.',[3 1 2]));
    result = sum(C,2);
    times1(ii) = toc;
end
mean(times1)

bsxfun takes 0.0456s and direct multiplication takes 0.0075s, though I suspect my solution actually does everything 6 times, due to the permute, which is not in the direct multiplication. So per outer product bsxfun takes 0.0076s, which is almost equal.

Adriaan
  • 17,741
  • 7
  • 42
  • 75