Skip to content

Commit

Permalink
Remove Uninitialized* functionality, add some tests and fix deprecati…
Browse files Browse the repository at this point in the history
…on bug (value = Inf). (#13)

* Add some tests (all lines are tested now)
* Remove Uninitialized... from Base.
* Fix the deprecation bug.
  • Loading branch information
pkofod committed Jun 7, 2017
1 parent a667b4e commit bce3ec3
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 35 deletions.
4 changes: 2 additions & 2 deletions src/NLSolversBase.jl
Expand Up @@ -5,10 +5,10 @@ module NLSolversBase
using Compat

import Base: gradient
export NonDifferentiable,
export AbstractObjective,
NonDifferentiable,
OnceDifferentiable,
TwiceDifferentiable,
AbstractObjective,
value,
value!,
value_gradient!,
Expand Down
45 changes: 13 additions & 32 deletions src/objective_types.jl
Expand Up @@ -18,12 +18,8 @@ type NonDifferentiable{T} <: AbstractObjective
last_x_f::Array{T}
f_calls::Vector{Int}
end
type UnitializedNonDifferentiable <: AbstractObjective
f
end
# The user friendly/short form NonDifferentiable constructor
NonDifferentiable(f) = UnitializedNonDifferentiable(f)
NonDifferentiable{T}(f, x_seed::Array{T}) = NonDifferentiable(f, f(x_seed), copy(x_seed), [1])

NonDifferentiable(f, x_seed::AbstractArray) = NonDifferentiable(f, f(x_seed), copy(x_seed), [1])

# Used for objectives and solvers where the gradient is available/exists
type OnceDifferentiable{T, Tgrad} <: AbstractObjective
Expand All @@ -37,29 +33,19 @@ type OnceDifferentiable{T, Tgrad} <: AbstractObjective
f_calls::Vector{Int}
g_calls::Vector{Int}
end
type UnitializedOnceDifferentiable <: AbstractObjective
f
g!
fg!
end
# The user friendly/short form OnceDifferentiable constructor
OnceDifferentiable(f, g!, fg!) = UnitializedOnceDifferentiable(f, g!, fg!)
OnceDifferentiable(f, g!) = UnitializedOnceDifferentiable(f, g!, nothing)
OnceDifferentiable(f) = UnitializedOnceDifferentiable(f, nothing, nothing)

# The user friendly/short form OnceDifferentiable constructor
function OnceDifferentiable(f, g!, fg!, x_seed::AbstractArray)
g = similar(x_seed)

_new_g! = fix_order(g, x_seed, g!, "g!")
_new_fg! = fix_order(g, x_seed, fg!, "fg!")

f_val = _new_fg!(g, x_seed)
OnceDifferentiable(f, _new_g!, _new_fg!, f_val, g, copy(x_seed), copy(x_seed), [1], [1])
end

# Automatically create the fg! helper function if only f and g! is provided
function OnceDifferentiable(f, g!, x_seed::AbstractArray)
g = similar(x_seed)
g = x_seed+one(eltype(x_seed))

_new_g! = fix_order(g, x_seed, g!, "g!")

Expand All @@ -86,28 +72,24 @@ type TwiceDifferentiable{T<:Real} <: AbstractObjective
g_calls::Vector{Int}
h_calls::Vector{Int}
end
type UnitializedTwiceDifferentiable <: AbstractObjective
f
g!
fg!
h!
end
TwiceDifferentiable(f, g!, fg!, h!) = UnitializedTwiceDifferentiable(f, g!, fg!, h!)
TwiceDifferentiable(f, g!, h!) = UnitializedTwiceDifferentiable(f, g!, nothing, h!)
TwiceDifferentiable(f, g!) = UnitializedTwiceDifferentiable(f, g!, nothing, nothing)
TwiceDifferentiable(f) = UnitializedTwiceDifferentiable(f, nothing, nothing, nothing)
# The user friendly/short form TwiceDifferentiable constructor
function TwiceDifferentiable(td::TwiceDifferentiable, x::AbstractArray)
value_gradient!(td, x)
hessian!(td, x)
td
end

function TwiceDifferentiable{T}(f, g!, fg!, h!, x_seed::Array{T})
n_x = length(x_seed)
g = similar(x_seed)
g = x_seed+one(T)
H = Array{T}(n_x, n_x)

_new_g! = fix_order(g, x_seed, g!, "g!")
_new_fg! = fix_order(g, x_seed, fg!, "fg!")

local _new_h!
try
_H = copy(H)
_H = copy(H)+one(T)
_x = copy(x_seed)
h!(_H, _x)
_new_h! = (storage, x) -> h!(storage, x)
Expand All @@ -127,13 +109,12 @@ function TwiceDifferentiable{T}(f, g!, fg!, h!, x_seed::Array{T})
g, H, copy(x_seed),
copy(x_seed), copy(x_seed), [1], [1], [1])
end

