How to accumulate submatrices without loop (smoothing subarrays)?

In Matlab, I need to accumulate overlapping diagonal blocks of a large matrix. Sample code is shown below.

Since this piece of code needs to be run multiple times, it consumes a lot of resources. This process is used to process array signals for so-called subara smoothing or spatial smoothing. Is there a way to make it faster?

% some values for parameters
M = 1000; % size of array
m = 400; % size of subarray
n = M-m+1; % number of subarrays 
R = randn(M)+1i*rand(M);

% main code
S = R(1:m,1:m);
for i = 2:n
    S = S + R(i:m+i-1,i:m+i-1);
end

      

ATTEMPTS:

1) I tried the following alternate vectorized version, but unfortunately it got a lot slower!

[X,Y] = meshgrid(1:m);
inds1 = sub2ind([M,M],Y(:),X(:));
steps = (0:n-1)*(M+1);
inds = repmat(inds1,1,n) + repmat(steps,m^2,1);
RR = sum(R(inds),2);
S = reshape(RR,m,m); 

      

2) I used Matlab encoder to create MEX file and it got much slower!

+3


source to share


1 answer


Recently I had to copy some parts of my code to some extent. Without being an expert, I would recommend trying the following:

1) Vectorization :

How to get rid of the for-loop

S = R(1:m,1:m);
for i = 2:n
    S = S + R(i:m+i-1,i:m+i-1)
end

      

and replace it with an alternative based on cumsum

should be here.

Note. Try working on this approach in the future.



2) Creating a MEX file :

In some cases, you can just start the Matlab Coder application (given that you have it in your current Matlab version). This should create a file .mex

for you that you can call as this was the function you are trying to replace.


Whether you choose (1) or 2)), you should profile your current implementation with tic; my_function(); toc;

for enough function calls and compare it to your current implementation:

my_time = zeros(1,10000);
for count = 1:10000
    tic;
    my_function();
    my_time(count) = toc;
end
mean(my_time)

      

-1


source







All Articles