Skip to content

Commit 49e807d

Browse files
committed
Calculate derivatives using Jacobian-vector products
1 parent 07963b7 commit 49e807d

File tree

9 files changed

+26
-76
lines changed

9 files changed

+26
-76
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ jobs:
1212
runs-on: ${{ matrix.os }}
1313
strategy:
1414
matrix:
15-
julia-version: ['min', 'lts', '1']
15+
# julia-version: ['min', 'lts', '1']
16+
julia-version: ['1']
1617
os: [ubuntu-latest, windows-latest, macOS-latest]
1718
steps:
1819
- uses: actions/checkout@v2
1920
- uses: julia-actions/setup-julia@v2
2021
with:
2122
version: ${{ matrix.julia-version }}
2223
- uses: julia-actions/cache@v2
23-
- uses: julia-actions/julia-buildpkg@v1
2424
- uses: julia-actions/julia-runtest@v1
2525
with:
2626
annotate: true

Project.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@ DoubleFloats = "1"
1414
ExplicitImports = "1.14"
1515
JET = "0.9, 0.10"
1616
LinearAlgebra = "<0.0.1, 1"
17-
NLSolversBase = "7"
17+
NLSolversBase = "8"
1818
NaNMath = "1"
19-
Optim = "1"
2019
OptimTestProblems = "2"
2120
Printf = "<0.0.1, 1"
2221
Test = "<0.0.1, 1"
@@ -27,9 +26,11 @@ Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
2726
DoubleFloats = "497a8b3b-efae-58df-a0af-a86822472b78"
2827
ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7"
2928
JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b"
30-
Optim = "429524aa-4258-5aef-a3af-852621145aeb"
3129
OptimTestProblems = "cec144fc-5a64-5bc6-99fb-dde8f63e154c"
3230
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
3331

3432
[targets]
35-
test = ["Aqua", "ExplicitImports", "JET", "Test", "OptimTestProblems", "Optim", "DoubleFloats"]
33+
test = ["Aqua", "ExplicitImports", "JET", "Test", "OptimTestProblems", "DoubleFloats"]
34+
35+
[sources]
36+
NLSolversBase = { url = "https://github.com/devmotion/NLSolversBase.jl.git", rev = "dmw/jvp" }

src/LineSearches.jl

Lines changed: 11 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module LineSearches
22

33
using Printf: @sprintf
4-
using LinearAlgebra: dot, norm
4+
using LinearAlgebra: norm
55
using NaNMath: NaNMath
66
using NLSolversBase: NLSolversBase, AbstractObjective
77

@@ -16,74 +16,40 @@ export InitialHagerZhang, InitialStatic, InitialPrevious,
1616
function make_ϕ(df, x_new, x, s)
1717
function ϕ(α)
1818
# Move a distance of alpha in the direction of s
19-
x_new .= x .+ α.*s
19+
x_new .= muladd.(α, s, x)
2020

2121
# Evaluate f(x+α*s)
22-
NLSolversBase.value!(df, x_new)
22+
return NLSolversBase.value!(df, x_new)
2323
end
2424
ϕ
2525
end
2626
function make_ϕdϕ(df, x_new, x, s)
2727
function ϕdϕ(α)
2828
# Move a distance of alpha in the direction of s
29-
x_new .= x .+ α.*s
30-
31-
# Evaluate ∇f(x+α*s)
32-
NLSolversBase.value_gradient!(df, x_new)
29+
x_new .= muladd.(α, s, x)
3330

3431
# Calculate ϕ(a_i), ϕ'(a_i)
35-
NLSolversBase.value(df), real(dot(NLSolversBase.gradient(df), s))
32+
ϕ, dϕ = NLSolversBase.value_jvp!(df, x_new, s)
33+
34+
return ϕ, real(dϕ)
3635
end
3736
ϕdϕ
3837
end
3938
function make_ϕ_dϕ(df, x_new, x, s)
4039
function (α)
4140
# Move a distance of alpha in the direction of s
42-
x_new .= x .+ α.*s
43-
44-
# Evaluate ∇f(x+α*s)
45-
NLSolversBase.gradient!(df, x_new)
41+
x_new .= muladd.(α, s, x)
4642

