Skip to content

Commit

Permalink
upgrade to ForwardDiff v0.5.0 (#42)
Browse files Browse the repository at this point in the history
* upgrade to ForwardDiff v0.5.0

* fix Julia/Travis versions in REQUIRE

* fix DualNumbers.Dual constructors in tests

* upper-bound ForwardDiff at next minor version just to be safe
  • Loading branch information
jrevels authored and mlubin committed Jun 15, 2017
1 parent 7e4c4af commit 3ffc785
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 19 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ os:
- linux
- osx
julia:
- 0.5
- 0.6
- nightly
notifications:
Expand Down
4 changes: 2 additions & 2 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
julia 0.5
julia 0.6.0-rc
Calculus
DataStructures
MathProgBase
NaNMath 0.2.1
ForwardDiff 0.3 0.5
ForwardDiff 0.5 0.6
3 changes: 3 additions & 0 deletions src/ReverseDiffSparse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ using Base.Meta
using ForwardDiff
import Calculus
import MathProgBase

const TAG = :rds_tag

# Override basic math functions to return NaN instead of throwing errors.
# This is what NLP solvers expect, and
# sometimes the results aren't needed anyway,
Expand Down
20 changes: 10 additions & 10 deletions src/forward.jl
Original file line number Diff line number Diff line change
Expand Up @@ -250,31 +250,31 @@ function forward_eval_ϵ{N,T}(storage::Vector{T},storage_ϵ::DenseVector{Forward
if op == 3 # :*
# Lazy approach for now
anyzero = false
tmp_prod = one(ForwardDiff.Dual{N,T})
tmp_prod = one(ForwardDiff.Dual{TAG,T,N})
for c_idx in children_idx
ix = children_arr[c_idx]
sval = storage[ix]
gnum = ForwardDiff.Dual(sval,storage_ϵ[ix])
gnum = ForwardDiff.Dual{TAG}(sval,storage_ϵ[ix])
tmp_prod *= gnum
anyzero = ifelse(sval*sval == zero(T), true, anyzero)
end
# By a quirk of floating-point numbers, we can have
# anyzero == true && ForwardDiff.value(tmp_prod) != zero(T)
if anyzero # inefficient
for c_idx in children_idx
prod_others = one(ForwardDiff.Dual{N,T})
prod_others = one(ForwardDiff.Dual{TAG,T,N})
for c_idx2 in children_idx
(c_idx == c_idx2) && continue
ix = children_arr[c_idx2]
gnum = ForwardDiff.Dual(storage[ix],storage_ϵ[ix])
gnum = ForwardDiff.Dual{TAG}(storage[ix],storage_ϵ[ix])
prod_others *= gnum
end
partials_storage_ϵ[children_arr[c_idx]] = ForwardDiff.partials(prod_others)
end
else
for c_idx in children_idx
ix = children_arr[c_idx]
prod_others = tmp_prod/ForwardDiff.Dual(storage[ix],storage_ϵ[ix])
prod_others = tmp_prod/ForwardDiff.Dual{TAG}(storage[ix],storage_ϵ[ix])
partials_storage_ϵ[ix] = ForwardDiff.partials(prod_others)
end
end
Expand All @@ -288,14 +288,14 @@ function forward_eval_ϵ{N,T}(storage::Vector{T},storage_ϵ::DenseVector{Forward
@inbounds base_ϵ = storage_ϵ[ix1]
@inbounds exponent = storage[ix2]
@inbounds exponent_ϵ = storage_ϵ[ix2]
base_gnum = ForwardDiff.Dual(base,base_ϵ)
exponent_gnum = ForwardDiff.Dual(exponent,exponent_ϵ)
base_gnum = ForwardDiff.Dual{TAG}(base,base_ϵ)
exponent_gnum = ForwardDiff.Dual{TAG}(exponent,exponent_ϵ)
if exponent == 2
partials_storage_ϵ[ix1] = 2*base_ϵ
else
partials_storage_ϵ[ix1] = ForwardDiff.partials(exponent_gnum*pow(base_gnum,exponent_gnum-1))
end
result_gnum = ForwardDiff.Dual(storage[k],storage_ϵ[k])
result_gnum = ForwardDiff.Dual{TAG}(storage[k],storage_ϵ[k])
partials_storage_ϵ[ix2] = ForwardDiff.partials(result_gnum*log(base_gnum))
elseif op == 5 # :/
@assert n_children == 2
Expand All @@ -307,9 +307,9 @@ function forward_eval_ϵ{N,T}(storage::Vector{T},storage_ϵ::DenseVector{Forward
@inbounds numerator_ϵ = storage_ϵ[ix1]
@inbounds denominator = storage[ix2]
@inbounds denominator_ϵ = storage_ϵ[ix2]
recip_denominator = 1/ForwardDiff.Dual(denominator,denominator_ϵ)
recip_denominator = 1/ForwardDiff.Dual{TAG}(denominator,denominator_ϵ)
partials_storage_ϵ[ix1] = ForwardDiff.partials(recip_denominator)
partials_storage_ϵ[ix2] = ForwardDiff.partials(-ForwardDiff.Dual(numerator,numerator_ϵ)*recip_denominator*recip_denominator)
partials_storage_ϵ[ix2] = ForwardDiff.partials(-ForwardDiff.Dual{TAG}(numerator,numerator_ϵ)*recip_denominator*recip_denominator)
elseif op >= USER_OPERATOR_ID_START
error("User-defined operators not supported for hessian computations")
end
Expand Down
12 changes: 6 additions & 6 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -315,14 +315,14 @@ function dualforward(ex, x; ignore_nan=false)
@test isapprox(fval_ϵ[1], dot(grad,ones(length(x))))

# compare with running dual numbers
forward_dual_storage = zeros(Dual{Float64},length(nd))
partials_dual_storage = zeros(Dual{Float64},length(nd))
output_dual_storage = zeros(Dual{Float64},length(x))
reverse_dual_storage = zeros(Dual{Float64},length(nd))
x_dual = [Dual(x[i],1.0) for i in 1:length(x)]
forward_dual_storage = zeros(DualNumbers.Dual{Float64},length(nd))
partials_dual_storage = zeros(DualNumbers.Dual{Float64},length(nd))
output_dual_storage = zeros(DualNumbers.Dual{Float64},length(x))
reverse_dual_storage = zeros(DualNumbers.Dual{Float64},length(nd))
x_dual = [DualNumbers.Dual(x[i],1.0) for i in 1:length(x)]
fval = forward_eval(forward_dual_storage,partials_dual_storage,nd,adj,const_values,[],x_dual,[])
reverse_eval(reverse_dual_storage,partials_dual_storage,nd,adj)
reverse_extract(output_dual_storage,reverse_dual_storage,nd,adj,[],Dual(2.0))
reverse_extract(output_dual_storage,reverse_dual_storage,nd,adj,[],DualNumbers.Dual(2.0))
for k in 1:length(nd)
@test isapprox(epsilon(forward_dual_storage[k]), forward_storage_ϵ[k][1])
if !(isnan(epsilon(partials_dual_storage[k])) && ignore_nan)
Expand Down

0 comments on commit 3ffc785

Please sign in to comment.