Skip to content

Commit b2833b5

Browse files
committed
Add more NLS tests
1 parent 7deb3cb commit b2833b5

10 files changed

Lines changed: 63 additions & 49 deletions

File tree

src/ADNLPProblems/bard.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ end
88
function bard(::Val{:nlp}; n::Int = default_nvar, type::Type{T} = Float64, kwargs...) where {T}
99
y = Rational{Int}[0.14 0.18 0.22 0.25 0.29 0.32 0.35 0.39 0.37 0.58 0.73 0.16 1.34 2.10 4.39]
1010
function f(x)
11-
return 1 // 2 * sum(y[i] - (x[1] + i / ((16 - i) * x[2] + min(i, 16 - i) * x[3])) for i = 1:15)
11+
return 1 // 2 * sum((y[i] - (x[1] + i / ((16 - i) * x[2] + min(i, 16 - i) * x[3])))^2 for i = 1:15)
1212
end
1313
x0 = ones(T, 3)
1414
return ADNLPModels.ADNLPModel(f, x0, name = "bard"; kwargs...)

src/ADNLPProblems/hs6.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ end
2323

2424
function hs6(::Val{:nls}; n::Int = default_nvar, type::Type{T} = Float64, kwargs...) where {T}
2525
function F!(r, x)
26-
r[1] = 1 // 2 * (x[1] - 1)^2
26+
r[1] = (x[1] - 1)
2727
return r
2828
end
2929
function c!(cx, x)

src/ADNLPProblems/penalty1.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ function penalty1(::Val{:nls}; n::Int = default_nvar, type::Type{T} = Float64, k
2222
r[n + 1] = sum(x[j]^2 for j = 1:n) - 1 // 4
2323
return r
2424
end
25-
x0 = ones(T, n)
25+
x0 = T[j for j = 1:n]
2626
return ADNLPModels.ADNLSModel!(F!, x0, n + 1, name = "penalty1-nls"; kwargs...)
2727
end

src/ADNLPProblems/watson.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ function watson(::Val{:nlp}; n::Int = default_nvar, type::Type{T} = Float64, kwa
2323
1 // 2 * (
2424
sum((j - 1) * x[j] * (x[2] - x[1]^2 - 1)^(j - 2) for j = 2:n) -
2525
sum(x[j] * (x[2] - x[1]^2 - 1)^(j - 1) for j = 1:n)^2 - 1
26-
)
26+
)^2
2727
end
2828
x0 = zeros(T, n)
2929
return ADNLPModels.ADNLPModel(f, x0, name = "watson"; kwargs...)

src/PureJuMP/bard.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ function bard(args...; n::Int = default_nvar, m::Int = 2n, kwargs...)
2323
@objective(
2424
nlp,
2525
Min,
26-
0.5 * sum(y[i] - (x[1] + i / ((16 - i) * x[2] + min(i, 16 - i) * x[3])) for i = 1:15)
26+
0.5 * sum((y[i] - (x[1] + i / ((16 - i) * x[2] + min(i, 16 - i) * x[3])))^2 for i = 1:15)
2727
)
2828

2929
return nlp

src/PureJuMP/hs6.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function hs6(args...; kwargs...)
1919
x0 = [-1.2, 1]
2020
@variable(nlp, x[i = 1:2], start = x0[i])
2121

22-
@objective(nlp, Min, 0.5 * (1 - x[1])^2)
22+
@objective(nlp, Min, 0.5 * (x[1] - 1)^2)
2323

2424
@constraint(nlp, 10 * (x[2] - x[1]^2) == 0)
2525

src/PureJuMP/watson.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ function watson(args...; n::Int = default_nvar, kwargs...)
4040
0.5 * (
4141
sum((j - 1) * x[j] * (x[2] - x[1]^2 - 1)^(j - 2) for j = 2:n) -
4242
sum(x[j] * (x[2] - x[1]^2 - 1)^(j - 1) for j = 1:n)^2 - 1
43-
)
43+
)^2
4444
)
4545

4646
return nlp

test/runtests.jl

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,20 @@ addprocs(np - 1)
1414
[n for n in names(mod) if isdefined(mod, n)]
1515
end
1616

17-
const list_problems =
18-
setdiff(union(defined_names(ADNLPProblems), defined_names(PureJuMP)), [:PureJuMP, :ADNLPProblems])
17+
@everywhere const list_problems = setdiff(union(defined_names(ADNLPProblems), defined_names(PureJuMP)), [:PureJuMP, :ADNLPProblems])
18+
19+
@testset "Test that all problems have a meta" begin
20+
@test sort(list_problems) == sort(Symbol.(OptimizationProblems.meta[!, :name]))
21+
end
1922

2023
# The problems included should be carefully argumented and issues
2124
# to create them added.
2225
# TODO: tests are limited for JuMP-only problems
23-
const list_problems_not_ADNLPProblems =
26+
@everywhere const list_problems_not_ADNLPProblems =
2427
Symbol[:catmix, :gasoil, :glider, :methanol, :minsurf, :pinene, :rocket, :steering, :torsion]
25-
const list_problems_ADNLPProblems = setdiff(list_problems, list_problems_not_ADNLPProblems)
26-
const list_problems_not_PureJuMP = Symbol[]
27-
const list_problems_PureJuMP = setdiff(list_problems, list_problems_not_PureJuMP)
28+
@everywhere const list_problems_ADNLPProblems = setdiff(list_problems, list_problems_not_ADNLPProblems)
29+
@everywhere const list_problems_not_PureJuMP = Symbol[]
30+
@everywhere const list_problems_PureJuMP = setdiff(list_problems, list_problems_not_PureJuMP)
2831

