Skip to content

Commit 75aabbb

Browse files
test: add tests for single roots, fix allroots tests
1 parent db21cf8 commit 75aabbb

File tree

3 files changed

+161
-13
lines changed

3 files changed

+161
-13
lines changed

lib/NonlinearSolveHomotopyContinuation/test/allroots.jl

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,24 @@ using SciMLBase: NonlinearSolution
55
alg = HomotopyContinuationJL{true}(; threading = false)
66

77
@testset "scalar u" begin
8-
@testset "`NonlinearProblem`" begin
9-
prob = NonlinearProblem(1.0, 2.0) do u, p
10-
return u * u - 2p * u + p * p
11-
end
8+
rhs = function (u, p)
9+
return u * u - 2p * u + p * p
10+
end
11+
jac = function (u, p)
12+
return 2u - 2p
13+
end
14+
@testset "`NonlinearProblem` - $name" for (jac, name) in [(nothing, "no jac"), (jac, "jac")]
15+
fn = NonlinearFunction(rhs; jac)
16+
prob = NonlinearProblem(fn, 1.0, 2.0)
1217
sol = solve(prob, alg)
1318

1419
@test sol isa EnsembleSolution
15-
@test length(sol) == 1
16-
@test sol.u[1] isa NonlinearSolution
17-
@test sol.u[1][1] 2.0
20+
@test sol.converged
21+
for nlsol in sol
22+
@test nlsol isa NonlinearSolution
23+
@test SciMLBase.successful_retcode(nlsol)
24+
@test nlsol.u[1] 2.0 atol = 1e-7
25+
end
1826

1927
@testset "no real solutions" begin
2028
prob = NonlinearProblem(1.0, 0.5) do u, p
@@ -63,19 +71,31 @@ alg = HomotopyContinuationJL{true}(; threading = false)
6371
end
6472
end
6573

66-
function f!(du, u, p)
74+
f! = function (du, u, p)
6775
du[1] = u[1] * u[1] - p[1] * u[2] + u[2] ^ 3 + 1
6876
du[2] = u[2] ^ 3 + 2 * p[2] * u[1] * u[2] + u[2]
6977
end
7078

71-
function f(u, p)
79+
f = function (u, p)
7280
[u[1] * u[1] - p[1] * u[2] + u[2] ^ 3 + 1, u[2] ^ 3 + 2 * p[2] * u[1] * u[2] + u[2]]
7381
end
7482

75-
@testset "vector u - $iip" for (rhs, iip) in [(f, "oop"), (f!, "iip")]
83+
jac! = function (j, u, p)
84+
j[1, 1] = 2u[1]
85+
j[1, 2] = -p[1] + 3 * u[2]^2
86+
j[2, 1] = 2 * p[2] * u[2]
87+
j[2, 2] = 3 * u[2]^2 + 2 * p[2] * u[1] + 1
88+
end
89+
jac = function (u, p)
90+
[2u[1] -p[1] + 3 * u[2]^2;
91+
2 * p[2] * u[2] 3 * u[2]^2 + 2 * p[2] * u[1] + 1]
92+
end
93+
94+
@testset "vector u - $name" for (rhs, jac, name) in [(f, nothing, "oop"), (f, jac, "oop + jac"), (f!, nothing, "iip"), (f!, jac!, "iip + jac")]
7695
sol = nothing
7796
@testset "`NonlinearProblem`" begin
78-
prob = NonlinearProblem(rhs, [1.0, 2.0], [2.0, 3.0])
97+
fn = NonlinearFunction(rhs; jac)
98+
prob = NonlinearProblem(fn, [1.0, 2.0], [2.0, 3.0])
7999
sol = solve(prob, alg)
80100
@test sol isa EnsembleSolution
81101
@test sol.converged
@@ -103,7 +123,8 @@ end
103123
polynomialize = function (u, p)
104124
return [u[1] ^ 3, 40asin(u[2])]
105125
end
106-
fn = HomotopyNonlinearFunction(rhs; denominator, polynomialize, unpolynomialize)
126+
nlfn = NonlinearFunction(rhs; jac)
127+
fn = HomotopyNonlinearFunction(nlfn; denominator, polynomialize, unpolynomialize)
107128
prob = NonlinearProblem(fn, [1.0, 2.0], [2.0, 3.0, 4.0, 5.0])
108129
sol2 = solve(prob, alg)
109130
@test sol2 isa EnsembleSolution

