Home vectorising multiple calls of Matlab 'find'

# vectorising multiple calls of Matlab 'find'

physioConfusio
1#
physioConfusio Published in 2018-02-14 00:31:34Z
 I make a large number of calls to the 'find' function of Matlab. For example, the following should give the essence: x=rand(1,10^8); indx=zeros(1,10^8); for i=1:10^8 indx(i) = find([0.2, 0.52, 0.76,1] < x(i), 1, 'last'); end  Is there a way to vectorize this code to speed it up? Just including x as a vector creates an error. If vectorization is not possible, then any other suggestions for speed would be appreciated. The actual problem I wish to solve has a considerably longer vector in the place of [0.2, 0.52, 0.76,1], so any solution shouldn't depend on the specific vector I provided. thanks.
crjones
2#
 Based on your example, you may want to consider using the discretize function for this: x=rand(1,10^8); edges = [0.2, 0.52, 0.76, 1]; indx = discretize(x, edges, 'IncludedEdge', 'right');  Note that cases outside of the range will result in NaN. % small test case % x = [0.5198, 0.0768, 0.6788, 0.9496] % indx = discretize(x, edges, 'IncludedEdge', 'right') % answer: 1 NaN 2 3  Of course, this will only be applicable if you're trying to find where x fits in a well-ordered set.
 Compare your vector with x to get a logical matrix indicating the values lesser in vec than x. Multiply that logical matrix with column vector representing the column subscripts. Use max to find the maximum (last) index that satisfies the inequality. For the case where inequality doesn't satisfy, you will get zero. vec = [0.2, 0.52, 0.76, 1]; %Your vector indx = bsxfun(@lt, vec(:), x); %Making 'vec' a column matrix and comparing with 'x' indx = max(bsxfun(@times, indx, (1:numel(vec)).')); %The required result  With R2016b and later versions, you can use implicit expansion instead of bsxfun: indx = vec(:) < x ; indx = max(indx .* (1:numel(vec)).'); 
 For MATLAB versions R2015a and newer, the answer from crjones gives the best option using discretize: edges = [0.2, 0.52, 0.76, 1]; indx = discretize(x, edges, 'IncludedEdge', 'right');  Any values in x outside the range of edges will have NaN for their indices. For MATLAB versions R2014b and newer you can also use histcounts: [~, ~, indx] = histcounts(x, edges);  The differences with discretize are that you can also get the count of values in each bin (the first output), and indices for values in x outside the range of edges will be 0. For MATLAB versions prior to R2014b you can use histc (deprecated in newer versions): [~, indx] = histc(x, edges);  Again, you can also get the count of values in each bin (the first output), and indices for values in x outside the range of edges will be 0.