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

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)
Not quite, it does the block multiplication but element wise, i needed scalar multiplication between the blocks.
madhan ravi
madhan ravi 2019년 1월 27일
편집: madhan ravi 2019년 1월 27일
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 2019년 1월 27일
편집: Eugenio Grabovic 2019년 1월 27일
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 2019년 1월 27일
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 2019년 1월 27일
편집: Eugenio Grabovic 2019년 1월 27일
@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
madhan ravi 2019년 1월 28일
편집: madhan ravi 2019년 1월 28일

2 개 추천

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

Stephan
Stephan 2019년 1월 28일
Nice! +1
Eugenio Grabovic
Eugenio Grabovic 2019년 1월 28일
편집: Eugenio Grabovic 2019년 1월 28일
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

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

질문:

2019년 1월 27일

편집:

2019년 1월 28일

Community Treasure Hunt

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

Start Hunting!

Translated by