Reputation: 24651
I have a matrix A
:
1 3 1
7 5 2
4 3 7
8 2 1
3 9 6
4 5 2
and a matrix B
:
2 9 1
4 3 8
9 7 3
4 4 2
6 5 7
2 9 2
I want to compute C
:
1*2+3*9+1*1
7*4+5*3+2*8
4*9+3*7+7*3
8*4+2*4+1*2
3*6+9*5+6*7
4*2+5*9+2*2
How can I express this purely using matrix operations? I realize I can do this using .
versions but I am interested in pure matrix operations. For example, when I have two vectors x
and y
, I vastly prefer x'*y
over sum(x.*y)
. Hence I am interested in how to do the above also using matrix operations.
Upvotes: 1
Views: 357
Reputation: 12737
You should use vector operations
C = sum( A .* B , 2 );
The .*
operator multiplies matrices value-by-value, while sum( <matrix> , 2 )
sums along the rows of a matrix inside the first parameter.
Upvotes: 4
Reputation: 70622
If you do not want to use vector operators, you can get the same result by performing a matrix multiplication with the transpose of the second multiplicand (otherwise you'll get a 3x3 result, in this case), and then extracting the diagonal.
Like so: C = diag(A * B')
I'm not quite sure how Octave optimizes this, but it appears to only be slightly slower than the element-wise approach. (at least, for this data set)
function test(func, n, a, b)
for i = 1:n
func(a, b);
endfor
endfunction
octave> tic; test(@(a, b) sum(a.*b, 2), 100000, A, B); toc
Elapsed time is 2.843 seconds.
octave> tic; test(@(a, b) diag(a*b'), 100000, A, B); toc
Elapsed time is 3.2 seconds.
CAUTION: A real life problem shows this to be far slower than the element-wise approach:
octave:100> size(yy)
ans =
5000 10
octave:101> size(expected)
ans =
5000 10
octave:102> tic; diag(yy * expected'); toc;
Elapsed time is 0.5447 seconds.
octave:103> tic; sum(yy .* expected, 2); toc;
Elapsed time is 0.0016899 seconds.
Upvotes: 4