4743
# Calculate ϕ'(a_i)
48-
real(dot(NLSolversBase.gradient(df), s))
44+
return real(NLSolversBase.jvp!(df, x_new, s))
4945
end
5046
make_ϕ(df, x_new, x, s), dϕ
5147
end
5248
function make_ϕ_dϕ_ϕdϕ(df, x_new, x, s)
53-
function (α)
54-
# Move a distance of alpha in the direction of s
55-
x_new .= x .+ α.*s
56-
57-
# Evaluate f(x+α*s) and ∇f(x+α*s)
58-
NLSolversBase.gradient!(df, x_new)
59-
60-
# Calculate ϕ'(a_i)
61-
real(dot(NLSolversBase.gradient(df), s))
62-
end
63-
function ϕdϕ(α)
64-
# Move a distance of alpha in the direction of s
65-
x_new .= x .+ α.*s
66-
67-
# Evaluate ∇f(x+α*s)
68-
NLSolversBase.value_gradient!(df, x_new)
69-
70-
# Calculate ϕ'(a_i)
71-
NLSolversBase.value(df), real(dot(NLSolversBase.gradient(df), s))
72-
end
73-
make_ϕ(df, x_new, x, s), dϕ, ϕdϕ
49+
make_ϕ_dϕ(df, x_new, x, s)..., make_ϕdϕ(df, x_new, x, s)
7450
end
7551
function make_ϕ_ϕdϕ(df, x_new, x, s)
76-
function ϕdϕ(α)
77-
# Move a distance of alpha in the direction of s
78-
x_new .= x .+ α.*s
79-
80-
# Evaluate ∇f(x+α*s)
81-
NLSolversBase.value_gradient!(df, x_new)
82-
83-
# Calculate ϕ'(a_i)
84-
NLSolversBase.value(df), real(dot(NLSolversBase.gradient(df), s))
85-
end
86-
make_ϕ(df, x_new, x, s), ϕdϕ
52+
make_ϕ(df, x_new, x, s), make_ϕdϕ(df, x_new, x, s)
8753
end
8854

8955
include("types.jl")

src/initialguess.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ function (is::InitialQuadratic{T})(ls, state, phi_0, dphi_0, df) where T
7474
# If we're at the first iteration
7575
αguess = is.α0
7676
else
77-
αguess = 2 * (NLSolversBase.value(df) - state.f_x_previous) / dphi_0
77+
f_x_ls = NLSolversBase.value!(df, state.x_ls)
78+
αguess = 2 * (f_x_ls - state.f_x_previous) / dphi_0
7879
αguess = NaNMath.max(is.αmin, state.alpha*is.ρ, αguess)
7980
αguess = NaNMath.min(is.αmax, αguess)
8081
# if αguess ≈ 1, then make it 1 (Newton-type behaviour)
@@ -180,8 +181,8 @@ function (is::InitialHagerZhang)(ls::Tls, state, phi_0, dphi_0, df) where Tls
180181
# and the user has not provided an initial step size (is.α0 is NaN),
181182
# then we
182183
# pick the initial step size according to HZ #I0
183-
state.alpha = _hzI0(state.x, NLSolversBase.gradient(df),
184-
NLSolversBase.value(df),
184+
fx, gx = NLSolversBase.value_gradient!(df, state.x)
185+
state.alpha = _hzI0(state.x, gx, fx,
185186
is.αmax,
186187
convert(eltype(state.x), is.ψ0)) # Hack to deal with type instability between is{T} and state.x
187188
if Tls <: HagerZhang

src/types.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
mutable struct LineSearchException{T<:Real} <: Exception
1+
struct LineSearchException{T<:Real} <: Exception
22
message::AbstractString
33
alpha::T
44
end

test/arbitrary_precision.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ doublefloatstypes = [Double64, Double32, Double16]
9898
ls = HagerZhang{T}()
9999
state = getstate()
100100
state.f_x_previous = 2*phi_0
101+
state.x_ls = zeros(T, 2)
101102
is = InitialQuadratic{T}(snap2one=(convert(T, 0.9),convert(T, Inf)))
102103
is(ls, state, phi_0, dphi_0, df)
103104
@test !isnan(state.alpha)
@@ -107,6 +108,7 @@ doublefloatstypes = [Double64, Double32, Double16]
107108
ls = HagerZhang{T}()
108109
state = getstate()
109110
state.f_x_previous = 2*phi_0
111+
state.x_ls = zeros(T, 2)
110112
is = InitialQuadratic{T}(snap2one=(convert(T, 0.75),convert(T, Inf)))
111113
is(ls, state, phi_0, dphi_0, df)
112114
@test !isnan(state.alpha)

test/examples.jl

Lines changed: 0 additions & 20 deletions
This file was deleted.

test/initial.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
ls = HagerZhang()
8989
state = getstate()
9090
state.f_x_previous = 2*phi_0
91+
state.x_ls = zeros(2)
9192
is = InitialQuadratic(snap2one=(0.9,Inf))
9293
is(ls, state, phi_0, dphi_0, df)
9394
@test state.alpha == 1.0

test/runtests.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ my_tests = [
1414
"initial.jl",
1515
"alphacalc.jl",
1616
"arbitrary_precision.jl",
17-
"examples.jl",
1817
"captured.jl",
1918
"issues.jl",
2019
"qa.jl",

0 commit comments

Comments
 (0)