MATLAB: Split matrix into matrices with rows in same range

MATLAB

I have a matrix A as below:
a = [20 30 45 55 100; 200 150 175 60 20; 100 29 36 52 98; 28 33 48 62 95; 206 147 180 53 45];
I want to have matrices with rows in range of +/-10 and if one number of each rows are out of range, it's okay.
For example, for matrix A we can write:
B = [20 30 45 55 100; 100 29 36 52 98; 28 33 48 62 95]
C = [200 150 175 60 20; 206 147 180 53 45]
for example if I have a matrix 1000*2000 how can I split it?

Best Answer

As John says clearer criteria for splitting the rows would be welcome.
If all the requirement is that the difference between the rows is between (-10, 10) for all but one column, then are you aware that worst case scenario that would required (1000*999/2 - 1) * 2000 ~= 1e9 comparisons (if none of the rows are within range of each other).
For small matrices,
squeeze(sum(abs(a - permute(a, [3 2 1])) <= 10, 2) >= size(a, 2)-1)
%in versions < R2016b:

%squeeze(sum(abs(bsxfun(@minus, a, permute(a, [3 2 1]))) <= 10, 2) >= size(a, 2)-1)
will give you a symmetrical matrix telling you which rows are in range of each other.
For a 1000x2000 matrix, the above is prohibitively expensive as it would require around 15 GB of memory just for storing the difference matrix and a very long time to generate. An iterative approach may work:
splitmatrices = {};
while ~isempty(a)
inrange = sum(abs(a(1, :) - a(2:end, :)) <= 10, 2) >= size(a, 2)-1;
%in versions < R2016b:
%inrange = sum(bsxfun(@minus, abs(a(1, :), a(2:end, :))) <= 10, 2) >= size(a, 2)-1;
rowstoextract = [1; find(inrange)+1];
splitmatrices(end+1) = {a(rowstoextract, :)};
a(rowstoextract, :) = [];
end
The above would work as long as the number of groups is not too high. Otherwise, again the computation time will become prohibitive.
Note: That algorithm makes no attempt to optimise the sets. There may be rows that could belong to several sets, and you could possibly create an algorithm that minimise the number of sets or prioritise sets with more rows. The algorithm above simply puts the row with the earliest row that is in range.