Closed
Description
There are already a few issues talking about #481 (#606, #607) and related problems (#480). I've been running into breakage hinted at in this comment and this workaround where
julia> x, y = 1, ForwardDiff.Dual(1,1);
julia> x < y || x > y || x == y
false
julia> x >= y && x <= y
true
This seems to be an issue for piecewise functions and wrapper types that assume x <= y
is equivalent to x == y || x < y
.
For example, something like this previously worked:
import ForwardDiff
struct WrappedNumber{T<:Number}
value::T
end
for op in (:isless, :(==))
@eval begin
Base.$op(x::WrappedNumber, y::WrappedNumber) = ($op)(x.value, y.value)
Base.$op(x::Number, y::WrappedNumber) = ($op)(x, y.value)
Base.$op(x::WrappedNumber, y::Number) = ($op)(x.value, y)
end
end
for op in (:*, :+, :-)
@eval begin
Base.$op(x::WrappedNumber, y::WrappedNumber) = WrappedNumber(($op)(x.value, y.value))
Base.$op(x::Number, y::WrappedNumber) = WrappedNumber(($op)(x, y.value))
Base.$op(x::WrappedNumber, y::Number) = WrappedNumber(($op)(x.value, y))
end
end
function f_piecewise(x)
lb = WrappedNumber(0.0)
ub = WrappedNumber(1.0)
(lb <= x < ub) && return 0.5*x*x
x >= ub && return 0.5*ub*ub + (x - ub)
return 0.0*x
end
function ForwardDiff.derivative(f, x::WrappedNumber{T}) where T
r = f(WrappedNumber(ForwardDiff.Dual(x.value, one(T))))
return ForwardDiff.partials(r.value)[1]
end
And now:
julia> ForwardDiff.derivative(f_piecewise, WrappedNumber(0.99))
0.99
julia> ForwardDiff.derivative(f_piecewise, WrappedNumber(1.01))
1.0
julia> ForwardDiff.derivative(f_piecewise, WrappedNumber(1.0))
0.0 # Used to be 1.0
Maybe I'm not supposed to do this. But it's been very convenient, and I suspect this isn't the only case with problems of this kind. Or maybe the issue is just a matter of following through on the changes to ==
and isequal
for other comparisons?
Metadata
Metadata
Assignees
Labels
No labels