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 件のコメント

madhan ravi
madhan ravi 2019 年 1 月 27 日
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 2019 年 1 月 27 日
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.
Stephan
Stephan 2019 年 1 月 27 日
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 件)

カテゴリ

ヘルプ センター および File ExchangeMatrix Indexing についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by