Julia - how to define an array of images for FluxML mlp? - julia

I wish to re-use this code:
https://github.com/FluxML/model-zoo/blob/master/vision/mnist/mlp.jl
but with my own set of images.
I think I need to define an object like imgs of type Array{Array{Gray{Normed{UInt8,8}},2},1}
How do I initialize an array of images to obtain something of the following type:
Array{Array{Gray{Normed{UInt8,8}},2},1}
I tried this, but it fails:
x = Array{Array{ColorTypes.Gray{FixedPointNumbers.Normed{UInt8,8}},2}}(10)
ERROR: MethodError: no method matching Array{Array{Gray{Normed{UInt8,8}},2},N} where N(::Int64)
Closest candidates are:
Array{Array{Gray{Normed{UInt8,8}},2},N} where N(::UndefInitializer, ::Int64) where T at boot.jl:416
Array{Array{Gray{Normed{UInt8,8}},2},N} where N(::UndefInitializer, ::Int64, ::Int64) where T at boot.jl:417
Array{Array{Gray{Normed{UInt8,8}},2},N} where N(::UndefInitializer, ::Int64, ::Int64, ::Int64) where T at boot.jl:418
...
Stacktrace:
[1] top-level scope at none:0

To create an empty vector use:
Array{Array{Gray{Normed{UInt8,8}},2},1}()
then you can use the push! function to add images to it. Alternatively you could write the same as:
Vector{Matrix{Gray{Normed{UInt8,8}}}}()
which is a bit easier to read.
Alternatively you can write:
Array{Array{Gray{Normed{UInt8,8}},2},1}(undef, 10)
To create an uninitialized vector with 10 entries. Then you can use normal index setting syntax to initialize it. Again you could write it also as:
Vector{Matrix{Gray{Normed{UInt8,8}}}}(undef, 10)

Related

Can't plot in Julia

