MethodError: Cannot `convert` an object of type Array{Float64,1} to an object of type SentinelArrays.ChainedVector{Float64,Array{Float64,1}} - julia

I ran the following loop:
for k in N
Load_dict[k] = fill(0.0,8760)
end
and got the error specified in the title.
Type of N is Array{Symbol,1}, load_dict[k] is SentinelArrays.ChainedVector{Float64,Array{Float64,1}} and fill(0.0, 8760) generates arrays of Array{Float64,1}.
Can Array{Float64,1} be converted to SentinelArrays.ChainedVector{Float64,Array{Float64,1}}? Or is there a way to generate SentinelArrays.ChainedVector{Float64,Array{Float64,1}} arrays, directly?
Thanks!

Currently an appropriate convert method is undefined so you need to use a constructor:
Load_dict[k] = ChainedVector([fill(0.0, 8760)])
However, it seems that the eltype of your Load_dict is overly narrow (unless you really know what you are doing and why you need a collection of ChainedVector).

Related

Plotting an float array in 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.

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.

Julia what does a nameless value in the function header mean?

I often see something like the following in Julia:
convert(::Type{Point{Float64}}, ::Float64)
how does the (:: work? And what is the terminology for this?
Your answer can be found in the Julia documentation for defining conversions. To quote (with types switched to make it even more straightforward to read):
The type of the first argument of this method is a singleton
type, Type{Point{Float64}}, the only instance of which is
Point{Float64}. Thus, this method is only invoked when the first
argument is the type value Point{Float64}. Notice the syntax used
for the first argument: the argument name is omitted prior to the ::
symbol, and only the type is given. This is the syntax in Julia for a
function argument whose type is specified but whose value is never
used in the function body. In this example, since the type is a
singleton, there would never be any reason to use its value within the
body.
(Emphasis mine)
You will also encounter the foo(::SomeType) syntax in error messages, when trying to invoke a function with arguments of the wrong type (after all you can't show the argument names of a variant that does not exist). E.g:
julia> foo(x::Bool) = 3
foo (generic function with 1 method)
julia> foo(5)
ERROR: `foo` has no method matching foo(::Int64)

How to create an object like `()` in user space

In Julia the empty tuple is both a type and an instance of that type. So isa((),()) is true. Is it possible to create a similar object myself?
I don't believe so. In fact, in Julia 0.4 isa((),()) is no longer true. The type of () is now Tuple{}:
julia> VERSION
v"0.4.0-dev+5441"
julia> typeof(())
Tuple{}
julia> isa((),()) # Throws an error since () is no longer considered a Type
ERROR: TypeError: isa: expected Type{T}, got Tuple{}
I think the only remaining objects that are an instance of themselves are Any, Type and DataType.

How to display a type alias instead of a parametric type in error messages

I build a parametric type in julia:
type MyType{T}
x::T
end
and for simplicity, I build a type alias for Float64:
typealias MT MyType{Float64}
I now deliberately cause an error involving MT. For example:
y1 = MyType(1.0)
y2 = MyType(2.0)
y1 + y2
will throw an error because + is not defined for MyType. The error message says:
`+` has no method matching +(::MyType{Float64}, ::MyType{Float64})
I would like it to say:
`+` has no method matching +(::MT, ::MT)
Why? Because real-world examples sometimes get quite a bit more complicated than this toy example, and one purpose of a type alias is to make a complicated specific instance of a parametric type easily recognisable. So it would be nice to also make it easily recognisable in error messages.
What have I tried? My best guess is that the error function calls the string function over a DataType in order to generate the appropriate strings in the error message. So it isn't obvious to me that I can extend the string function via multiple dispatch to specialise on my type alias, so I'm pretty much at a loss about where to go from here.
You need to define an appropriate show method:
import Base.show
show(io::IO, ::Type{MT}) = print(io, "MT")
Your example then gives:
julia> y1 + y2
ERROR: `+` has no method matching +(::MT, ::MT)

Resources