Custom types in ForwardDiff

This might be trivial but I am currently fighting with JuMP to accept my quality function for the minimisation procedure. I figured out that my custom type:

struct Position <: FieldVector{3, Float64}
    x::Float64
    y::Float64
    z::Float64
end

is causing this error:

MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{getfield(JuMP, Symbol("##84#86")){KM3NeT.MultiDUMinimiser},Float64},Float64,6})
Closest candidates are:
  Float64(::Real, !Matched::RoundingMode) where T<:AbstractFloat at rounding.jl:194
  Float64(::T<:Number) where T<:Number at boot.jl:741
  Float64(!Matched::Int8) at float.jl:60

when I try to

register(model, :qfunc, 6, m, autodiff=true)
...
...
...
@NLobjective(model, Min, qfunc(x, y, z, θ, ϕ, t₀))
optimize!(model)   # this is the line which fails with the message above

Given the candidates, I guess I have to somehow implement something related to roundings :wink: ? Can someone toss me in the right direction?

I found this discussion but still clueless: https://github.com/JuliaDiffEq/DiffEqBase.jl/issues/169

struct Position{T} <: FieldVector{3, T}
    x::T
    y::T
    z::T
end
1 Like

Thanks Chris, I tried it but I still get the same error :confused:

I just checked, I think it’s caused by this type now (the Position stuff works, and I also added it to Direction):

struct Track
    dir::Direction
    pos::Position
    time::Float64
end

I’ll now try to parametrise that with

  2 struct Track{T}
  1     dir::Direction{T}
89      pos::Position{T}
  1     time::T
  2 end

Any place where you write Float64, replace it with a parameterization.

3 Likes

Makes sense now, thanks :wink:

The problem is, now I destroyed some other calls, namely when I create a track using a standard vector:

MethodError: no method matching KM3NeT.Track(::Array{Float64,1}, ::Array{Float64,1}, ::Float64)
Closest candidates are:
  KM3NeT.Track(!Matched::Direction{T}, !Matched::Position{T}, ::T) where T at /home/tgal/.julia/dev/KM3NeT/src/types.jl:88

I am now lost in parametric hell…

OK, this one works :wink:

struct Track
    dir::Direction
    pos::Position
    time
end

Frequently you need to make the types parametric and allow different types between the fields (ie, you only want dual numbers in one of them).