File Exchange

image thumbnail

Vectorized FIND with 'FIRST' option

version 1.1.0.0 (5.13 KB) by Bruno Luong
Find the first non-zero element(s) along row/column - or any other dimension

3 Downloads

Updated 19 May 2010

View Version History

View License

Up to now, to find the first non-zero element of a matrix along a column (for example) user might:

1. Use for-loop with FIND command
for j=1:size(A,2)
... = find(A(:,j), 1, 'first');
end

2. Use other vectorized methods, often time not very straight-forwards (MAX, LOGICAL, SPARSE, etc...). This method creates temporary arrays and scan such the arrays few times while doing some calculation.

3. Write the basic FOR-LOOP algorithm to accomplish the task.

The FINDFIRST command does just the same, but implemented using MEX engine which should be faster than any of the above. It can handle 'FIRST', 'LAST' option, and return more than one FIND count.

NOTE: not yet tested on Linux (gcc)

Cite As

Bruno Luong (2020). Vectorized FIND with 'FIRST' option (https://www.mathworks.com/matlabcentral/fileexchange/24641-vectorized-find-with-first-option), MATLAB Central File Exchange. Retrieved .

Comments and Ratings (13)

Armin Kolb

Thx Bruno, it worked!

Bruno Luong

@Armin: try to change line #39 of find1dmex.c to
typedef int int32;

Those line are only lines platform-dependent.

I don't have Mac and associated compiler I can't test.

Armin Kolb

three years later, same error occurs from Joseph Cullen. I am using Matlab 2016b and macOS Sierra. was there any fix?

Uri Cohen

Bruno Luong

@Cullen, please ask Mac developer forum. It is odd that an integer 32 bits is not 4 bytes. Something must be very wrong,

Joseph Cullen

I am getting the following error when trying to run this on a Mac use the compiler in Xcode. From the other comment about Linux, it seems that I have to change the typedef. Any ideas about what it should be for Mac?

Error using find1dmex
FIND1DMEX: incorrect int32 definition (modify MEX file is required)

Error in findfirst (line 106)
B = find1dmex(A, count);

Error in test_nonparam (line 80)
z=findfirst(d)

Liber Eleutherios

I have tried this:

M = 1000; N = 20000;
A = rand(M, N) < 0.5;
tic, B = findfirst(A, 1, M); toc
tic
C = zeros(M, N);
inds = zeros(N, 1);
for hh = 1:N
tmp = find(A(:,hh));
inds(hh) = numel(tmp);
C((hh - 1) * M + (1:inds(hh))) = tmp;
end
toc
all(B(:) == C(:))

Works fine.

Liber Eleutherios

Karel Lebeda

Your comment is incorrect, on the 7th line should be:
B=zeros(1,size(A,2));

David

For this to work on linux, the typedefs need to be changed on lines 38-41 from:

typedef long long int int64;
typedef long int int32;
typedef short int16;
typedef char int08;

to:

typedef int64_t int64;
typedef int32_t int32;
typedef int16_t int16;
typedef int8_t int08;

best,
David

David

Andrea Freddi

Gianni Schena

handy and fast ! it implemnts an option not available in the standard matlab find function

MATLAB Release Compatibility
Created with R2009a
Compatible with any release
Platform Compatibility
Windows macOS Linux
Categories
Tags Add Tags
Acknowledgements

Inspired: csearch

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!