I am currently reading a book (BRML) which has a demo (earthquake demo, exercise 1.22), which is written in Julia. I have never used Julia (although used Python and other languages quite extensively) before so I'm a complete noob.
What exactly does the line plot(x,y,".") do in the following code:
Pkg.add("Pkg")
using Pkg
Pkg.add("PyPlot")
S=5000 # number of points on the spiral
x=zeros(S); y=zeros(S)
for s=1:S
theta=50*2*pi*s/S; r=s/S
x[s]=r*cos(theta); y[s]=r*sin(theta)
end
plot(x,y,".")
I understand everything that is done before that, however I'm not sure what that specific line does. The reason I can't see for myself is because when I'm trying to run it on an online Julia compiler, I get the following error:
INFO: Initializing package repository /home/cg/root/4655378/.julia/v0.6
INFO: Cloning METADATA from https://github.com/JuliaLang/METADATA.jl
ERROR: LoadError: GitError(Code:ERROR, Class:Net, curl error: Could not resolve host: github.com
)
Stacktrace:
[1] macro expansion at ./libgit2/error.jl:99 [inlined]
[2] clone(::String, ::String, ::Base.LibGit2.CloneOptions) at ./libgit2/repository.jl:276
[3] #clone#100(::String, ::Bool, ::Ptr{Void}, ::Nullable{Base.LibGit2.AbstractCredentials}, ::Function, ::String, ::String) at ./libgit2/libgit2.jl:562
[4] (::Base.LibGit2.#kw##clone)(::Array{Any,1}, ::Base.LibGit2.#clone, ::String, ::String) at ./<missing>:0
[5] (::Base.Pkg.Dir.##8#10{String,String})() at ./pkg/dir.jl:55
[6] cd(::Base.Pkg.Dir.##8#10{String,String}, ::String) at ./file.jl:70
[7] init(::String, ::String) at ./pkg/dir.jl:53
[8] #cd#1(::Array{Any,1}, ::Function, ::Function, ::String, ::Vararg{String,N} where N) at ./pkg/dir.jl:28
[9] add(::String) at ./pkg/pkg.jl:117
while loading /home/cg/root/4655378/main.jl, in expression starting on line 1
As the third line indicates, the book is using the PyPlot package, which is basically a Julia wrapper around Python's pyplot.
So, we could refer to pyplot's documentation to figure out how that line of code works. But as mentioned in that page, pyplot is trying to emulate MATLAB's plot function, and for this case their help page is easier to navigate. As mentioned there,
plot(X,Y) creates a 2-D line plot of the data in Y versus the corresponding values in X.
and plot(X,Y,LineSpec) in addition "creates the plot using the specified line style, marker, and color." Clicking on LineSpec, we can see in the second table that '.' is one of the markers, with description Point and the resulting marker a black filled dot. So plot(x,y,".") creates a plot with dots as markers at the points specified by the x- and y-coordinates.
We could also try one of the other markers, for eg. plot(x,y,"+") creates this instead:
where if you look carefully, you can see that the points are marked by + signs instead.

Julia LoadError: MethodError: no method matching

I am getting an error while running the following Julia snippet
using GR, Interact
t = 0:0.01:1
#manipulate for phi=0:0.1:6.28
plot(cos.(2π*t+phi))
end
LoadError: MethodError: no method matching +(::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Float64)
Closest candidates are:
+(::Any, ::Any, !Matched::Any, !Matched::Any...) at operators.jl:529
+(!Matched::Bool, ::T<:AbstractFloat) where T<:AbstractFloat at bool.jl:104
+(!Matched::Float64, ::Float64) at float.jl:395
...
in expression starting at C:\Users\W.Aftab\Desktop\Julia_Codes\src\003.jl:3
(::getfield(Main, Symbol("##9#10")))(::Float64) at 003.jl:4
map(::Function, ::Widget{:slider,Float64}) at Observables.jl:174
top-level scope at manipulate.jl:25
Any idea what is wrong?
The following should work better:
using GR, Interact
t = 0:0.01:1
#manipulate for phi=0:0.1:6.28
plot(cos.(2π*t.+phi)) #note the dot in ".+"
end
This is because in that expression, t is a range, and therefore 2pi*t is also a range, because in Julia the product between a scalar and a collection of value is defined to perform the product of each element of the collection by the scalar.
At each iteration in the loop, phi is a scalar. And the operation + is not defined between a scalar and a collection. It has to be explicitly broadcasted, for example using the .+ notation.

Using tuples has keys in Julia without initializing the dictionary

I am new to Julia. For my application I have an expensive operation to calculate a matrix based on two points. Calculated matrices will be used multiple times so I though I would cache them in a dictionary. However, I have encountered a strange behaviour in Julia. If I add a first (key, value) pair as part of the dictionary initialization it all works as expected. However, if I don't, and try and add my first (key, value) pair later, Julia bombs out.
p1 = [ 2.0, 1.0, 1.0]
p2 = [ 4.0, 2.0, 1.0]
# This works
my_dict = Dict{Tuple{Array{Float64,1}, Array{Float64,1}}, String}(
(p1, p2) => "hello world"
)
println(my_dict[(p1, p2)])
# This works
my_dict[ (p2, p1)] = "hello again"
println(my_dict[ (p2, p1)] )
# This doesn't
my_dict2 = Dict{Tuple{Array{Float64,1}, Array{Float64,1}}, String}
my_dict2[(p2, p1)] = "this fails with method dispatch error"
Output from Julia:
julia complex_key_for_dict.jl
hello world
hello again
ERROR: LoadError: MethodError: no method matching setindex!(::Type{Dict{Tuple{Array{Float64,1},Array{Float64,1}},String}}, ::String, ::Tuple{Array{Float64,1},Array{Float64,1}})
Stacktrace:
[1] top-level scope at none:0
[2] include at ./boot.jl:326 [inlined]
[3] include_relative(::Module, ::String) at ./loading.jl:1038
[4] include(::Module, ::String) at ./sysimg.jl:29
[5] exec_options(::Base.JLOptions) at ./client.jl:267
[6] _start() at ./client.jl:436
in expression starting at /home/peter/julia/gps_analysis/complex_key_for_dict.jl:16
For now, I will simply add a fictitious first entry into the dictionary, but would be grateful if someone can put me straight on my error.
Nothing like posting a question to StackOverflow to me make realise what the solution might be. This works:
# This works. Added an open/close bracket to the end of the Dict defintion
my_dict2 = Dict{Tuple{Array{Float64,1}, Array{Float64,1}}, String}()
my_dict2[ (p2, p1)] = "this now works"
println(my_dict2[ (p2, p1)])
Thought I would post the answer so that anyone else who has also banged their head against a brick wall on this may find it helpful.

no method matching in subtraction

I'm using julia 0.5 after run this code :
Freqsample = 100;
second = 4;
step = (Freqsample * second )-1
i get this Error :
MethodError: no method matching getindex(::Int64, ::Colon, ::UnitRange{Int64})
in -(::Int64, ::Int64) at main.jl:12
in include_string(::String, ::String) at loading.jl:441
in eval(::Module, ::Any) at boot.jl:234
in (::Atom.##65#68)() at eval.jl:40
in withpath(::Atom.##65#68, ::Void) at utils.jl:30
in withpath(::Function, ::Void) at eval.jl:46
in macro expansion at eval.jl:109 [inlined]
in (::Atom.##64#67{Dict{String,Any}})() at task.jl:60
Whats wrong with subtracting ? i'm pretty new to julia forgive if its a dumb question
You've redefined - for more types than you probably intended. The second line in the backtrace you posted is telling you that Julia called a - method in main.jl for two integers. And line one is saying that within there it's trying to do something like x[:, 1:5] at line 12, where x is an integer.
This tells me two things;
Your definition of - is probably typed too permissively. You probably didn't intend to accept integers.
You are probably shadowing the built in - definition instead of extending it. You need to import Base: - in order to add a new method to a function in the standard library.

Appending to Vector

I'm having trouble appending to an empty vector in Julia.
v = Int64[]
append!(v,1)
append(v,1)
The append! gives the error
ERROR: `Variable` has no method matching Variable(::Int64, ::Int64, ::Int64, ::Int64)
And append gives the error
ERROR: append not defined
This is probably a basic mistake on my part, but I can't figure out why neither command is working.
If you're appending a scalar value, you want push!. If you're adding a list of elements, then you want append!. There's a good reason for the distinction, as you will probably realize if you consider what should happen if you want to build an array-of-arrays.
Typing ?append! at the REPL will show you help on the function, including a demo on how to use it. (In julia 0.4, the help has been improved and refers you to the push! function as well, but that doesn't seem to have been implemented in the current release.)

Resources