Plotting an float array in julia - julia

I have the following code
using Plots
function test()::nothing
A::Array{Float64,1} = rand(Float64,100)
plot(A)
end
Which I run in julia like this
julia> include("main.jl")
test (generic function with 1 method)
julia> test()
ERROR: MethodError: First argument to `convert` must be a Type, got nothing
Stacktrace:
[1] test() at /path/to/main.jl:85
[2] top-level scope at REPL[2]:1
Why do I get the error First argument to convert must be a Type, got nothing ?

Well, this problem is related to the fact that you were using nothing in annotation, but correct type is Nothing (note capital N). nothing is an object, Nothing is a type of this object.
So you should use something like
function test()::Nothing
A::Array{Float64,1} = rand(Float64, 100)
display(plot(A))
nothing
end
Note, that I had to add nothing as return value and explicit display to show actual plot.
But, to be honest, main problem is not the Nothing, but overspecialization. Type annotations in functions do not speed up calculations, you should use them only when they are really needed, for example in multiple dispatch.
Idiomatic code looks like this
function test()
A = rand(100)
plot(A)
end
Note, that I removed all extra annotations and unnecessary Float64 in rand, since it is default value.

Related

Julia: Even-number datatype for functions

I have about 50 functions which should consume only even positive numbers. Right now I am checking each time with an "if" whether the number put in is zero or not:
function grof(x::Int)
if (x % 2) == 0
println("good")
else
throw("x is not an even number!!!!!!!!!!!!! Stupid programmer!")
end
end
Ideally, I would like to have a datatype which produces this automatically, i.e.
function grof(x::EvenInt)
println("good")
end
However, I am not able to produce this datatype by my own since I am unable to understand the documentary. Thanks for your help!
Best, v.
I don't think creating a type is warranted in such a situation: I would simply #assert that the condition is verified at the beginning of the function(s). (Funnily enough, checking the whether a number is even is the example that was chosen in the documentation to illustrate the effect of #assert)
For example:
julia> function grof(x::Int)
#assert iseven(x) "Stupid programmer!"
println("good")
end
grof (generic function with 1 method)
julia> grof(2)
good
julia> grof(3)
ERROR: AssertionError: Stupid programmer!
Stacktrace:
[1] grof(::Int64) at ./REPL[5]:2
[2] top-level scope at REPL[7]:1
EDIT: If you really want to create a type enforcing such a constraint, it is possible. The way to do this would be to
create a type (possibly subtyping one of the Number abstract types; maybe Signed)
define an inner constructor ensuring that such a type cannot hold an odd value
A very simple example to build upon would be along the lines of:
# A wrapper around an even integer value
struct EvenInt
val :: Int
# inner constructor
function EvenInt(val)
#assert iseven(val)
new(val)
end
end
# Accessor to the value of an EvenInt
val(x::EvenInt) = x.val
# A method working only on even numbers
grof(x::EvenInt) = println("good: $(val(x)) is even")
You'd use this like so:
julia> x = EvenInt(42)
EvenInt(42)
julia> grof(x)
good: 42 is even
julia> y = EvenInt(1)
ERROR: AssertionError: iseven(val)
Stacktrace:
[1] EvenInt(::Int64) at ./REPL[1]:5
[2] top-level scope at REPL[6]:1
but note that you can't do anything on EvenInts yet: you need to either unwrap them (using val() in this case), or define operations on them (a task which can be vastly simplified if you make EvenInt a subtype of one of the abstract number types and follow the relevant interface).
All integers multiplied by two are even, so redefine your function to take half the number it currently takes.
function grof2(halfx::Int)
x=2*halfx
println("good")
end

Julia Error - Constructor not found when defined

