Help with Matrix block multiplication

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.
Thank you in advance.

7 comentarios

See if the below does what you want:
A = rand(3,3);
B = rand(9,3);
[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]);
CC = reshape(C,[],size(A,2),1)
Eugenio Grabovic
Eugenio Grabovic el 27 de En. de 2019
Not quite, it does the block multiplication but element wise, i needed scalar multiplication between the blocks.
madhan ravi
madhan ravi el 27 de En. de 2019
Editada: madhan ravi el 27 de En. de 2019
Give a short example of fixed A and B matrix and your expected result.
What is the question? You gave the solution by yourself in the question:
A = rand(3,3)
B = rand(9,3)
result = [A*B(1:3,:);A*B(4:6,:);A*B(7:9,:)]
The result is a concatenated block of the 3 results of matrix multiplication:
A =
0.8143 0.3500 0.6160
0.2435 0.1966 0.4733
0.9293 0.2511 0.3517
B =
0.8308 0.0759 0.3371
0.5853 0.0540 0.1622
0.5497 0.5308 0.7943
0.9172 0.7792 0.3112
0.2858 0.9340 0.5285
0.7572 0.1299 0.1656
0.7537 0.5688 0.6020
0.3804 0.4694 0.2630
0.5678 0.0119 0.6541
result =
1.2200 0.4076 0.8206
0.5776 0.2803 0.4899
1.1123 0.2707 0.6333
1.3134 1.0414 0.5404
0.6379 0.4349 0.2581
1.1904 1.0042 0.4802
1.0967 0.6348 0.9852
0.5271 0.2364 0.5079
0.9956 0.6506 0.8554
Eugenio Grabovic
Eugenio Grabovic el 27 de En. de 2019
Editada: Eugenio Grabovic el 27 de En. de 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
Stephan el 27 de En. de 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
Eugenio Grabovic el 27 de En. de 2019
Editada: Eugenio Grabovic el 27 de En. de 2019
@Stephan yes the only thing that is unkown is the row dimension of B ( parameter k) but is always a multiple of n.

Iniciar sesión para comentar.

 Respuesta aceptada

madhan ravi
madhan ravi el 28 de En. de 2019
Editada: madhan ravi el 28 de En. de 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

2 comentarios

Stephan
Stephan el 28 de En. de 2019
Nice! +1
Eugenio Grabovic
Eugenio Grabovic el 28 de En. de 2019
Editada: Eugenio Grabovic el 28 de En. de 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

Iniciar sesión para comentar.

Más respuestas (0)

Preguntada:

el 27 de En. de 2019

Editada:

el 28 de En. de 2019

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by