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!
source to share
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)
source to share