Here's how to do it in a vectorized way:
TR = 16;
sets = num2cell(single(x),2);
c = cell(1, numel(sets));
[c{:}] = ndgrid( sets{:} );
cartProd = cell2mat( cellfun(@(v)v(:), c, 'UniformOutput',false) );
validRows = cartProd(sum(cartProd,2) > TR,:); % output is [353x11]
Notice how I use single
to save space and make the computation slightly faster.
The above solution is an adaptation of this answer.
Upon further contemplation, I think I've come up with a way that should be both faster and more memory efficient. We do this by indexing x
, and then doing the previous process on the indices. Why is this better, you might ask? This is because we can store the indices as uint8
, which consumes considerably less memory than double
or even single
. Also we get to keep the full double
precision of x
. Thus:
function validRows = q42933114(x,thresh)
%% Input handling
if nargin < 2
thresh = 16;
end
if nargin < 1
x = [...
4.9000 -0.1000 -5.1000
4.6000 -0.4000 -5.4000
3.0000 -2.0000 -7.0000
2.9000 -2.1000 -7.1000
2.9000 -2.1000 -7.1000
2.9000 -2.1000 -7.1000
2.8000 -2.2000 -7.2000
2.7000 -2.3000 -7.3000
2.7000 -2.3000 -7.3000
2.2000 -2.8000 -7.8000
1.8000 -3.2000 -8.2000
];
end
I = reshape(uint8(1:numel(x)),size(x));
sets = num2cell(I,2);
c = cell(1, numel(sets));
[c{:}] = ndgrid( sets{:} );
cartProd = cell2mat( cellfun(@(v)v(:), c, 'UniformOutput',false) );
validRows = x(cartProd(sum(x(cartProd),2) > thresh,:));
Memory consumption comparison:
Method 1 (old):
>> whos
Name Size Bytes Class Attributes
c 1x11 7795700 cell
cartProd 177147x11 7794468 single
sets 11x1 1364 cell
validRows 353x11 15532 single
Method 2 (new):
>> whos
Name Size Bytes Class Attributes
c 1x11 1949849 cell
cartProd 177147x11 1948617 uint8
sets 11x1 1265 cell
validRows 353x11 31064 double
We see that the memory consumption is indeed smaller (in about 4 times), as expected.
Runtime comparison:
Method 1 -- 0.0110
Method 2 -- 0.0186
Here we see that the 2nd method is actually a bit slower. When profiling this, we see that the cause is x(...)
which is relatively expensive.