how to use set operations in julia language - julia

I want to use set() as in python in Julia. Is it possible to do so? If yes, please provide an example using the following python code
set(A) - set(B)

The relevant functionality is explained in the docs. While you can still use -, it's been deprecated:
julia> A = [1,2,3]; B = [2,3,4];
julia> Set(A) - Set(B)
WARNING: a::Set - b::Set is deprecated, use setdiff(a,b) instead.
in - at deprecated.jl:26
Set{Int32}({1})
julia> setdiff(A, B)
1-element Array{Int32,1}:
1
julia> setdiff(Set(A), Set(B))
Set{Int32}({1})
Note that we can use setlike ops on arrays directly, in which case they're order-preserving.

You can also do this using the filter command. This way you will get an array back.
julia> A = [1; 2; 3]; B = [2; 3; 4; 5];
julia> filter(x -> !(x in A), B)
2-element Array{Int64,1}:
4
5

Related

Double Broadcasting in Julia for Matrix Vector Addition?

Newbie Julia question here. Given two arrays,
W = [randn(3,2), randn(3,2)]
b = [randn(3), randn(3)]
I would like to do a "nested broadcast" along the lines of,
W .+ b = [W[1].+b[1], W[2].+b[2]]
So far the best I've been able to come up with is,
[Wi.+bi (Wi,bi) for zip(W,b)]
Coming from a Python background this feels sacrilegious. Is there a better way to do this in Julia?
You could do something like the following:
julia> W = [randn(3,2), randn(3,2)]
2-element Array{Array{Float64,2},1}:
[0.39179718902868116 -0.5387622679356612; -0.594274465053327 0.018804631512093436; -2.273706742420988 -0.4638617400026042]
[0.3249960563405678 -0.4877554417492699; 0.5036437919340767 1.3172770503034696; 0.03501532820428975 -0.2675024677340758]
julia> b = [randn(3), randn(3)]
2-element Array{Array{Float64,1},1}:
[1.2571527266220441, 0.21599608118129476, 0.21498843153804936]
[-0.528960345932853, 0.5610435189953311, -0.8636370930615718]
# A helper function which broadcasts once
julia> s_(Wi, bi) = Wi .+ bi
s_ (generic function with 1 method)
# Broadcast the helper function
julia> s_.(W, b)
2-element Array{Array{Float64,2},1}:
[1.6489499156507252 0.718390458686383; -0.3782783838720323 0.2348007126933882; -2.0587183108829388 -0.24887330846455485]
[-0.20396428959228524 -1.016715787682123; 1.0646873109294077 1.8783205692988008; -0.828621764857282 -1.1311395607956476]
As mentioned in comments, you can use one of the available user-definable infix operators to name the helper function, which allows for a nicer syntax (the particular symbol used below can be obtained by typing \oplus then Tab):
julia> ⊕(x, y) = x .+ y
⊕ (generic function with 1 method)
julia> W .⊕ b
2-element Array{Array{Float64,2},1}:
[1.6489499156507252 0.718390458686383; -0.3782783838720323 0.2348007126933882; -2.0587183108829388 -0.24887330846455485]
[-0.20396428959228524 -1.016715787682123; 1.0646873109294077 1.8783205692988008; -0.828621764857282 -1.1311395607956476]
Or - again as mentioned in comments - if you don't feel like explicitly declaring a helper function:
julia> ((Wi, bi)->Wi.+bi).(W, b)
2-element Array{Array{Float64,2},1}:
[1.6489499156507252 0.718390458686383; -0.3782783838720323 0.2348007126933882; -2.0587183108829388 -0.24887330846455485]
[-0.20396428959228524 -1.016715787682123; 1.0646873109294077 1.8783205692988008; -0.828621764857282 -1.1311395607956476]
(I personally have more difficulty reading that last version, but YMMV)
When you want to broadcast broadcast, then broadcast broadcast:
julia> broadcast.(+, W, b)
2-element Array{Array{Float64,2},1}:
[-0.7364111670769904 0.010994354421031916; -0.9010128415786036 0.22868802910609998; 1.2030371118617933 0.21305414210853912]
[0.19183885867446926 0.5362077496502086; 1.5909421118115665 0.1235808501390212; 1.5190965380769597 0.1883638848487652]
julia> [W[1].+b[1], W[2].+b[2]]
2-element Array{Array{Float64,2},1}:
[-0.7364111670769904 0.010994354421031916; -0.9010128415786036 0.22868802910609998; 1.2030371118617933 0.21305414210853912]
[0.19183885867446926 0.5362077496502086; 1.5909421118115665 0.1235808501390212; 1.5190965380769597 0.1883638848487652]

How to pretty print matrix to String in Julia?

How to use show to pretty print matrix to String?
It's possible to print it to stdout with show(stdout, "text/plain", rand(3, 3)).
I'm looking for something like str = show("text/plain", rand(3, 3))
For simple conversions usually DelimitedFiles is your best friend.
julia> a = rand(2,3);
julia> using DelimitedFiles
julia> writedlm(stdout, a)
0.7609054249392935 0.5417287267974711 0.9044189728674543
0.8042343804934786 0.8206460267786213 0.43575947315522123
If you want to capture the output use a buffer:
julia> b=IOBuffer();
julia> writedlm(b, a)
julia> s = String(take!(b))
"0.7609054249392935\t0.5417287267974711\t0.9044189728674543\n0.8042343804934786\t0.8206460267786213\t0.43575947315522123\n"
Last but not least, if you want to have a stronger control use CSV - and the pattern is the same - either use stdout or capture the output using a buffer e.g.:
julia> using CSV, Tables
julia> b=IOBuffer();
julia> CSV.write(b, Tables.table(a));
julia> s = String(take!(b))
"Column1,Column2,Column3\n0.7609054249392935,0.5417287267974711,0.9044189728674543\n0.8042343804934786,0.8206460267786213,0.43575947315522123\n"
Even more - if you want to capture the output from display - you can too!
julia> b=IOBuffer();
julia> t = TextDisplay(b);
julia> display(t,a);
julia> s = String(take!(b))
"2×3 Array{Float64,2}:\n 0.760905 0.541729 0.904419\n 0.804234 0.820646 0.435759"
What you were looking for:
b = IOBuffer()
show(b, "text/plain", rand(3, 3))
s = String(take!(b))

