Skip to content

Commit

Permalink
Merge pull request #95 from JuliaDiff/closure-fixes
Browse files Browse the repository at this point in the history
Fix closure-related test breakage
  • Loading branch information
jrevels committed Feb 2, 2016
2 parents 057ab29 + 24d7865 commit 6f04cb7
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 55 deletions.
9 changes: 1 addition & 8 deletions src/api/derivative.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ end
end
end

# The below code generation enables better type inferencing in the event that
# `f` is a type (see https://github.com/JuliaDiff/ForwardDiff.jl/issues/54).
closure_deriv_def = quote
function derivative{A}(f, ::Type{A}=Void; mutates=false)
if mutates
d!(output, x::Number) = ForwardDiff.derivative!(output, f, x, A)
return d!
Expand All @@ -46,8 +44,3 @@ closure_deriv_def = quote
return d
end
end

@eval begin
derivative{A}(f, ::Type{A}=Void; mutates=false) = $closure_deriv_def
derivative{A,f}(::Type{f}, ::Type{A}=Void; mutates=false) = $closure_deriv_def
end
4 changes: 2 additions & 2 deletions src/api/jacobian.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ function jacobian{A}(f, ::Type{A}=Void;
# appropriate closure
if output_length > 0
output_cache = ForwardDiffCache()
function newf{G<:GradientNumber}(x::Vector{G})
output = get_workvec!(output_cache, G, output_length)
newf = (x::Vector) -> begin
output = get_workvec!(output_cache, eltype(x), output_length)
f(output, x)
return output
end
Expand Down
54 changes: 25 additions & 29 deletions test/test_behaviors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,61 +53,57 @@ j = x -> ForwardDiff.jacobian(g, x, chunk_size=2)/2 # jacobian in chunk_mode
# Promote type Issues #
#######################

# Test overloading of `promote_array_type`
#-------------------------------------------------------#
# Test overloading of `promote_array_type` #
#------------------------------------------#

promtyp = Base.promote_array_type(Base.DotAddFun(),
ForwardDiff.ForwardDiffNumber{2, Float64,
Tuple{Float64, Float64}}, Float64)
fdiffnum = ForwardDiff.ForwardDiffNumber{2,Float64,Tuple{Float64,Float64}}
fdiffnum = ForwardDiff.ForwardDiffNumber{2,Float64,Tuple{Float64,Float64}}
@test promtyp <: fdiffnum


promtyp = Base.promote_array_type(Base.DotAddFun(),
ForwardDiff.GradientNumber{2, Float64,
Tuple{Float64, Float64}}, Float64)
gradnum = ForwardDiff.GradientNumber{2,Float64,Tuple{Float64,Float64}}
Tuple{Float64, Float64}}, Float64)
gradnum = ForwardDiff.GradientNumber{2,Float64,Tuple{Float64,Float64}}
@test promtyp <: gradnum

promtyp = Base.promote_array_type(Base.DotAddFun(),
ForwardDiff.HessianNumber{2, Float64,
Tuple{Float64, Float64}}, Float64)
hessnum = ForwardDiff.HessianNumber{2,Float64,Tuple{Float64,Float64}}
Tuple{Float64, Float64}}, Float64)
hessnum = ForwardDiff.HessianNumber{2,Float64,Tuple{Float64,Float64}}
@test promtyp <: hessnum

promtyp = Base.promote_array_type(Base.DotAddFun(),
ForwardDiff.TensorNumber{2, Float64,
Tuple{Float64, Float64}}, Float64)
tensnum = ForwardDiff.TensorNumber{2,Float64,Tuple{Float64,Float64}}
Tuple{Float64, Float64}}, Float64)
tensnum = ForwardDiff.TensorNumber{2,Float64,Tuple{Float64,Float64}}
@test promtyp <: tensnum


# functions involving `.-`, `.+`, etc. #
#-------------------------------------------------------#

a = ones(4)
# Arithmetic element-wise functions #
#-----------------------------------#

## Test jacobian
N = 4
a = ones(N)
jac0 = reshape(vcat([[zeros(N*(i-1)); a; zeros(N^2-N*i)] for i = 1:N]...), N^2, N)

for op = [:-, :+, :./, :.*]
@eval fn(x) = [($op)(x[1], a); ($op)(x[2], a); ($op)(x[3], a); ($op)(x[4], a)]
jac = ForwardDiff.jacobian(fn, a)
for op in (-, +, .-, .+, ./, .*)

f = x -> [op(x[1], a); op(x[2], a); op(x[3], a); op(x[4], a)]

# jacobian
jac = ForwardDiff.jacobian(f, a)
@test reduce(&, -jac + jac0 .== 0)
end

## Test hessian
for op = [:-, :+, :./, :.*]
@eval fn(x) = sum([($op)(x[1], a); ($op)(x[2], a); ($op)(x[3], a); ($op)(x[4], a)])
hess = ForwardDiff.hessian(fn, a)
f = x -> sum([op(x[1], a); op(x[2], a); op(x[3], a); op(x[4], a)])

# hessian
hess = ForwardDiff.hessian(f, a)
@test reduce(&, -hess + zeros(N, N) .== 0)
end

## Test tensor
for op = [:-, :+, :./, :.*]
@eval fn(x) = sum([($op)(x[1], a); ($op)(x[2], a); ($op)(x[3], a); ($op)(x[4], a)])
tens = ForwardDiff.tensor(fn, a)
# tensor
tens = ForwardDiff.tensor(f, a)
@test reduce(&, -tens + zeros(N, N, N) .== 0)
end


