2

A motivating issue, implemented in Matlab:

N = 1000;
R = zeros(2*N);

for i=0:N-1
    R = R(2:end-1, 2:end-1);
end

For this code timeit() gives a time 2.9793 on my machine. It isn't really great.

By canonical way I mean a discussion that isn't just acceptable, but a performant implementation that respects very large matrices reduced. I would be very appreciative of any answer, referrals to other discussions or literature.

As for language, I am not really a programmer, this question is motivated by a mathematics inquiry and I have encountered performance issues implementing any such reduction process in Matlab. Is there a solution to this in Matlab, or must one delve into the scary depths of C/C++?

One note: One may ask, why not just keep the matrix as is and consider parts of it as needed? To clarify, the reduction process in practice of course depends on the actual (nonzero) values of the elements, e.g. by processing the matrix in 2x2 blocks, and the removal of edge-values is needed to prepare the matrix for then next reduction step.

  • What is the the whole processing time of your algorithm including processing the matrix in 2x2 blocks? What is the contribution of reduction 2.9793 to the whole processing time? – rahnema1 Nov 30 '20 at 12:41
  • Related: https://stackoverflow.com/questions/19633192/memory-efficient-way-to-truncate-large-array-in-matlab, https://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/ – Luis Mendo Nov 30 '20 at 13:12
  • @rehnema1 For a starting 1200x1200 matrix of weights it is worked down to 2x2 in 2.413s (with ~1s) of this being removal of boundary values from the matrix. I put the calculation step into a mex function to speed up the 2x2 block operations on the matrix (takes ~1.18s) but the subsequent removal of borders takes almost as long. – user9584063 Nov 30 '20 at 15:27
  • If you are using mex to do block operation it is easy to tune it to operate on parts of the matrix without copying. – rahnema1 Nov 30 '20 at 17:35

2 Answers2

1

R(2:end-1, 2:end-1) is the correct way of extracting the part of the array that is all values except the ones at the edges. This requires copying the data, so will take some time. There is no legal way around the copy, and no alternative for extracting a part of the array. (subsref might seems like an alternative, but is the function that is internally called for the given syntax.)

As for illegal ways, you could try James Tursa’s sharedchild from the MATLAB FileExchange. It allows to create an array that references subsets of the data of another array. James is well known in the MATLAB user community as one of the people reverse-engineering the system and bending it to his will. This is solid code. But every version of MATLAB introduces new changes to the infrastructure, so upgrading MATLAB might break your program if you use this code.

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
0

You don't need the for loop. If you want to remove L elements from the borders, simply do:

R=R(L+1:end-L, L+1:end-L)

I am surprised you didn't get an error with that code. I think you should end up with an empty matrix at the end of the loop.

falopsy
  • 636
  • 7
  • 16