# Help with Matrix block multiplication

52 views (last 30 days)
Eugenio Grabovic on 27 Jan 2019
Edited: Eugenio Grabovic on 28 Jan 2019
Hi, i need help with block matrix multiplication. I think a practical example should explain what i'm looking for.
Given:
A = rand(3,3); B = rand(9,3);
so basically i have [A] nxn block (generalizing) and [B] (k*n)xn block.
I would like to achieve as a result the equivalent of the following:
[A*B(1:3,:);A*B(4:6,:);A*B(7:9,:)];
possibly without any loops and arrayfun/cellfun.

Eugenio Grabovic on 27 Jan 2019
A = [1 1 0;1 1 0; 1 1 1];
B = [1,2,3;4,5,6;7,8,9;2,6,8;4,1,6;1,12,16;4,2,1;4,9,6;3,8,2;];
expected_result=[A*B(1:3,:);A*B(4:6,:);A*B(7:9,:)]
expected_result =
5 7 9
5 7 9
12 15 18
6 7 14
6 7 14
7 19 30
8 11 7
8 11 7
11 19 9
[m,n]=size(A);
[r,c]=size(B);
AA=A.*ones(n,n,n);
BB=permute(reshape(B',c,c,[]),[2 1 3]);
C=permute(AA.*BB,[1 3 2]);
Your_result = reshape(C,[],size(A,2),1)
Your_result =
1 2 0
4 5 0
7 8 9
2 6 0
4 1 0
1 12 16
4 2 0
4 9 0
3 8 2
@Stephan yes it's true, but that was an example, and it was achieved by manually feeding inputs to the resulting matrix. Usually in my alghorithm the B matrix's depth is unknown and thus i can't ( or at least don't know how) to concatenate the resulting matrix in an "automated" way. I already found how to do it with loops/arrayfun but was wondering if it was possible to achieve the result with just matrix manipulation.
Stephan on 27 Jan 2019
Is A always of size n x n ?
Is B always of size (k*n) x n with k=[1,2,3...] ?
Eugenio Grabovic on 27 Jan 2019
@Stephan yes the only thing that is unkown is the row dimension of B ( parameter k) but is always a multiple of n.

madhan ravi on 28 Jan 2019
Edited: madhan ravi on 28 Jan 2019
A = [1 1 0;1 1 0; 1 1 1];
B = [1,2,3;4,5,6;7,8,9;2,6,8;4,1,6;1,12,16;4,2,1;4,9,6;3,8,2];
expected_result=[A*B(1:3,:);A*B(4:6,:);A*B(7:9,:)];
%code starts here
[m,n]=size(A);
[r,c]=size(B);
BB=permute(reshape(B',c,c,[]),[2 1 3]);
[a,b,c]=size(BB);
BBB=reshape(BB,[a b*c]);
A_times_B_slices=A*BBB;
C=permute(reshape(A_times_B_slices,b,a,[]),[2 1 3]);
My_Result=reshape(C,c,[],1)';
isequal(My_Result,expected_result) % to check both the results are the same

Stephan on 28 Jan 2019
Nice! +1
Eugenio Grabovic on 28 Jan 2019
Thank you very much, your code actually helped me with other algorithms too.
If anyone is curious if it's worth avoiding a loop , here is my test result:
function perform_test
n=3;
k=1000;
A = rand(n,n);
B = rand(n*k,3);
tic
result1 = zeros(n*k,3);
for i = 1 : k
result1(i*3-2:i*3,:) = A*B(i*3-2:i*3,:);
end
disp("loop time: " + toc)
tic
[m,n]=size(A);
[r,c]=size(B);
BB=permute(reshape(B',c,c,[]),[2 1 3]);
[a,b,c]=size(BB);
BBB=reshape(BB,[a b*c]);
A_times_B_slices=A*BBB;
C=permute(reshape(A_times_B_slices,b,a,[]),[2 1 3]);
result2 = C(:,:).'; %<<<-------------------------***had to change this line***
disp("matrix manipulation time: " + toc)
equality = isequal(result1,result2)
end
and the results:
>> perform_test
loop time: 0.0046915
matrix manipulation time: 0.0009893
equality =
logical
1