10 changes: 5 additions & 5 deletions test/test_deprecated.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
T = Float64
dummy_fsym = :sin
testexpr = :(sin(a) + exp(b) - tan(c) * cos(d))
testexpr = :(sin(a) + exp(b) - tan(c) * cos(d))

@eval function testf(x::Vector)
testf = @eval (x::Vector) -> begin
a,b,c,d = x
return $testexpr
end
Expand Down Expand Up @@ -31,7 +31,7 @@ testout = Array(T, M, N)
testexpr_jac = [:(sin(a) + cos(b)), :(-tan(c)), :(4 * exp(d)), :(cos(b)^5), :(sin(a))]
testresult = jacob_test_result(testexpr_jac, testx)

@eval function jactestf(x::Vector)
jactestf = @eval (x::Vector) -> begin
a,b,c,d = x
return [$(testexpr_jac...)]
end
Expand All @@ -49,10 +49,10 @@ jacf = forwarddiff_jacobian(jactestf, T)
N = 6
testx = hess_test_x(dummy_fsym, N)
testout = Array(T, N, N)
testexpr_hess = :(sin(a) + exp(b) - tan(c) * cos(l) + sin(m) * exp(r))
testexpr_hess = :(sin(a) + exp(b) - tan(c) * cos(l) + sin(m) * exp(r))
testresult = hess_test_result(testexpr_hess, testx)

@eval function hess_testf(x::Vector)
hess_testf = @eval (x::Vector) -> begin
a,b,c,l,m,r = x
return $testexpr_hess
end
Expand Down
4 changes: 2 additions & 2 deletions test/test_derivatives.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ end
for fsym in ForwardDiff.auto_defined_unary_funcs
func_expr = :($(fsym)(x) + 4^$(fsym)(x) - x * $(fsym)(x))
deriv = Calculus.differentiate(func_expr)
try
@eval begin
try
@eval begin
x = deriv_test_x($fsym)
testdf = x -> $func_expr
val_result = testdf(x)
Expand Down
2 changes: 1 addition & 1 deletion test/test_gradients.jl
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ chunk_sizes = (ForwardDiff.default_chunk_size, 1, Int(N/2), N)
for fsym in map(first, Calculus.symbolic_derivatives_1arg())
testexpr = :($(fsym)(a) + $(fsym)(b) - $(fsym)(c) * $(fsym)(d))

@eval function testf(x::Vector)
testf = @eval (x::Vector) -> begin
a,b,c,d = x
return $testexpr
end
Expand Down
2 changes: 1 addition & 1 deletion test/test_hessians.jl
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ chunk_sizes = (ForwardDiff.default_chunk_size, 2, Int(N/2), N)
for fsym in ForwardDiff.auto_defined_unary_hess_funcs
testexpr = :($(fsym)(a) + $(fsym)(b) - $(fsym)(c) * $(fsym)(l) - $(fsym)(m) + $(fsym)(r))

@eval function testf(x::Vector)
testf = @eval (x::Vector) -> begin
a,b,c,l,m,r = x
return $testexpr
end
Expand Down
10 changes: 5 additions & 5 deletions test/test_jacobians.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ for fsym in ForwardDiff.auto_defined_unary_funcs
:($(fsym)(b)^5),
:($(fsym)(a))]

@eval function testf(x::Vector)
testf = @eval (x::Vector) -> begin
a,b,c,d = x
return [$(testexprs...)]
end

@eval function testf!(output::Vector, x::Vector)
testf! = @eval (output::Vector, x::Vector) -> begin
a,b,c,d = x
output[1] = $(testexprs[1])
output[2] = $(testexprs[2])
Expand All @@ -59,15 +59,15 @@ for fsym in ForwardDiff.auto_defined_unary_funcs
testx = jacob_test_x(fsym, N)
val_result = testf(testx)
jacob_result = jacob_test_result(testexprs, testx)

# Non-AllResults
test_jacob = (testout) -> @test_approx_eq testout jacob_result

ForwardDiff.jacobian!(testout, testf, testx; chunk_size=chunk)
test_jacob(testout)

test_jacob(ForwardDiff.jacobian(testf, testx; chunk_size=chunk))

jacf! = ForwardDiff.jacobian(testf; mutates=true, chunk_size=chunk)
testout = similar(testout)
jacf!(testout, testx)
Expand Down Expand Up @@ -123,4 +123,4 @@ for fsym in ForwardDiff.auto_defined_unary_funcs
throw(err)
end
end
end
end
4 changes: 2 additions & 2 deletions test/test_tensors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ rand_tens = TensorNumber(rand_hess, rand_tensvec)
# Multiplication/Division #
#-------------------------#
function tens_approx_eq(a::TensorNumber, b::TensorNumber)
eps = 1e-9
eps = 1e-8
try
@test_approx_eq_eps value(a) value(b) eps
@test_approx_eq_eps collect(grad(a)) collect(grad(b)) eps
Expand Down Expand Up @@ -285,7 +285,7 @@ end
for fsym in ForwardDiff.auto_defined_unary_tens_funcs
testexpr = :($(fsym)(a) + $(fsym)(b) - $(fsym)(c) * $(fsym)(d))

@eval function testf(x::Vector)
testf = @eval (x::Vector) -> begin
a,b,c,d = x
return $testexpr
end
Expand Down

0 comments on commit 6f04cb7

Please sign in to comment.