Copied this into a jupyter notebook cell but can't get it to run and the message doesn't really help. Everything looks right.
mutable struct CircularArray{T} <: AbstractArray{T,1}
data::Array{T,1}
first::Int
CircularArray{T}(length::Int) where {T} = new{T}(Array{T, 1}(undef, length), 1)
end
a = CircularArray(10)
MethodError: no method matching CircularArray(::Int64)
I think the error is clear: you need to define CircularArray(length::Int). What you implemented, however, is a parametric constructor. To call your parametric constructor, you need to pass the parameter T with your constructor call, e.g.
a = CircularArray{Float64}(10);
You can also implement non-parametric constructor for a default type of your choice. For example;
CircularArray(length::Int) = CircularArray{Float64}(length)
After this your call to this constructor, CircularArray(10);, won't give a MethodError: no method matching CircularArray(::Int64).
Note the ; at the end of the commands. You need to define other methods (like size) for your array type so that display can work. Otherwise, you may get an error in REPL if you omit ; after the evaluations that return a CircularArray.

Call particular method in Julia [duplicate]

The problem is the following:
I have an abstract type MyAbstract and derived composite types MyType1 and MyType2:
abstract type MyAbstract end
struct MyType1 <: MyAbstract
somestuff
end
struct MyType2 <: MyAbstract
someotherstuff
end
I want to specify some general behaviour for objects of type MyAbstract, so I have a function
function dosth(x::MyAbstract)
println(1) # instead of something useful
end
This general behaviour suffices for MyType1 but when dosth is called with an argument of type MyType2, I want some additional things to happen that are specific for MyType2 and, of course, I want to reuse the existing code, so I tried the following, but it did not work:
function dosth(x::MyType2)
dosth(x::MyAbstract)
println(2)
end
x = MyType2("")
dosth(x) # StackOverflowError
This means Julia did not recognize my attempt to treat x like its "supertype" for some time.
Is it possible to call an overloaded function from the overwriting function in Julia? How can I elegantly solve this problem?
You can use the invoke function
function dosth(x::MyType2)
invoke(dosth, Tuple{MyAbstract}, x)
println(2)
end
With the same setup, this gives the follow output instead of a stack overflow:
julia> dosth(x)
1
2
There's a currently internal and experimental macro version of invoke which can be called like this:
function dosth(x::MyType2)
Base.#invoke dosth(x::MyAbstract)
println(2)
end
This makes the calling syntax quite close to what you wrote.

Julia - Array of UTF8 behavior

I encountered a problem which I've solved, but why the solution works doesnt make sense to me
I had a function similar to this one
function testB(a::Array{AbstractString})
println(a)
end
running it like so gave me
testB(convert(Array{UTF8String},["a","b"]))
ERROR: MethodError: `testB` has no method matching
testB(::Array{UTF8String,1})
Note that Im not manually converting to UTF8 in reality, its for demonstration, in reality I have an AbstractString array, but when I fetch elements from it, they become UFT8
My solution reads in short
function testA{T <: AbstractString}(a::Array{T})
println(a)
end
running this method gives
testA(convert(Array{UTF8String},["a","b"]))
UTF8String["a","b"]
Can anyone tell me why testA works but testB doesnt?
Also, is there a name for this {T <: SomeDataType} notation?
While UTF8String is a subtype of AbstractString, Array{UTF8String} is not a subtype of Array{AbstractString} (no covariance). Hence your testB does not work. (But testB(convert(Array{AbstractString},["a","b"])) should work.)
Rationale for why it has to be like this: a function f(x::Vector{AbstractString}) could e.g. push! a new FooString into x (assuming FooString is a subtype of AbstractString). Now if x was in fact a Vector{UTF8String}, that would fail.

Vector{AbstractString} function parameter won't accept Vector{String} input in julia

The following code in Julia:
function foo(a::Vector{AbstractString})
end
foo(["a"])
gives the following error:
ERROR: MethodError: no method matching foo(::Array{String,1})
Closest candidates are:
foo(::Array{AbstractString,1}) at REPL[77]:2
Even though the following code runs, as expected:
function foo(a::Vector{String})
end
foo(["a"])
And further, AbstractString generally matches String as in:
function foo(::AbstractString)
end
foo("a")
How can I call a function with a Vector{AbstractString} parameter if I have String elements?
You need to write the function signature like this:
function foo{S<:AbstractString}(a::Vector{S})
# do stuff
end
On Julia 0.6 and newer, it's also possible to write instead
function foo(a::Vector{<:AbstractString})
# do stuff
end
This is a consequence of parametric type invariance in Julia. See the chapter on types in the manual for more details.

Resources