0

Suppose I have a matrix of dimension [4x4], and a vector of [16x1], I need to multiply every 4 element in the vector in one element in the matrix, (instead of multiplying element in row by element in vector), how can I do that using loop ?

For example here below, the results of the first four elements in the resulted vector as shown in the below example, then the same thing for the second, third and fourth rows in the matrix. :

enter image description here

So the results in that example is supposed to be [16x1]

Thank you

Community
  • 1
  • 1
Gze
  • 398
  • 1
  • 12

4 Answers4

3

Using kron you can use this one-liner:

%A = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16];
%v = [2 2 2 2 0 0 0 0 1 1 1 1 3 3 3 3].';
sum(kron(A,ones(4,4)).'.*v).'/4

I use the kronecker tensor product to "replicate" 4x4 time the A matrice. After that it's pure algebra.

obchardon
  • 10,614
  • 1
  • 17
  • 33
2

There are details that I assumed, but this shoudl do the trick:

A=reshape(1:16,4,4).';
b=repelem([2,0,1,3],1,4).';

c=[];
for row=1:size(A,1)
     c=[ c; sum(reshape(repelem(A(row,:),4).*b.',4,[]),2)];
end

I am assuming here that your demo for the vector is just a bad example and that you wont have repeated values, otherwise an easier version can be achieved by just not doing 3/4ths of the multiplications.


If you do not have access to repelem, have a look at alterative codes that do the same thing:Element-wise array replication in Matlab

Ander Biguri
  • 35,140
  • 11
  • 74
  • 120
  • Thank you so much for your quick answer, could you please explain what you mean by repelem ?? when I type help for it in MATLAB, I don't get it. are you doing repeating for elements of 2, 0 , 1 and 3 ?? but what's about they are generated randomly ? – Gze Feb 27 '19 at 09:59
  • How about to do using the command repmat(A,4,4) , where A is the matrix [4x4]? but in that case, the whole matrix will be repeated, is there a command alternative to repmat where I can repeat element by element ?? – Gze Feb 27 '19 at 10:09
  • @Gze please, read the linked question. It has 7 answers to your problem, there is no need for me to explain them here – Ander Biguri Feb 27 '19 at 10:10
  • 1
    Thank you so much, that worked also well. but I don't have right to vote up nor accepting more than one answer :) – Gze Feb 27 '19 at 10:36
2

See if this is what you want:

A = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16];
v = [2 2 2 2 0 0 0 0 1 1 1 1 3 3 3 3].';
r = reshape(sum(bsxfun(@times, permute(A, [3 2 1]), permute(reshape(v, 1, [], size(A,2)), [2 3 1])), 2), [], 1);

which gives

r =
    17
    17
    17
    17
    41
    41
    41
    41
    65
    65
    65
    65
    89
    89
    89
    89
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
2

This is just matrix multiplication in disguise... If your tall vector was a matrix of the same size as the matrix shown, where each highlighted block is a row, it's matrix multiplication. We can set this up, then reshape back into a vector.

You can use indexing to turn this into simple matrix multiplication. A question I answered already today details how the below indexing works using bsxfun, then we just reshape at the end:

% Setup
A = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16];
v = [2 2 2 2 0 0 0 0 1 1 1 1 3 3 3 3].';

% Matrix mutliplication
r = numel(v)/size(A,1);
b = A * v( bsxfun( @plus, (1:r:numel(v)).', 0:r-1 ) );
% Make result a column vector
b = reshape( b.', [], 1 );
Wolfie
  • 27,562
  • 7
  • 28
  • 55