lib/NonlinearSolveHomotopyContinuation/test/runtests.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,7 @@ using Aqua
99
@testset "AllRoots" begin
1010
include("allroots.jl")
1111
end
12-
# Write your tests here.
12+
@testset "Single Root" begin
13+
include("single_root.jl")
14+
end
1315
end
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
using NonlinearSolve
2+
using NonlinearSolveHomotopyContinuation
3+
using SciMLBase: NonlinearSolution
4+
5+
alg = HomotopyContinuationJL{false}(; threading = false)
6+
7+
@testset "scalar u" begin
8+
rhs = function (u, p)
9+
return (u - 3.0) * (u - p)
10+
end
11+
jac = function (u, p)
12+
return 2u - (p + 3)
13+
end
14+
@testset "`NonlinearProblem` - $name" for (jac, name) in [(nothing, "no jac"), (jac, "jac")]
15+
fn = NonlinearFunction(rhs; jac)
16+
prob = NonlinearProblem(fn, 1.0, 2.0)
17+
sol = solve(prob, alg)
18+
19+
@test sol isa NonlinearSolution
20+
@test sol.u 2.0 atol = 1e-10
21+
22+
@testset "no real solutions" begin
23+
prob = NonlinearProblem(1.0, 1.0) do u, p
24+
return u * u - 2p * u + p
25+
end
26+
sol = solve(prob, alg)
27+
@test sol.retcode == SciMLBase.ReturnCode.ConvergenceFailure
28+
end
29+
end
30+
31+
@testset "`HomotopyContinuationFunction`" begin
32+
denominator = function (u, p)
33+
return [u - 0.7]
34+
end
35+
polynomialize = function (u, p)
36+
return sin(u)
37+
end
38+
unpolynomialize = function (u, p)
39+
return [asin(u)]
40+
end
41+
fn = HomotopyNonlinearFunction(; denominator, polynomialize, unpolynomialize) do u, p
42+
return (u - p[1]) * (u - p[2])
43+
end
44+
prob = NonlinearProblem(fn, 0.0, [0.5, 0.7])
45+
46+
sol = solve(prob, alg)
47+
@test sin(sol.u[1]) 0.5 atol=1e-10
48+
49+
@testset "no valid solutions" begin
50+
prob2 = remake(prob; p = [0.7, 0.7])
51+
sol2 = solve(prob2, alg)
52+
@test sol2.retcode == SciMLBase.ReturnCode.Infeasible
53+
end
54+
55+
@testset "closest root" begin
56+
prob3 = remake(prob; p = [0.5, 0.6], u0 = asin(0.4))
57+
sol3 = solve(prob3, alg)
58+
@test sin(sol3.u) 0.5 atol = 1e-10
59+
prob4 = remake(prob3; u0 = asin(0.7))
60+
sol4 = solve(prob4, alg)
61+
@test sin(sol4.u) 0.6 atol = 1e-10
62+
end
63+
end
64+
end
65+
66+
f! = function (du, u, p)
67+
du[1] = u[1] * u[1] - p[1] * u[2] + u[2] ^ 3 + 1
68+
du[2] = u[2] ^ 3 + 2 * p[2] * u[1] * u[2] + u[2]
69+
end
70+
71+
f = function (u, p)
72+
[u[1] * u[1] - p[1] * u[2] + u[2] ^ 3 + 1, u[2] ^ 3 + 2 * p[2] * u[1] * u[2] + u[2]]
73+
end
74+
75+
jac! = function (j, u, p)
76+
j[1, 1] = 2u[1]
77+
j[1, 2] = -p[1] + 3 * u[2]^2
78+
j[2, 1] = 2 * p[2] * u[2]
79+
j[2, 2] = 3 * u[2]^2 + 2 * p[2] * u[1] + 1
80+
end
81+
82+
jac = function (u, p)
83+
[2u[1] -p[1] + 3 * u[2]^2;
84+
2 * p[2] * u[2] 3 * u[2]^2 + 2 * p[2] * u[1] + 1]
85+
end
86+
87+
@testset "vector u - $name" for (rhs, jac, name) in [(f, nothing, "oop"), (f, jac, "oop + jac"), (f!, nothing, "iip"), (f!, jac!, "iip + jac")]
88+
@testset "`NonlinearProblem`" begin
89+
fn = NonlinearFunction(rhs; jac)
90+
prob = NonlinearProblem(fn, [1.0, 2.0], [2.0, 3.0])
91+
sol = solve(prob, alg)
92+
@test SciMLBase.successful_retcode(sol)
93+
@test f(sol.u, prob.p) [0.0, 0.0] atol = 1e-10
94+
95+
@testset "no real solutions" begin
96+
prob2 = remake(prob; p = zeros(2))
97+
sol2 = solve(prob2, alg)
98+
@test !SciMLBase.successful_retcode(sol2)
99+
end
100+
end
101+
102+
@testset "`HomotopyNonlinearFunction`" begin
103+
denominator = function (u, p)
104+
return [u[1] - p[3], u[2] - p[4]]
105+
end
106+
unpolynomialize = function (u, p)
107+
return [[cbrt(u[1]), sin(u[2] / 40)]]
108+
end
109+
polynomialize = function (u, p)
110+
return [u[1] ^ 3, 40asin(u[2])]
111+
end
112+
nlfn = NonlinearFunction(rhs; jac)
113+
fn = HomotopyNonlinearFunction(nlfn; denominator, polynomialize, unpolynomialize)
114+
prob = NonlinearProblem(fn, [1.0, 1.0], [2.0, 3.0, 4.0, 5.0])
115+
sol = solve(prob, alg)
116+
@test SciMLBase.successful_retcode(sol)
117+
@test f(polynomialize(sol.u, prob.p), prob.p) zeros(2) atol = 1e-10
118+
119+
@testset "some invalid solutions" begin
120+
prob2 = remake(prob; p = [2.0, 3.0, polynomialize(sol.u, prob.p)...])
121+
sol2 = solve(prob2, alg)
122+
@test !SciMLBase.successful_retcode(sol2)
123+
end
124+
end
125+
end

0 commit comments

Comments
 (0)