Skip to content

Commit

Permalink
Don't check previous x's if you're not going to update the values! (#95)
Browse files Browse the repository at this point in the history
* Don't check previous x's if you're not going to update the values!

* fix tests and default chunk
  • Loading branch information
pkofod authored Dec 20, 2018
1 parent 095b2b2 commit 12ceb15
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 44 deletions.
38 changes: 13 additions & 25 deletions src/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,8 @@ Evaluates the objective value at `x`.
Returns `f(x)`, but does *not* store the value in `obj.F`
"""
function value(obj::AbstractObjective, x)
if x != obj.x_f
obj.f_calls .+= 1
return obj.f(x)
end
value(obj)
obj.f_calls .+= 1
return obj.f(x)
end
"""
Evaluates the objective value at `x`.
Expand All @@ -39,13 +36,10 @@ Evaluates the gradient value at `x`
This does *not* update `obj.DF` or `obj.x_df`.
"""
function gradient(obj::AbstractObjective, x)
if x != obj.x_df
newdf = copy(obj.DF)
obj.df(newdf, x)
obj.df_calls .+= 1
return newdf
end
gradient(obj)
newdf = copy(obj.DF)
obj.df(newdf, x)
obj.df_calls .+= 1
return newdf
end
"""
Evaluates the gradient value at `x`.
Expand Down Expand Up @@ -152,24 +146,18 @@ function jacobian!!(obj, J, x)
J
end
function jacobian(obj::AbstractObjective, x)
if x != obj.x_df
tmp = copy(obj.DF)
jacobian!!(obj, x)
newdf = copy(obj.DF)
copyto!(obj.DF, tmp)
return newdf
end
obj.DF
tmp = copy(obj.DF)
jacobian!!(obj, x)
newdf = copy(obj.DF)
copyto!(obj.DF, tmp)
return newdf
end

value(obj::NonDifferentiable{TF, TX}, x) where {TF<:AbstractArray, TX} = value(obj, copy(obj.F), x)
value(obj::OnceDifferentiable{TF, TDF, TX}, x) where {TF<:AbstractArray, TDF, TX} = value(obj, copy(obj.F), x)
function value(obj::AbstractObjective, F, x)
if x != obj.x_f
obj.f_calls .+= 1
return obj.f(F, x)
end
value(obj)
obj.f_calls .+= 1
return obj.f(F, x)
end

value!!(obj::NonDifferentiable{TF, TX}, x) where {TF<:AbstractArray, TX} = value!!(obj, obj.F, x)
Expand Down
13 changes: 9 additions & 4 deletions src/objective_types/constraints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,18 @@ function OnceDifferentiableConstraints(bounds::ConstraintBounds)
OnceDifferentiableConstraints(c!, J!, bounds)
end

function OnceDifferentiableConstraints(c!, lx::AbstractVector, ux::AbstractVector,
lc::AbstractVector, uc::AbstractVector,
autodiff::Symbol = :central,
chunk::ForwardDiff.Chunk = ForwardDiff.Chunk(lx))
function checked_chunk(lx)
if isempty(lx)
throw(ArgumentError("autodiff on constraints require the full lower bound vector `lx`."))
end
ForwardDiff.Chunk(lx)
end

function OnceDifferentiableConstraints(c!, lx::AbstractVector, ux::AbstractVector,
lc::AbstractVector, uc::AbstractVector,
autodiff::Symbol = :central,
chunk::ForwardDiff.Chunk = checked_chunk(lx))

bounds = ConstraintBounds(lx, ux, lc, uc)
T = eltype(bounds)
sizex = size(lx)
Expand Down
30 changes: 15 additions & 15 deletions test/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
@test hessian(td) == h_x_seed

# Test that the call counters got incremented
@test nd.f_calls == od.f_calls == td.f_calls == [1]
@test nd.f_calls == od.f_calls == td.f_calls == [2]
@test od.df_calls == td.df_calls == [1]
@test td.h_calls == [1]

Expand All @@ -45,7 +45,7 @@
value_gradient!(td, x_seed)
hessian!(td, x_seed)

@test nd.f_calls == od.f_calls == td.f_calls == [1]
@test nd.f_calls == od.f_calls == td.f_calls == [2]
@test od.df_calls == td.df_calls == [1]
@test td.h_calls == [1]

