The straightforward approach to this in Julia uses broadcasting. The OR operator in Julia is |
. To broadcast an operator like this, we can prefix it with a dot as follows.
julia> .|(a)
2×2 BitMatrix:
1 0
1 1
julia> .|(a,b)
2×2 BitMatrix:
1 0
1 1
julia> .|(a,b,c)
2×2 BitMatrix:
1 0
1 1
julia> .|(a,b,c,d)
2×2 BitMatrix:
1 0
1 1
Indicating each matrix manually is tedious. To avoid this, we can use the splat operator which will take elements in an iterator and turn them each into a distinct argument for the function being called.
julia> .|(z1...)
2×2 BitMatrix:
1 0
1 1
julia> .|(z2...)
2×2 BitMatrix:
1 0
1 1
julia> .|(z3...)
2×2 BitMatrix:
0 0
1 1
julia> .|(z4...)
2×2 BitMatrix:
1 0
1 1
julia> .|(z100...)
2×2 BitMatrix:
1 1
1 1
Note that broadcasting allows for expansion of some of the arguments so all the arguments do not need to be the same shape.
julia> .|(z4..., [1 0])
2×2 Matrix{Int64}:
1 0
1 1
julia> .|(z4..., [0 1])
2×2 Matrix{Int64}:
1 1
1 1
julia> .|(z4..., [0, 1])
2×2 Matrix{Int64}:
1 0
1 1
julia> .|(z4..., [1, 0])
2×2 Matrix{Int64}:
1 1
1 1
julia> .|(z4..., 0)
2×2 Matrix{Int64}:
1 0
1 1
julia> .|(z4..., 1)
2×2 Matrix{Int64}:
1 1
1 1
Since the above solutions use broadcasting, they are quite general. If we constrain the problem such that all the boolean matrices must be the same size, then we can take advantage of short circuit evaluation. Once we find a 1
or true
value in any position, we do not need to check the elements in the same position of subsequent matrices. To implement this we will use the any
function along with an array comprehension.
julia> short_circuit_or(z...) = short_circuit_or(z)
short_circuit_or (generic function with 1 method)
julia> short_circuit_or(z::Tuple) = [
any(x->x[ind], z) for ind in CartesianIndices(first(z))
]
short_circuit_or (generic function with 2 methods)
julia> short_circuit_or(a,b,c)
2×2 Matrix{Bool}:
1 0
1 1
julia> short_circuit_or(z4...)
2×2 Matrix{Bool}:
1 0
1 1
julia> short_circuit_or(z1)
2×2 Matrix{Bool}:
1 0
1 1
julia> short_circuit_or(z2)
2×2 Matrix{Bool}:
1 0
1 1
julia> short_circuit_or(z3)
2×2 Matrix{Bool}:
0 0
1 1
julia> short_circuit_or(z4)
2×2 Matrix{Bool}:
1 0
1 1
julia> short_circuit_or(z100)
2×2 Matrix{Bool}:
1 1
1 1
As demonstrated by these benchmarks, short circuit evaluation can save time.
julia> using BenchmarkTools
julia> @btime .|($z100...)
3.032 ms (24099 allocations: 1.91 MiB)
2×2 BitMatrix:
1 1
1 1
julia> @btime short_circuit_or($z100)
76.413 ns (1 allocation: 96 bytes)
2×2 Matrix{Bool}:
1 1
1 1
short_circuit_or
- could you add it so other readers can use it? – Piceous