Search code examples
matlabfor-loopmatrixvectorization

Vectorize a "shrinking" scalar product in MATLAB


Say I am given a row vector psi of length P and a row vector q of length M in MATLAB. Here, M>P. I want to assemble G in the following way:

for j = 1:M
        G(j) = q(j:min(j+P-1, M))*psi(1:min(M-j+1, P))';
end

For large M, P, this is very time consuming. It is also delicate to the size of qand psi changing for large j.

For example: (adapted to the answer) If

M = 20;
P = 7;
psi = [1:P];
q = [1:M];

, then

G =

  Columns 1 through 11

   140   168   196   224   252   280   308   336   364   392   420

  Columns 12 through 20

   448   476   504   385   280   190   116    59    20

if it is produced with the above for loop.

I have not been able to vectorize this, also due to j moving. Of course, one could write this as a matrix-vector multiplication with psi being the vector, but assembling the correct matrix looks almost equally expensive to me.

I appreciate any sort of help.


Solution

  • This is a cross-correlation. You could use xcorr and then trim the results, or pad and let filter2 do the work for you. I chose to use filter2.

    Since you want only the valid values at the front, and all of the values at the end, you do need to pad the end of q with P - 1 zeros.

    M = 20;
    P = 7;
    q = [1:M];
    psi = [1:P];
    qp = [q zeros(1, P-1)];   % padded q
    
    G_filt = filter2(psi, qp, 'valid');
    
    G_filt =
     Columns 1 through 16:
       140   168   196   224   252   280   308   336   364   392   420   448   476   504   385   280
     Columns 17 through 20:
       190   116    59    20
    

    Results from your example:

    G =
     Columns 1 through 16:
       140   168   196   224   252   280   308   336   364   392   420   448   476   504   385   280
     Columns 17 through 20:
       190   116    59    20