ForwardDiff.jl icon indicating copy to clipboard operation
ForwardDiff.jl copied to clipboard

no promotion exists for ForwardDiff.Dual{N,T<:Real} and Float64

Open emilemathieu opened this issue 8 years ago • 3 comments

Hi all !

I would like to concatenate a vector of Dual with a Real as the following

T = 1
p = Array{Dual}(N)
k = 2
ps = vcat(p[1:k], T)
# z = rand(Categorical(ps))

Yet I get the error no promotion exists for ForwardDiff.Dual{N,T<:Real} and Float64. Therefore I tried to extends the vcat function:

function Base.vcat{T<:Real}(a::Array{Dual{T}}, x::T)
  N = length(a)
  new_a = Array{Dual}(N+1)
  new_a[1:N] = a
  new_a[N+1] = Dual(x)
  new_a
end

Unfortunatly this does not work. How shall I proceed ?

Thanks for your help, Emile

emilemathieu avatar Nov 06 '17 15:11 emilemathieu

@xukai92 I remember we managed to solve this problem in Turing sometime ago. Could you help Emile out?

yebai avatar Nov 13 '17 14:11 yebai

Yes, this promotion rule isn't defined because there's not really a correct/optimal behavior for this situation, given such a vague type signature. I guess the closest thing to a correct definition would probably be promote_rule(::Type{Dual}, ::Type{V}) where {V<:Real} = Dual{Void,V,0}, but throwing the error is a better idea than defining that promote rule.

What's your use case? Using Dual as an array's element type is almost certainly not what you want - it's too ill-specified to make sense for most use cases that I can think of.

jrevels avatar Nov 13 '17 15:11 jrevels

@yebai We avoided this problem by constructing a new vector of dual from the real parts, which only happens when we need to use the vector in AD:

vi[range[i]] = ForwardDiff.Dual{CHUNKSIZE, Float64}(realpart(vals[i]), SEEDS[dim_count])

@emilemathieu I agree with @jrevels that the correct way of handling it depends on what how the new vector is used. Do you still need the gradient information from the previous vector?

xukai92 avatar Nov 13 '17 22:11 xukai92