# Automatically create the fg! helper function if only f, g! and h! is provided
function TwiceDifferentiable{T}(f,
g!,
h!,
x_seed::Array{T})
g = similar(x_seed)
g = x_seed+one(T)
_new_g! = fix_order(g, x_seed, g!, "g!")

function fg!(storage::Vector, x::Vector)
Expand Down
19 changes: 19 additions & 0 deletions test/interface.jl
Expand Up @@ -32,6 +32,12 @@
td = TwiceDifferentiable(exponential, exponential_gradient!, exponential_hessian!, x_seed)

@test value(nd) == value(od) == value(td) == f_x_seed
@test value(nd, x_seed) == value(od, x_seed) == value(td, x_seed)
# change last_x_f manually to test branch
nd.last_x_f .*= 0
od.last_x_f .*= 0
td.last_x_f .*= 0
@test value(nd, x_seed) == value(od, x_seed) == value(td, x_seed)
@test gradient(od) == gradient(td) == g_x_seed
@test hessian(td) == h_x_seed
@test nd.f_calls == od.f_calls == td.f_calls == [1]
Expand All @@ -44,6 +50,7 @@

@test value(nd) == value(od) == value(td) == f_x_seed
@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 == [1]
@test od.g_calls == td.g_calls == [2]
Expand Down Expand Up @@ -74,6 +81,18 @@
value_gradient!(od, x_seed)
value_gradient!(td, x_seed)
@test value(od) == value(td) == f_x_seed
# change last_x_f manually to test branch
od.last_x_f .*= 0
td.last_x_f .*= 0
value_gradient!(od, x_seed)
value_gradient!(td, x_seed)
@test value(od) == value(td) == f_x_seed
# change last_x_g manually to test branch
od.last_x_g .*= 0
td.last_x_g .*= 0
value_gradient!(od, x_seed)
value_gradient!(td, x_seed)
@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 == [3]
Expand Down
8 changes: 7 additions & 1 deletion test/objective_types.jl
Expand Up @@ -25,7 +25,6 @@
@test value(nd) == f_x_seed
@test nd.last_x_f == [0.0, 0.0]
@test nd.f_calls == [1]

od = OnceDifferentiable(exponential, exponential_gradient!, x_seed)
@test od.f == exponential
#@test od.g! == exponential_gradient!
Expand All @@ -35,11 +34,18 @@
@test od.g_calls == [1]

td = TwiceDifferentiable(exponential, exponential_gradient!, exponential_hessian!, x_seed)
td_new = TwiceDifferentiable(td, x_seed)
@test td.f == exponential
#@test td.g! == exponential_gradient!
@test value(td) == f_x_seed
@test td.last_x_f == [0.0, 0.0]
@test td.f_calls == [1]
@test td.g_calls == [1]
@test td.h_calls == [1]

td_from_td = TwiceDifferentiable(td, x_seed-1)
@test value(td_from_td) == value(td, x_seed-1)
gradient!(td, x_seed-1)
@test gradient(td_from_td) == gradient(td)
@test value(td_from_td, x_seed) == value(td, x_seed)
end

0 comments on commit bce3ec3

Please sign in to comment.