Is there an autodiff package that is compatible?
timholy opened this issue · comments
I'd like to compute up to third-order derivatives with respect to a scalar (non-measurement) of a measurement-valued function. Something along the lines of this demo:
julia> using Measurements
julia> c, w = π/4, 0.1 # could alternatively be AbstractVectors
(0.7853981633974483, 0.1)
julia> f = sin # could be anything
sin (generic function with 15 methods)
julia> ϕ(t) = f(c ± (1 + t)*w) # evaluates f over a Measurement
ϕ (generic function with 1 method)
julia> ϕ(0.1)
0.707 ± 0.078
I've tried ForwardDiff (I saw #100):
julia> using ForwardDiff
julia> ForwardDiff.derivative(ϕ, 0.0)
ERROR: StackOverflowError:
Stacktrace:
[1] measurement(val::ForwardDiff.Dual{ForwardDiff.Tag{typeof(ϕ), Float64}, Float64, 1}, err::ForwardDiff.Dual{ForwardDiff.Tag{typeof(ϕ), Float64}, Float64, 1}) (repeats 79984 times)
@ Measurements ~/.julia/packages/Measurements/hcRfF/src/Measurements.jl:93
and TaylorDiff:
julia> TaylorDiff.derivative(ϕ, 0.0, 1)
ERROR: MethodError: no method matching measurement(::Float64, ::TaylorScalar{Float64, 2})
Closest candidates are:
measurement(::T) where T<:AbstractFloat
@ Measurements ~/.julia/packages/Measurements/hcRfF/src/Measurements.jl:82
measurement(::Real)
@ Measurements ~/.julia/packages/Measurements/hcRfF/src/Measurements.jl:83
measurement(::T, ::T) where T<:AbstractFloat
@ Measurements ~/.julia/packages/Measurements/hcRfF/src/Measurements.jl:84
...
Stacktrace:
[1] ϕ(t::TaylorScalar{Float64, 2})
@ Main ./REPL[100]:1
[2] derivative(f::typeof(ϕ), x::Float64, ::Val{2})
@ TaylorDiff ~/.julia/packages/TaylorDiff/zNnz2/src/derivative.jl:28
[3] derivative(f::Function, x::Float64, order::Int64)
@ TaylorDiff ~/.julia/packages/TaylorDiff/zNnz2/src/derivative.jl:18
[4] top-level scope
@ REPL[107]:1
and TaylorSeries:
julia> using TaylorSeries
WARNING: using TaylorSeries.derivative in module Main conflicts with an existing identifier.
julia> tt = Taylor1(3)
1.0 t + 𝒪(t⁴)
julia> ϕ(0.0 + tt)
ERROR: MethodError: no method matching measurement(::Float64, ::Taylor1{Float64})
Closest candidates are:
measurement(::T) where T<:AbstractFloat
@ Measurements ~/.julia/packages/Measurements/hcRfF/src/Measurements.jl:82
measurement(::Real)
@ Measurements ~/.julia/packages/Measurements/hcRfF/src/Measurements.jl:83
measurement(::T, ::T) where T<:AbstractFloat
@ Measurements ~/.julia/packages/Measurements/hcRfF/src/Measurements.jl:84
...
Stacktrace:
[1] ϕ(t::Taylor1{Float64})
@ Main ./REPL[100]:1
[2] top-level scope
@ REPL[111]:1
I haven't yet tried Diffractor (the docs are not fully fleshed out).
can you try with ForwardDiffOverMeasurements.jl? (adds ForwardDiff overloads to measurements)
With that example, I still get
julia> ForwardDiff.derivative(ϕ, 0.0)
ERROR: StackOverflowError:
Stacktrace:
[1] measurement(val::ForwardDiff.Dual{…}, err::ForwardDiff.Dual{…}) (repeats 79984 times)
@ Measurements ~/.julia/packages/Measurements/hcRfF/src/Measurements.jl:93
Some type information was truncated. Use `show(err)` to see complete types.
This is with Measurements 2.10.0, ForwardDiff 0.10.36, and ForwardDiffOverMeasurements 0.1.0. Might the difference from the examples you show is that the variable I'm differentiating is a mapping Float64 -> Measurement{Float64}
rather than a Measurement{Float64} -> Measurement{Float64}
?
A method measurement(val, err::Dual{T, V})::Dual{T, Measurement{T}}
is needed.