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.
Related
I am having some issues understanding the concept of parametric constructors in Julia. I am looking at the standard example in the Julia docs:
struct Point{T<:Real}
x::T
y::T
end
To my understanding, this means I can generate a Point-datatype with an input that is subtype of Real, i.e., AbstractFloat, AbstractIrrational, ..., Integer, Rational, ..., StatsBase.TestStat.
However, both of the examples below result in errors:
Point(Integer(12))
Point(Rational(12))
Why does the above fail given that both integer and rational are subtypes of real?
The type parameter goes inside the curly braces in the constructor call, just like it does in the struct definition:
julia> Point{Integer}(12, 12)
Point{Integer}(12, 12)
julia> Point{Rational}(12, 10//3)
Point{Rational}(12//1, 10//3)
The arguments supplied are the values for the fields of the struct i.e. x and y. If the arguments are already of the type you want, you can leave out explicitly specifying the type parameter:
julia> Point(12, 6)
Point{Int64}(12, 6)
julia> Point(12.0, 6.0)
Point{Float64}(12.0, 6.0)
julia> Point(12, 6.0) #no automatic type promotion happens though
ERROR: MethodError: no method matching Point(::Int64, ::Float64)
Closest candidates are:
Point(::T, ::T) where T<:Real at REPL[1]:2
Stacktrace:
[1] top-level scope
# REPL[9]:1
julia> Point{Float64}(12, 6.0) #unless you explicitly specify the type
Point{Float64}(12.0, 6.0)
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.
Is it possible to type function kwargs in Julia?
The following works for standard Varargs.
function int_args(args::Integer...)
args
end
int_args(1, 2, 3)
# (1, 2, 3)
int_args(1, 2, 3.0)
# ERROR: MethodError: `int_args` has no method matching int_args(::Int64, ::Int64, ::Float64)
However, when applying this same syntax to kwargs, all function calls seem to error.
function int_kwargs(; kwargs::Integer...)
kwargs
end
int_kwargs(x=1, y=2)
# ERROR: MethodError: `__int_kwargs#0__` has no method matching __int_kwargs#0__(::Array{Any,1})
Normal keyword arguments can have types, as in function f(x; a::Int=0), but this doesn't work for "rest" keyword arguments. Also note that since we currently don't dispatch on keyword arguments, the a::Int in this case is a type assertion and not a dispatch specification.
It looks like this case is not handled well, and needs a better error message at least. I'd encourage you to file an issue at https://github.com/JuliaLang/julia/issues.
I'm not sure what the syntax x::T... should mean for keyword arguments. In the case of varargs, it's clear that each element of x should have type T, but for rest keyword arguments each element is actually a symbol-value pair. Of course we could give it the meaning you describe (all values have type T), but this doesn't seem to come up very often. Keyword arguments tend to be quite heterogeneous, unlike varargs which are more like lists or arrays.
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.
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)