Hello, I’m trying to write a solver library for a very specific machine learning problem and I have a function that errors in runtime and I really don’t understand what exactly is wrong.
In particular, the function that errors is:
function risk(S::Vector{Sample}, γ::Vector{Function})
return ( S .|> (s -> loss(s, γ)) |> sum ) / size(S)[1]
end
Where:
function loss(s::Sample, γ::Vector{Function})
v = collect(Iterators.flatten([g(y) for (g, y) in zip(γ, s.Y)]))
return real(dot(v, s.R * v) + 2 * real(dot(v, s.r)) + s.c)
end
And Sample is defined as:
struct Sample{T <: Number}
Y::Vector{Vector{T}}
R::Matrix{T}
r::Vector{T}
c::T
end
The error I get reads:
MethodError: no method matching risk(::Vector{Sample{Float64}}, ::Vector{Function})
Closest candidates are:
risk(!Matched::Vector{Sample}, ::Vector{Function})
This doesn’t make sense to me, as Vector{Sample{Float64}} is a subtype of Vector{Sample}. Moreover calling loss
on a single sample works just fine. Additionally, calling risk(Vector{Sample}(S), \gamma} also works, which is honestly baffling, as I am essentially casting to a more generic type.
Also, I am declaring Sample as parametrised by a Number
since I need to handle both real and complex valued samples.
I feel that intuitively, there’s nothing wrong with my code, after all, Julia main advertised feature is multiple dispatch, i.e the ability to write generic functions and structs. But then again, I am pretty new to the language, so I must be missing a piece of the puzzle here.