Expand All @@ -55,7 +55,7 @@
value_gradient!!(td, x_seed)
hessian!!(td, x_seed)

@test nd.f_calls == od.f_calls == td.f_calls == [2]
@test nd.f_calls == od.f_calls == td.f_calls == [3]
@test od.df_calls == td.df_calls == [2]
@test td.h_calls == [2]

Expand All @@ -68,7 +68,7 @@
@test gradient(td) == g_x_alt
@test gradient(td) == [gradient(td, i) for i = 1:length(x_seed)]
@test hessian(td) == h_x_seed
@test nd.f_calls == od.f_calls == td.f_calls == [2]
@test nd.f_calls == od.f_calls == td.f_calls == [3]
@test od.df_calls == td.df_calls == [3]
@test td.h_calls == [2]

Expand All @@ -79,7 +79,7 @@
@test value(nd) == value(od) == value(td) == f_x_seed
@test gradient(td) == g_x_alt
@test hessian(td) == h_x_alt
@test nd.f_calls == od.f_calls == td.f_calls == [2]
@test nd.f_calls == od.f_calls == td.f_calls == [3]
@test od.df_calls == td.df_calls == [3]
@test td.h_calls == [3]

Expand All @@ -89,7 +89,7 @@
@test value(nd) == value(od) == value(td) == f_x_alt
@test gradient(td) == g_x_alt
@test hessian(td) == h_x_alt
@test nd.f_calls == od.f_calls == td.f_calls == [3]
@test nd.f_calls == od.f_calls == td.f_calls == [4]
@test od.df_calls == td.df_calls == [3]
@test td.h_calls == [3]

Expand All @@ -114,7 +114,7 @@
@test value(od) == value(td) == f_x_seed
@test gradient(td) == g_x_seed
@test hessian(td) == h_x_alt
@test od.f_calls == td.f_calls == [4]
@test od.f_calls == td.f_calls == [5]
@test od.df_calls == td.df_calls == [4]
@test td.h_calls == [3]

Expand Down Expand Up @@ -229,22 +229,22 @@
@test jacobian(od) == J_x_seed

# Test that the call counters got incremented
@test nd.f_calls == od.f_calls == [2]
@test nd.f_calls == od.f_calls == [3]
@test od.df_calls == [1]

# Test that the call counters do not get incremented
# with single-"bang" methods...
value!(nd, x_seed)
value_jacobian!(od, x_seed)

@test nd.f_calls == od.f_calls == [2]
@test nd.f_calls == od.f_calls == [3]
@test od.df_calls == [1]

# ... and that they do with double-"bang" methods
value!!(nd, x_seed)
value_jacobian!!(od, x_seed)

@test nd.f_calls == od.f_calls == [3]
@test nd.f_calls == od.f_calls == [4]
@test od.df_calls == [2]

# Test that jacobian doesn't work for NonDifferentiable, but does otherwise
Expand All @@ -253,19 +253,19 @@

@test value(nd) == value(od) == F_x_seed
@test jacobian(od) == J_x_alt
@test nd.f_calls == od.f_calls == [3]
@test nd.f_calls == od.f_calls == [4]
@test od.df_calls == [3]

@test value(nd) == value(od) == F_x_seed
@test jacobian(od) == J_x_alt
@test nd.f_calls == od.f_calls == [3]
@test nd.f_calls == od.f_calls == [4]
@test od.df_calls == [3]

value!(nd, x_alt)
value!(od, x_alt)
@test value(nd) == value(od) == F_x_alt
@test jacobian(od) == J_x_alt
@test nd.f_calls == od.f_calls == [4]
@test nd.f_calls == od.f_calls == [5]
@test od.df_calls == [3]

@test_throws ErrorException value_jacobian!(nd, x_seed)
Expand All @@ -282,7 +282,7 @@
value_jacobian!(od, x_seed)
@test value(od) == F_x_seed
@test jacobian(od) == J_x_seed
@test od.f_calls == [5]
@test od.f_calls == [6]
@test od.df_calls == [4]

clear!(nd)
Expand Down Expand Up @@ -311,4 +311,4 @@
@test xxx3 == od.x_df

end
end
end

0 comments on commit 12ceb15

Please sign in to comment.