The number of values ​​is greater than the threshold

I have a matrix A Now I want to find the number of elements greater than 5 and their corresponding indices. How to solve this in matlab without using for loop?

For example, if A = [1 4 6 8 9 5 6 8 9]' :

  • Number of items> 5: 6
  • Indexes: [3 4 5 7 8 9]
+8
indexing matlab
source share
3 answers

You use find :

 index = find(A>5); numberOfElements = length(index); 
+14
source share

You use sum , which allows you to get the number of elements with a single command:

 numberOfElements = sum(A>5); 

Do you really need explicit indexes? Since the logical matrix A>5 can also be used as an index (usually more efficient than indexing with find ):

 index = (A>5); numberOfElements = sum(index); 

For completeness: indexing using logical systems is the same as regular indexes:

 >> A(A>5) ans = 6 8 9 6 8 9 
+4
source share

Motivated by the discussion above with Rody, here is a simple test that checks the speed of indexing integers and logical arrays in MATLAB. I would say a very important thing, since the "vectorized" MATLAB mainly deals with indexing. So

 % random data a = rand(10^7, 1); % threashold - how much data meets the a>threashold criterion % This determines the total indexing time - the more data we extract from a, % the longer it takes. % In this example - small threashold meaning most data in a % will meet the criterion. threashold = 0.08; % prepare logical and integer indices (note the uint32 cast) index_logical = a>threashold; index_integer = uint32(find(index_logical)); % logical indexing of a tic for i=1:10 b = a(index_logical); end toc % integer indexing of a tic for i=1:10 b = a(index_integer); end toc 

On my computer, the results

 Elapsed time is 0.755399 seconds. Elapsed time is 0.728462 seconds. 

means these two methods do pretty much the same thing - that’s how I chose the threashold example. This is interesting because the index_integer array index_integer almost 4 times bigger!

 index_integer 9198678x1 36794712 uint32 index_logical 10000000x1 10000000 logical 

For large index values, the threashold integer is faster. Results for threashold=0.5 :

 Elapsed time is 0.687044 seconds. (logical) Elapsed time is 0.296044 seconds. (integer) 

If I'm not doing something wrong here, integer indexing seems to be the fastest in most cases.

Including the creation of indexes in the test gives very different results:

 a = rand(1e7, 1); threshold = 0.5; % logical tic for i=1:10 inds = a>threshold; b = a(inds); end toc % double tic for i=1:10 inds = find(a>threshold); b = a(inds); end toc % integer tic for i=1:10 inds = uint32(find(a>threshold)); b = a(inds); end toc 

Results (Rody):

 Elapsed time is 1.945478 seconds. (logical) Elapsed time is 3.233831 seconds. (double) Elapsed time is 3.508009 seconds. (integer) 

Results (angainor):

 Elapsed time is 1.440018 seconds. (logical) Elapsed time is 1.851225 seconds. (double) Elapsed time is 1.726806 seconds. (integer) 

Thus, it would seem that actual indexing is faster when indexing with integers, but logical indexing is performed much better from front to back.

The time difference between the last two methods is unexpected, although it seems that the Matlab internal elements either do not reject double numbers as an integer, but instead perform error checking on each element before performing the actual indexing. Otherwise, we would not see almost any difference between double and integer methods.

Edit There are two options that I see:

  • matlab converts double indexes to uint32 indexes explicitly before the index call (as in the case of an integer test)
  • matlab skips doubling and double-clicking> on the fly during indexing

The second option should be faster, because we only need to read double indexes once. In our explicit conversion test, we must read the double indices, write the integer indices, and then read the integer indices again during the actual indexing. So Matlab should be faster ... Why is it not?

+2
source share

All Articles