Broadcast version of in() function or in operator? - julia

Consider an array, say 0 to 4. I want to test if each element is in a list and return an array of booleans. A call to in returns a single boolean, because this left-hand side array is not an element of the right-hand side array:
> a = 0:4;
> a in [1, 2]
false
Does Julia have a broadcast version of the in() function or the in operator that returns an array like this call to map and a lambda function?
> map(x -> x in [1,2], a)
5-element Array{Bool,1}:
false
true
true
false
false

You can use broadcasting, but you have to tell Julia that the second argument should not be iterated over, so you should do:
julia> in.(a, [[1,2]])
5-element BitArray{1}:
false
true
true
false
false
or
julia> in.(a, Ref{Vector{Int}}([1,2]))
5-element BitArray{1}:
false
true
true
false
false
Both will work under Julia 0.6.3 and 0.7.
Similarly, the ∈ operator (\inTAB, synonymous with the in function) allows for broadcasting using infix notation.
julia> 0:4 .∈ [[1,2]]
5-element BitArray{1}:
false
true
true
false
false

Related

Is there a Kronecker delta in Julia?

If I have some declared some Points in Julia (p_1,...,p_n). Is there some function or algorithm for kronecker delta (f_i(p_j)=1 if i=j and f_i(p_j)=0 if i != j)
It would be very helpful.
Thank you so much.
If you want a kronecker delta function you can use the ==(x,y) function (as indicated by #mbauman in the comments).
julia> δ(x,y) = ==(x,y)
δ (generic function with 1 method)
julia> δ(1,1)
true
julia> δ(1,2)
false
Note that this returns true or false instead of 1 and 0 but the former are essentially equal to the latter and will behave in the same way, for example ==(1,1) * 2 will give 2. In fact, true isa Integer in Julia.
Another option might be to use I the (lazy) identity matrix built into Julia (LinearAlgebra that is):
julia> using LinearAlgebra
julia> I[1,1]
true
julia> I[1,2]
false
For an arbitrary number of arguments, you can do:
δ(x, y) = ==(x, y)
function δ(x, y, z...)
!δ(x, y) && return false
for i in z
!δ(x, i) && return false
end
return true
end
or if you make the convention that δ(x) := true:
δ(x, y) = ==(x, y)
function δ(z...)
for i in z
!δ(z[1], i) && return false
end
return true
end

How do I check if an array is empty in Julia?

I am trying to see if there's a handy way to check if an array in Julia is empty or not.
In Julia you can use the isempty() function documented here.
julia> a = []
0-element Array{Any,1}
julia> isempty(a)
true
julia> length(a)
0
julia> b = [1]
1-element Array{Int64,1}:
1
julia> isempty(b)
false
Note that I included the length check as well in case that will help your use case.
For arrays one can also simply use a == []. The types are ignored in this comparison (as usual).
julia> a = []
a == []
0-element Array{Any,1}
julia> a == []
true
julia> a == Int[]
true
julia> String[] == Int[]
true
From Julia help:
isempty determines whether a collection is empty (has no elements).
e.g.
julia> isempty([])
true
julia> isempty(())
true

Substitute of "occursin" function to find a string in an Array{String,1}

What I am trying to do is
i = occursin("ENTITIES\n", lines)
i != 0 || error("ENTITIES section not found")
The error information is
ERROR: LoadError: LoadError: MethodError: no method matching occursin(::String, ::Array{String,1})
Closest candidates are:
occursin(::Union{AbstractChar, AbstractString}, ::AbstractString) at strings/search.jl:452
This is a piece of julia v0.6 code. I am using v1.1 now. I am new to julia and don't know what's the proper subsititute function for this. Please help.
You can broadcast orrursin like this (add a . after function name):
julia> x = "abc"
"abc"
julia> y = ["abc", "xyz"]
2-element Array{String,1}:
"abc"
"xyz"
julia> b = occursin.(x, y)
2-element BitArray{1}:
true
false
julia> findall(b)
1-element Array{Int64,1}:
1
julia> findfirst(b)
1
Note that although String can be iterated over it is treated by broadcast as a scalar.
Also it is worth to remember that occursin returns Bool value so that you can use it directly in logical tests e.g. i || error("ENTITIES section not found") in the code from your question.
In order to locate the index in the collection of the occurrence of true in the return value of broadcasted occursin use findall or findfirst functions (there is also findlast). The difference is that findall returns a vector of entries where true is encountered in the collection, while findfirst returns the first such entry only. Also note the difference when you pass all falses to it. findall will return an empty vector and findfirst will return nothing.
If you do not want to retain the vector b in the code above, you can get the indices directly (this should be faster) by passing a predicate as a first argument to findall/findfirst:
julia> findall(t -> occursin(x, t), y)
1-element Array{Int64,1}:
1
julia> findfirst(t -> occursin(x, t), y)
1

Dict with array key in julia

In julia language (ver 1.1.0), I am experimenting what would happen when I mutate a dictionary key.
Before mutation, both the variable x and [1,2,3] is recognized.
x = [1,2,3]; d = Dict(x=>"x")
haskey(d, x)
# true
haskey(d, [1,2,3])
# true
Once I mutate x, neither the variable x nor [1,2,3,4] is recognized.
push!(x, 4)
haskey(d, x)
# false
haskey(d, [1,2,3,4])
# false
haskey(d, [1,2,3])
# false
Value-wise, the key is "equal" to x, so I guess this has something to do with the hash function, but could not understand the source code.
collect(keys(d))[1] == x == [1,2,3,4]
# true
Can someone explain what makes this behavior, or suggest resources that I should look at?
The key function to look into is ht_keyindex.
There you can see that in order for the key to be found it must both:
Match hash value (via hashindex).
Match identity or value.
There is a non-negligible probability that after mutating x it will have the same hashindex value and the key would be found. For example here you could set index 4 of x to 5 and all seemingly would work:
julia> x[4] = 5
5
julia> x
4-element Array{Int64,1}:
1
2
3
5
julia> haskey(d, x)
true
Therefore - as in any programming language supporting dictionaries in a similar way - mutating keys of the dictionary should not be done. The above discussion should be in practice only a theoretical one.

Check if an Object is an Array or a Dict

I'd like to check if var is an Array or a Dict.
typeof(var) == Dict
typeof(var) == Array
But it doesn't work because typeof is too precise: Dict{ASCIIString,Int64}.
What's the best way ?
If you need a "less precise" check, you may want to consider using the isa() function, like this:
julia> d = Dict([("A", 1), ("B", 2)])
julia> isa(d, Dict)
true
julia> isa(d, Array)
false
julia> a = rand(1,2,3);
julia> isa(a, Dict)
false
julia> isa(a, Array)
true
The isa() function could then be used in control flow constructs, like this:
julia> if isa(d, Dict)
println("I'm a dictionary!")
end
I'm a dictionary!
julia> if isa(a, Array)
println("I'm an array!")
end
I'm an array!
Note: Tested with Julia 0.4.3
Instead of checking for a particular concrete type, such as Array, or Dict, you might do better by checking for the abstract types, and gain a lot of flexibility.
For example:
julia> x = [1,2,3]
3-element Array{Int64,1}:
1
2
3
julia> d = Dict(:a=>1,:b=>2)
Dict(:a=>1,:b=>2)
julia> isa(d, Associative)
true
julia> isa(x, AbstractArray)
true
There are many different types of arrays in Julia, so checking for Array is likely to be too restrictive, you won't get sparse matrices, for example.
There are also a number of different types of associative structures, Dict, ObjectIdDict, SortedDict, OrderedDict.

Resources