What is the difference between fields and properties in Julia?

Julia has the setter functions setproperty! and setfield! and the getter functions getproperty and getfield that operate on structs. What is the difference between properties and fields in Julia?
For example, the following seems to indicate that they do the same thing:
julia> mutable struct S
a
end
julia> s = S(2)
S(2)
julia> getfield(s, :a)
2
julia> getproperty(s, :a)
2
julia> setfield!(s, :a, 3)
3
julia> s
S(3)
julia> setproperty!(s, :a, 4)
4
julia> s
S(4)
fields are simply the "components" of a struct. The struct
struct A
b
c::Int
end
has the fields b and c. A call to getfield returns the object that is bound to the field:
julia> a = A("foo", 3)
A("foo", 3)
julia> getfield(a, :b)
"foo"
In early versions of Julia, the syntax a.b used to "lower", i.e. be the same as, writing getfield(a, :b). What has changed now is that a.b lowers to getproperty(a, :b) with the default fallback
getproperty(a::Type, v::Symbol) = getfield(a, v)
So by default, nothing has changed. However, authors of structs can overload getproperty (it is not possible to overload getfield) to provide extra functionality to the dot-syntax:
julia> function Base.getproperty(a::A, v::Symbol)
if v == :c
return getfield(a, :c) * 2
elseif v == :q
return "q"
else
return getfield(a, v)
end
end
julia> a.q
"q"
julia> getfield(a, :q)
ERROR: type A has no field q
julia> a.c
6
julia> getfield(a, :c)
3
julia> a.b
"foo"
So we can add extra functionality to the dot syntax (dynamically if we want). As a concrete example where this is useful is for the package PyCall.jl where you used to have to write pyobject[:field] while it is possible now to implement it such that you can write pyobject.field.
The difference between setfield! and setproperty! is analogous to the difference between getfield and getproperty, explained above.
In addition, it is possible to hook into the function Base.propertynames to provide tab completion of properties in the REPL. By default, only the field names will be shown:
julia> a.<TAB><TAB>
b c
But by overloading propertynames we can make it also show the extra property q:
julia> Base.propertynames(::A) = (:b, :c, :q)
julia> a.<TAB><TAB>
b c q

Assign vector components to different variables in Julia

I want to assign the result of an operation to a concatenation of variables in Julia. Something similar to this (although this doesn't work):
a = zeros(5)
b = zeros(5)
a, b .= rand(10)
Is it possible? Thank you.
You are looking for "vector view concatenation". The idea here is to use SubArrays to build an Array that is actually a view into two arrays. Julia does not support this out of the box. The Julia package ChainedVectors.jl was built for this, but it is heavily outdated and only works with Julia <= 0.4.
Not everything is lost. You have two alternatives:
Use CatViews.jl
As pointed out in the comments, CatViews.jl is like ChainedVectors.jl, but works with Julia 0.6 and 0.7:
Pkg.add("CatViews")
using CatViews
a = zeros(2)
b = zeros(2)
CatView(a, b) .= rand(4)
Build your own solution
With a little work, we can get as good as
a = zeros(2)
b = zeros(2)
MyView(a, b) .= rand(4)
Julia allows you to build your own view-concatenation type. The effort required to build it scales proportional to how general you want it to be. Here is a first attempt that works with vectors:
julia> # Create a type for a view into two vectors.
julia> type MyView{T} <: AbstractVector{T}
a::Vector{T}
b:: Vector{T}
end
julia> import Base: size, getindex, setindex!
julia> # Define methods to make MyView behave properly.
julia> size(c::MyView) = size(c.a) .+ size(c.b)
julia> getindex(c::MyView, i::Int) = i <= length(c.a) ? getindex(a, i) : getindex(b, i-length(a))
julia> setindex!(c::MyView, val, i::CartesianIndex) = i[1] <= length(c.a) ? setindex!(c.a, val, i[1]) : setindex!(c.b, val, i[1]-length(a))
julia> setindex!(c::MyView, val, i::Int) = i <= length(c.a) ? setindex!(c.a, val, i) : setindex!(c.b, val, i-length(a))
julia> # Test MyView. Define two arrays and put them
julia> # into a single view.
julia> a = rand(2)
2-element Array{Float64,1}:
0.701867
0.543514
julia> b = rand(2)
2-element Array{Float64,1}:
0.00355893
0.405809
julia> MyView(a, b) .= rand(4)
4-element MyView{Float64}:
0.922896
0.969057
0.586866
0.457117
julia> # Hooray, it worked! As we see below,
julia> # the individual arrays were updated.
julia> a
2-element Array{Float64,1}:
0.922896
0.969057
julia> b
2-element Array{Float64,1}:
0.586866
0.457117
This?
a .= x[1:5]
b .= x[6:end]
You must tell Julia somehow where to split the vector.

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