2932
include("test-defined-problems.jl")
3033
include("test-utils.jl")
@@ -57,6 +60,8 @@ end
5760
return ctor(matrix_free = true; kwargs...)
5861
end
5962

63+
include("test-in-place-residual.jl")
64+
6065
@everywhere function test_one_problem(prob::Symbol)
6166
pb = string(prob)
6267

@@ -75,35 +80,26 @@ end
7580

7681
nlp_ad = timed_info("Instantiating $(pb)", make_nlp, prob)
7782

78-
@test nlp_ad.meta.name == pb
83+
@testset "Sanity check (name, obj)" begin
84+
@test nlp_ad.meta.name == pb
85+
@test !isnothing(obj(nlp_ad, nlp_ad.meta.x0))
86+
end
7987

8088
if pb in meta[(meta.contype .== :quadratic) .| (meta.contype .== :general), :name]
8189
@testset "Test In-place Nonlinear Constraints for AD-$prob" begin
8290
test_in_place_constraints(prob, nlp_ad)
8391
end
8492
end
8593

86-
@testset "Test multi-precision ADNLPProblems for $prob" begin
87-
test_multi_precision(prob, nlp_ad)
88-
end
89-
90-
if pb in meta[meta.objtype .== :least_squares, :name]
91-
@testset "Test Nonlinear Least Squares for $prob" begin
92-
test_in_place_residual(prob)
94+
if typeof(nlp_ad) <: ADNLPModels.AbstractADNLPModel
95+
@testset "Test multi-precision ADNLPProblems for $prob" begin
96+
test_multi_precision(prob, nlp_ad)
9397
end
9498
end
9599

96-
model = begin
97-
mod = PureJuMP
98-
if isdefined(mod, prob)
99-
getfield(mod, prob)(n = ndef)
100-
else
101-
nothing
102-
end
103-
end
104-
if !isnothing(model)
100+
if mod in intersect(list_problems_PureJuMP, list_problems_ADNLPProblems)
105101
@testset "Test problems compatibility for $prob" begin
106-
nlp_jump = MathOptNLPModel(model)
102+
nlp_jump = make_jump_nlp(prob; n = ndef)
107103
test_compatibility(prob, nlp_jump, nlp_ad, ndef)
108104
end
109105
end

test/test-in-place-residual.jl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
@everywhere function test_in_place_residual(prob::Symbol)
2+
nlp = make_ad_nlp(prob; use_nls = false)
3+
@test typeof(nlp) <: ADNLPModels.ADNLPModel
4+
nls = make_ad_nlp(prob; use_nls = true)
5+
@test typeof(nls) <: ADNLPModels.ADNLSModel
6+
return test_in_place_residual(prob, nlp, nls)
7+
end
8+
9+
@everywhere function test_in_place_residual(prob::Symbol, nlp::AbstractNLPModel, nls::AbstractNLSModel)
10+
@testset "Test in-place residual $prob" begin
11+
x = nls.meta.x0
12+
Fx = similar(x, nls.nls_meta.nequ)
13+
pb = String(prob)
14+
if VERSION v"1.7" && !occursin("palmer", pb) && (pb != "watson") # palmer residual allocate
15+
@allocated residual!(nls, x, Fx)
16+
@test (@allocated residual!(nls, x, Fx)) == 0
17+
end
18+
m = OptimizationProblems.eval(Meta.parse("get_$(prob)_nls_nequ"))()
19+
@test nls.nls_meta.nequ == m
20+
end
21+
22+
@testset "Compare NLS with NLP $prob: x0 and obj are the same." begin
23+
x0 = nlp.meta.x0
24+
@test x0 == nls.meta.x0
25+
nlp_fx = obj(nlp, x0)
26+
nls_fx = obj(nls, x0)
27+
are_almost_same = (nlp_fx nls_fx) | (nlp_fx 2 * nls_fx)
28+
if !(are_almost_same)
29+
@info "$prob : NLS $(nls_fx) ≈ NLP $(nlp_fx)"
30+
end
31+
@test are_almost_same
32+
end
33+
end
34+
35+
nls_name_list = intersect(Symbol.(meta[meta.objtype .== :least_squares, :name]), list_problems_ADNLPProblems)
36+
pmap(test_in_place_residual, nls_name_list)

test/test-utils.jl

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,6 @@ end
4646
@test ncon == m
4747
end
4848

49-
@everywhere function test_in_place_residual(prob::Symbol)
50-
nls = OptimizationProblems.ADNLPProblems.eval(prob)(use_nls = true)
51-
@test typeof(nls) <: ADNLPModels.ADNLSModel
52-
return test_in_place_residual(prob, nls)
53-
end
54-
55-
@everywhere function test_in_place_residual(prob::Symbol, nls::AbstractNLSModel)
56-
x = nls.meta.x0
57-
Fx = similar(x, nls.nls_meta.nequ)
58-
pb = String(prob)
59-
if VERSION v"1.7" && !occursin("palmer", pb) && (pb != "watson") # palmer residual allocate
60-
@allocated residual!(nls, x, Fx)
61-
@test (@allocated residual!(nls, x, Fx)) == 0
62-
end
63-
m = OptimizationProblems.eval(Meta.parse("get_$(prob)_nls_nequ"))()
64-
@test nls.nls_meta.nequ == m
65-
end
66-
6749
@everywhere function test_compatibility(prob::Symbol, ndef::Integer = ndef)
6850
prob_fn = eval(Meta.parse("PureJuMP.$(prob)"))
6951
model = prob_fn(n = ndef)

0 commit comments

Comments
 (0)