Skip to content

Commit

Permalink
Require Julia 0.7 (#127)
Browse files Browse the repository at this point in the history
* Move to Julia 0.7
* Explicitly call `convert(T, ::Number)` rather than `T(::Number)`
  • Loading branch information
anriseth committed Jul 16, 2018
1 parent dc27e6e commit c6747d4
Show file tree
Hide file tree
Showing 21 changed files with 123 additions and 196 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Expand Up @@ -4,7 +4,7 @@ os:
- linux
- osx
julia:
- 0.6
- 0.7
- nightly
matrix:
allow_failures:
Expand Down
5 changes: 2 additions & 3 deletions REQUIRE
@@ -1,5 +1,4 @@
julia 0.6
NLSolversBase 5.0
julia 0.7-beta2
NLSolversBase 7.0
Parameters
NaNMath
Compat
4 changes: 2 additions & 2 deletions appveyor.yml
@@ -1,7 +1,7 @@
environment:
matrix:
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.7/julia-0.7-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.7/julia-0.7-latest-win64.exe"
matrix:
allow_failures:
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
Expand Down
7 changes: 4 additions & 3 deletions docs/generate.jl
Expand Up @@ -3,12 +3,13 @@ import Literate

# TODO: Remove items from `SKIPFILE` as soon as they run on the latest
# stable `Optim` (or other dependency)
#ONLYSTATIC = ["optim_linesearch.jl", "optim_initialstep.jl"]
ONLYSTATIC = []
ONLYSTATIC = ["optim_linesearch.jl", "optim_initialstep.jl"]
#ONLYSTATIC = []

EXAMPLEDIR = joinpath(@__DIR__, "src", "examples")
GENERATEDDIR = joinpath(@__DIR__, "src", "examples", "generated")
for example in filter!(r"\.jl$", readdir(EXAMPLEDIR))
myfilter(str) = occursin(r"\.jl$", str)
for example in filter!(myfilter, readdir(EXAMPLEDIR))
input = abspath(joinpath(EXAMPLEDIR, example))
script = Literate.script(input, GENERATEDDIR)
code = strip(read(script, String))
Expand Down
4 changes: 2 additions & 2 deletions docs/make.jl
Expand Up @@ -11,7 +11,7 @@ makedocs(
format = :html,
sitename = "LineSearches.jl",
doctest = false,
# strict = VERSION.minor == 6 && sizeof(Int) == 8, # only strict mode on 0.6 and Int64
# strict = VERSION.minor == 7 && sizeof(Int) == 8, # only strict mode on 0.7 and Int64
strict = false,
pages = Any[
"Home" => "index.md",
Expand All @@ -27,7 +27,7 @@ makedocs(
deploydocs(
repo = "github.com/JuliaNLSolvers/LineSearches.jl.git",
target = "build",
julia = "0.6", # deploy from release bot
julia = "0.7", # deploy from release bot
deps = nothing,
make = nothing,
)
8 changes: 4 additions & 4 deletions docs/src/examples/customoptimizer.jl
Expand Up @@ -28,11 +28,11 @@ function gdoptimize(f, g!, fg!, x0::AbstractArray{T}, linesearch,
ϕ(α) = f(x .+ α.*s)
function (α)
g!(gvec, x .+ α.*s)
return vecdot(gvec, s)
return dot(gvec, s)
end
function ϕdϕ(α)
phi = fg!(gvec, x .+ α.*s)
dphi = vecdot(gvec, s)
dphi = dot(gvec, s)
return (phi, dphi)
end

Expand Down Expand Up @@ -100,10 +100,10 @@ ls = BackTracking(order=3)
fx_bt3, x_bt3, iter_bt3 = gdoptimize(f, g!, fg!, x0, ls)

## Test the results #src
using Base.Test #src
using Test #src
@test fx_bt3 < 1e-12 #src
@test iter_bt3 < 10000 #src
@test x_bt3 [1.0, 1.0] atol=1e-7 #src
@test x_bt3 [1.0, 1.0] atol=2e-7 #src

# Interestingly, the `StrongWolfe` line search converges in one iteration, whilst
# all the other algorithms take thousands of iterations.
Expand Down
8 changes: 1 addition & 7 deletions docs/src/examples/optim_initialstep.jl
@@ -1,11 +1,5 @@
# # Optim initial step length guess
#
#src TODO: Find a way to run these with Literate when deploying via Travis
#src TODO: This file must currently be run locally and not on CI, and then
#src TODO: the md file must be copied over to the correct directory.
#src TODO: The reason is that there may be breaking changes between Optim and LineSearches,
#src TODO: so we don't want that to mess up JuliaCIBot
#-
#-
#md # !!! tip
#md # This example is also available as a Jupyter notebook:
Expand Down Expand Up @@ -34,7 +28,7 @@ res_hz = Optim.optimize(prob.f, prob.g!, prob.h!, prob.initial_x, method=algo_hz
# From the result we see that this has reduced the number of function and gradient calls, but increased the number of iterations.

## Test the results #src
using Base.Test #src
using Test #src
@test Optim.f_calls(res_hz) < Optim.f_calls(res_st) #src
@test Optim.g_calls(res_hz) < Optim.g_calls(res_st) #src
@test Optim.iterations(res_hz) > Optim.iterations(res_st) #src
9 changes: 2 additions & 7 deletions docs/src/examples/optim_linesearch.jl
@@ -1,10 +1,5 @@
# # Optim line search
#
#src TODO: Find a way to run these with Literate when deploying via Travis
#src TODO: This file must currently be run locally and not on CI, and then
#src TODO: the md file must be copied over to the correct directory.
#src TODO: The reason is that there may be breaking changes between Optim and LineSearches,
#src TODO: so we don't want that to mess up JuliaCIBot
#-
#md # !!! tip
#md # This example is also available as a Jupyter notebook:
Expand Down Expand Up @@ -32,7 +27,7 @@ algo_bt3 = Newton(linesearch = BackTracking(order=3))
res_bt3 = Optim.optimize(prob.f, prob.g!, prob.h!, prob.initial_x, method=algo_bt3)


## Test the results #src
using Base.Test #src
## Test the results #src
using Test #src
@test Optim.f_calls(res_bt3) < Optim.f_calls(res_hz) #src
@test Optim.g_calls(res_bt3) < Optim.g_calls(res_hz) #src
19 changes: 8 additions & 11 deletions src/LineSearches.jl
@@ -1,12 +1,9 @@
isdefined(Base, :__precompile__) && __precompile__()
__precompile__()

module LineSearches

using Compat,
Compat.LinearAlgebra,
Compat.Distributed,
Compat.Printf

using Printf
import LinearAlgebra: dot, norm
using Parameters, NaNMath

import NLSolversBase
Expand Down Expand Up @@ -38,7 +35,7 @@ function make_ϕdϕ(df, x_new, x, s)
NLSolversBase.value_gradient!(df, x_new)

# Calculate ϕ(a_i), ϕ'(a_i)
NLSolversBase.value(df), real(vecdot(NLSolversBase.gradient(df), s))
NLSolversBase.value(df), real(dot(NLSolversBase.gradient(df), s))
end
ϕdϕ
end
Expand All @@ -51,7 +48,7 @@ function make_ϕ_dϕ(df, x_new, x, s)
NLSolversBase.gradient!(df, x_new)

# Calculate ϕ'(a_i)
real(vecdot(NLSolversBase.gradient(df), s))
real(dot(NLSolversBase.gradient(df), s))
end
make_ϕ(df, x_new, x, s), dϕ
end
Expand All @@ -64,7 +61,7 @@ function make_ϕ_dϕ_ϕdϕ(df, x_new, x, s)
NLSolversBase.gradient!(df, x_new)

# Calculate ϕ'(a_i)
real(vecdot(NLSolversBase.gradient(df), s))
real(dot(NLSolversBase.gradient(df), s))
end
function ϕdϕ(α)
# Move a distance of alpha in the direction of s
Expand All @@ -74,7 +71,7 @@ function make_ϕ_dϕ_ϕdϕ(df, x_new, x, s)
NLSolversBase.value_gradient!(df, x_new)

# Calculate ϕ'(a_i)
NLSolversBase.value(df), real(vecdot(NLSolversBase.gradient(df), s))
NLSolversBase.value(df), real(dot(NLSolversBase.gradient(df), s))
end
make_ϕ(df, x_new, x, s), dϕ, ϕdϕ
end
Expand All @@ -87,7 +84,7 @@ function make_ϕ_ϕdϕ(df, x_new, x, s)
NLSolversBase.value_gradient!(df, x_new)

# Calculate ϕ'(a_i)
NLSolversBase.value(df), real(vecdot(NLSolversBase.gradient(df), s))
NLSolversBase.value(df), real(dot(NLSolversBase.gradient(df), s))
end
make_ϕ(df, x_new, x, s), ϕdϕ
end
Expand Down
2 changes: 1 addition & 1 deletion src/backtracking.jl
Expand Up @@ -29,7 +29,7 @@ function (ls::BackTracking)(df::AbstractObjective, x::AbstractArray{T}, s::Abstr
dϕ_0 = ((0))
end

α_0 = min(α_0, min(alphamax, ls.maxstep / vecnorm(s, Inf)))
α_0 = min(α_0, min(alphamax, ls.maxstep / norm(s, Inf)))
ls(ϕ, α_0, ϕ_0, dϕ_0)
end

Expand Down
34 changes: 19 additions & 15 deletions src/hagerzhang.jl
Expand Up @@ -111,18 +111,19 @@ function (ls::HagerZhang)(ϕ, ϕdϕ,
@unpack delta, sigma, alphamax, rho, epsilon, gamma,
linesearchmax, psi3, display, mayterminate = ls

zeroT = convert(T, 0)

if !(isfinite(phi_0) && isfinite(dphi_0))
throw(ArgumentError("Value and slope at step length = 0 must be finite."))
end
if dphi_0 >= T(0)
if dphi_0 >= zeroT
throw(ArgumentError("Search direction is not a direction of descent."))
end

# Prevent values of x_new = x+αs that are likely to make
# ϕ(x_new) infinite
iterfinitemax::Int = ceil(Int, -log2(eps(T)))
alphas = [T(0)] # for bisection
alphas = [zeroT] # for bisection
values = [phi_0]
slopes = [dphi_0]
if display & LINESEARCH > 0
Expand All @@ -131,7 +132,7 @@ function (ls::HagerZhang)(ϕ, ϕdϕ,


phi_lim = phi_0 + epsilon * abs(phi_0)
@assert c > T(0)
@assert c > zeroT
@assert isfinite(c) && c <= alphamax
phi_c, dphi_c = ϕdϕ(c)
iterfinite = 1
Expand All @@ -142,9 +143,9 @@ function (ls::HagerZhang)(ϕ, ϕdϕ,
phi_c, dphi_c = ϕdϕ(c)
end
if !(isfinite(phi_c) && isfinite(dphi_c))
warn("Failed to achieve finite new evaluation point, using alpha=0")
@warn("Failed to achieve finite new evaluation point, using alpha=0")
mayterminate[] = false # reset in case another initial guess is used next
return T(0.0), ϕ(T(0.0)) # phi_0
return zeroT, ϕ(zeroT) # phi_0
end
push!(alphas, c)
push!(values, phi_c)
Expand Down Expand Up @@ -175,7 +176,7 @@ function (ls::HagerZhang)(ϕ, ϕdϕ,
", phi_c = ", phi_c,
", dphi_c = ", dphi_c)
end
if dphi_c >= T(0)
if dphi_c >= zeroT
# We've reached the upward slope, so we have b; examine
# previous values to find a
ib = length(alphas)
Expand All @@ -191,7 +192,7 @@ function (ls::HagerZhang)(ϕ, ϕdϕ,
# have crested over the peak. Use bisection.
ib = length(alphas)
ia = ib - 1
if c alphas[ib] || slopes[ib] >= T(0)
if c alphas[ib] || slopes[ib] >= zeroT
error("c = ", c)
end
# ia, ib = bisect(phi, lsr, ia, ib, phi_lim) # TODO: Pass options
Expand Down Expand Up @@ -226,7 +227,7 @@ function (ls::HagerZhang)(ϕ, ϕdϕ,
if !(isfinite(phi_c) && isfinite(dphi_c))
mayterminate[] = false # reset in case another initial guess is used next
return cold, ϕ(cold)
elseif dphi_c < T(0) && c == alphamax
elseif dphi_c < zeroT && c == alphamax
# We're on the edge of the allowed region, and the
# value is still decreasing. This can be due to
# roundoff error in barrier penalties, a barrier
Expand Down Expand Up @@ -352,7 +353,8 @@ function secant2!(ϕdϕ,
dphi_a = slopes[ia]
dphi_b = slopes[ib]
T = eltype(slopes)
if !(dphi_a < T(0) && dphi_b >= T(0))
zeroT = convert(T, 0)
if !(dphi_a < zeroT && dphi_b >= zeroT)
error(string("Search direction is not a direction of descent; ",
"this error may indicate that user-provided derivatives are inaccurate. ",
@sprintf "(dphi_a = %f; dphi_b = %f)" dphi_a dphi_b))
Expand Down Expand Up @@ -436,10 +438,11 @@ function update!(ϕdϕ,
a = alphas[ia]
b = alphas[ib]
T = eltype(slopes)
zeroT = convert(T, 0)
# Debugging (HZ, eq. 4.4):
@assert slopes[ia] < T(0)
@assert slopes[ia] < zeroT
@assert values[ia] <= phi_lim
@assert slopes[ib] >= T(0)
@assert slopes[ib] >= zeroT
@assert b > a
c = alphas[ic]
phi_c = values[ic]
Expand All @@ -456,7 +459,7 @@ function update!(ϕdϕ,
if c < a || c > b
return ia, ib #, 0, 0 # it's out of the bracketing interval
end
if dphi_c >= T(0)
if dphi_c >= zeroT
return ia, ic #, 0, 0 # replace b with a closer point
end
# We know dphi_c < 0. However, phi may not be monotonic between a
Expand Down Expand Up @@ -485,9 +488,10 @@ function bisect!(ϕdϕ,
a = alphas[ia]
b = alphas[ib]
# Debugging (HZ, conditions shown following U3)
@assert slopes[ia] < T(0)
zeroT = convert(T, 0)
@assert slopes[ia] < zeroT
@assert values[ia] <= phi_lim
@assert slopes[ib] < T(0) # otherwise we wouldn't be here
@assert slopes[ib] < zeroT # otherwise we wouldn't be here
@assert values[ib] > phi_lim
@assert b > a
while b - a > eps(b)
Expand All @@ -503,7 +507,7 @@ function bisect!(ϕdϕ,
push!(slopes, gphi)

id = length(alphas)
if gphi >= T(0)
if gphi >= zeroT
return ia, id # replace b, return
end
if phi_d <= phi_lim
Expand Down

0 comments on commit c6747d4

Please sign in to comment.