6.3. Logical Indexing#
6.3.1. Introduction to Logical indexing#
As an alternative to indexing an array by x[idx]
where idx
is an array of integers, logical indexing allows for the syntax x[choose]
where choose
is an array of booleans. The size of choose
must be the length of the array (or more generally, the dimension it indexes into). Note that the result is identical to x[findall(choose)]
, but shorter to write and likely more efficient.
x = -11:11
y = sin.(x)
x = x[y .> 0] # Only keep values of x where y=sin x is positive
11-element Vector{Int64}:
-11
-10
-6
-5
-4
1
2
3
7
8
9
# Example: Consider the matrix
A = rand(-10:10, 3, 10)
3×10 Matrix{Int64}:
2 -3 10 7 3 3 2 -8 9 7
0 -4 3 -6 3 9 4 2 5 -6
5 10 2 -9 -3 -8 5 8 -8 -10
# Compute a boolean array with `true` if the column sums are >=0
pick = sum(A, dims=1) .≥ 0
1×10 BitMatrix:
1 1 1 0 1 1 1 1 1 0
# Create a new vector with only the columns of A given by the `pick` variable
# Note that since `pick` is a 2D vector (row vector), we use [:] before indexing
B = A[:, pick[:]]
3×8 Matrix{Int64}:
2 -3 10 3 3 2 -8 9
0 -4 3 3 9 4 2 5
5 10 2 -3 -8 5 8 -8
6.3.2. Examples: Simplifying the Sieve of Eratosthenes function#
In our previous implementation, we used the code below to collect all the prime numbers:
...
# Return an array with all prime numbers
primes = Int64[]
for i = 2:n
if prime[i]
push!(primes, i)
end
end
primes
...
Using array comprehensions, we can replace this entire part of the code by a single line:
primes = [ i for i = 2:n if prime[i] ]
or even simpler, since the list of primes is simply the indices of the true
values in the array prime
, we can use the findall
function. However in our original implementation, prime[1]
was set to true
(since it was not used) so we have to first make sure the number 1 is not considered a prime. Then the code can be written as:
prime[1] = false
primes = findall(prime)
6.3.3. Example: Simplifying the dart-throwing function#
We previously used the following code to count the number of “hits”, that is, how many points in the vectors x
,y
are inside the unit circle:
# Determine if points are inside the circle (a "hit")
hits = 0
for i = 1:n
if x[i]^2 + y[i]^2 ≤ 1
hits += 1
end
end
Using the count
function, this can be written as a single line of code:
hits = count(@. x^2 + y^2 ≤ 1)
6.3.4. Example: Simplifying the poker hand flush code#
When simulating the poker hands, we used the following code to determine if all cards were of the same suit:
same_suit = true
for i = 2:5
if suits[i] ≠ suits[1]
same_suit = false
break
end
end
Using the all
function, this can be simplified to a single line of code:
same_suit = all(suits[2:5] .== suits[1])