Skip to content

Commit 25ebe4c

Browse files
authored
Merge pull request #70 from gwater/smiley_tests
Add some hard test cases from Smiley and Chun (2001)
2 parents 6491d43 + 2c7566b commit 25ebe4c

File tree

3 files changed

+258
-0
lines changed

3 files changed

+258
-0
lines changed

test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ using Base.Test
66
include("roots.jl")
77
include("newton1d.jl")
88
include("quadratic.jl")
9+
include("test_smiley.jl")

test/smiley_examples.jl

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
# examples from
2+
# M. W. Smiley and C. Chun, J. Comput. Appl. Math. **137**, 293 (2001).
3+
# https://doi.org/10.1016/S0377-0427(00)00711-1
4+
5+
module SmileyExample22
6+
7+
using IntervalArithmetic
8+
using StaticArrays
9+
10+
const title = "Smiley and Chun (2001), Example 2.2"
11+
12+
f(x) = SVector(
13+
x[1]^2 + 4 * x[2]^2 - 4,
14+
x[2] * (x[1] - 1.995) * (x[2] - x[1]^2) * (x[2] - x[1] + 1)
15+
)
16+
17+
# contains all 8 reported roots
18+
const region = IntervalBox(-3..3, -3..3)
19+
20+
# only three roots are reported explicitely:
21+
# (2, 0) and (1.995, ±0.071)
22+
23+
end
24+
25+
module SmileyExample52
26+
27+
using IntervalArithmetic
28+
using StaticArrays
29+
30+
const title = "Smiley and Chun (2001), Example 5.2"
31+
32+
const c0 = 1
33+
const a0 = 0.5
34+
const b0 = 0.5
35+
const d01 = 0.2
36+
const d02 = -0.7
37+
const r1 = 1
38+
const r2 = 2
39+
const m = 3
40+
const θs = [i * pi / m for i in 1:m]
41+
_v(θ) = -(a0 * cos(θ) + b0 * sin(θ)) / c0
42+
const vs = _v.(θs)
43+
44+
_a(θ, v) = b0 * v - c0 * sin(θ)
45+
const as = _a.(θs, vs)
46+
_b(θ, v) = c0 * cos(θ) - a0 * v
47+
const bs = _b.(θs, vs)
48+
_c(θ) = a0 * sin(θ) - b0 * cos(θ)
49+
const cs = _c.(θs)
50+
_d(c) = d01 * c / c0
51+
const ds = _d.(cs)
52+
53+
f(x) = SVector(
54+
(x[1]^2 + x[2]^2 + x[3]^2 - r1^2) * (x[1]^2 + x[2]^2 + x[3]^2 - r2^2),
55+
(a0 * x[1] + b0 * x[2] + c0 * x[3] - d01) *
56+
(a0 * x[1] + b0 * x[2] + c0 * x[3] - d02),
57+
prod(as * x[1] .+ bs * x[2] .+ cs * x[3] .- ds)
58+
)
59+
60+
# contains all 24 reported roots
61+
const region = IntervalBox(-3..3, -3..3, -3..3)
62+
63+
const known_roots = [
64+
IntervalBox(-1.933009 ± 1e-6, -0.300000 ± 1e-6, 0.416504 ± 1e-6),
65+
IntervalBox(-1.701684 ± 1e-6, 0.000000 ± 1e-6, 1.050842 ± 1e-6),
66+
IntervalBox(-1.258803 ± 1e-6, 1.360696 ± 1e-6, -0.750946 ± 1e-6),
67+
IntervalBox(-1.044691 ± 1e-6, -1.589843 ± 1e-6, 0.617267 ± 1e-6),
68+
IntervalBox(-0.996600 ± 1e-6, 1.726162 ± 1e-6, -0.164780 ± 1e-6),
69+
70+
IntervalBox(-0.951026 ± 1e-6, -0.300000 ± 1e-6, -0.074486 ± 1e-6),
71+
IntervalBox(-0.800000 ± 1e-6, -0.000000 ± 1e-6, 0.600000 ± 1e-6),
72+
IntervalBox(-0.776373 ± 1e-6, -1.344718 ± 1e-6, 1.260546 ± 1e-6),
73+
IntervalBox(-0.717665 ± 1e-6, 0.423418 ± 1e-6, -0.552876 ± 1e-6),
74+
IntervalBox(-0.592072 ± 1e-6, -0.805884 ± 1e-6, -0.001021 ± 1e-6),
75+
76+
IntervalBox(-0.499927 ± 1e-6, 0.865900 ± 1e-6, 0.017013 ± 1e-6),
77+
IntervalBox(-0.360640 ± 1e-6, -0.624646 ± 1e-6, 0.692643 ± 1e-6),
78+
IntervalBox( 0.082249 ± 1e-6, -0.962075 ± 1e-6, -0.260086 ± 1e-6),
79+
IntervalBox( 0.085220 ± 1e-6, 0.367221 ± 1e-6, -0.926221 ± 1e-6),
80+
IntervalBox( 0.453788 ± 1e-6, 0.785984 ± 1e-6, -0.419886 ± 1e-6),
81+
82+
IntervalBox( 0.464511 ± 1e-6, -0.804557 ± 1e-6, 0.370022 ± 1e-6),
83+
IntervalBox( 0.511026 ± 1e-6, -0.300000 ± 1e-6, -0.805513 ± 1e-6),
84+
# the following two roots are suspect, first column probably reported in error
85+
#IntervalBox( 0.623386 ± 1e-6, 1.151180 ± 1e-6, -1.544510 ± 1e-6),
86+
#IntervalBox( 0.869521 ± 1e-6, -1.899353 ± 1e-6, -0.062016 ± 1e-6),
87+
IntervalBox( 0.537839 ± 1e-6, 1.151180 ± 1e-6, -1.544510 ± 1e-6),
88+
IntervalBox( 0.623386 ± 1e-6, -1.899353 ± 1e-6, -0.062016 ± 1e-6),
89+
IntervalBox( 0.869521 ± 1e-6, 1.506056 ± 1e-6, -0.987788 ± 1e-6),
90+
91+
IntervalBox( 0.960000 ± 1e-6, 0.000000 ± 1e-6, -0.280000 ± 1e-6),
92+
IntervalBox( 0.961183 ± 1e-6, -1.664819 ± 1e-6, 0.551817 ± 1e-6),
93+
IntervalBox( 1.493009 ± 1e-6, -0.300000 ± 1e-6, -1.296504 ± 1e-6),
94+
IntervalBox( 1.861684 ± 1e-6, 0.000000 ± 1e-6, -0.730842 ± 1e-6),
95+
]
96+
97+
end
98+
99+
# example 5.4, rescaled form
100+
module SmileyExample54
101+
102+
using IntervalArithmetic
103+
using StaticArrays
104+
105+
const title = "Smiley and Chun (2001), Example 5.4"
106+
107+
const c11 = 1.069e-5
108+
const c12 = 2e2
109+
const c13 = 1e5
110+
const c14 = -1.8e5
111+
const c15 = -1.283e-4
112+
const c21 = 2e-2
113+
const c22 = 1e1
114+
const c23 = -1e1
115+
116+
f(t) = SVector(
117+
c11 * t[1]^4 + c12 * t[1]^3 * t[2] + c13 * t[1]^3 + c14 * t[1] + c15,
118+
c21 * t[1] * t[2]^2 + c22 * t[2]^2 + c23
119+
)
120+
121+
# contains all 7 reported roots
122+
const region = IntervalBox(-5.1e2..1.4, -5.1e2..1.1)
123+
124+
const known_roots = [
125+
IntervalBox(-1.34298 ± 1e-5, -1.00134 ± 1e-5),
126+
IntervalBox(-1.34030 ± 1e-5, 1.00134 ± 1e-5),
127+
IntervalBox( 1.34030 ± 1e-5, 0.99866 ± 1e-5),
128+
IntervalBox( 1.34298 ± 1e-5, -0.99866 ± 1e-5),
129+
# following three roots are not reported precisely
130+
IntervalBox(-7e-10 ± 1e-10, 1 ± 1e-5),
131+
IntervalBox(-7e-10 ± 1e-10, -1 ± 1e-5),
132+
IntervalBox(-5e2 ± 1, -5e2 ± 1)
133+
]
134+
135+
end
136+
137+
module SmileyExample55
138+
139+
using IntervalArithmetic
140+
using StaticArrays
141+
142+
const title = "Smiley and Chun (2001), Example 5.5"
143+
144+
const μ1 = pi / 10
145+
const μ2 = pi / 5
146+
const α = 5
147+
const D1 = exp(-2μ1)
148+
const D2 = exp(-2μ2)
149+
const C1 = (1 - D1) / 2μ1
150+
const C2 = (1 - D2) / 2μ2
151+
152+
g(x) = SVector(C1 * (x[3] - α * sin(x[1]) * cos(x[2])) + x[1],
153+
C2 * (x[4] - α * cos(x[1]) * sin(x[2])) + x[2],
154+
D1 * (x[3] - α * sin(x[1]) * cos(x[2])),
155+
D2 * (x[4] - α * cos(x[1]) * sin(x[2])))
156+
157+
f(x) = (g g)(x) .- x
158+
159+
# contains all 41 reported roots of f
160+
const region =
161+
IntervalBox(-1.02pi..1.02pi, -1.02pi..1.02pi, -0.5pi..0.5pi, -0.5pi..0.5pi)
162+
163+
# roots from
164+
# C. S. Hsu and R. S. Guttalu, Trans. ASME **50**, 858 (1983).
165+
# http://dx.doi.org/10.1115/1.3167157
166+
const known_roots = [
167+
# period 1 points
168+
IntervalBox(-pi ± 0, -pi ± 0, 0 ± 0, 0 ± 0),
169+
IntervalBox(-pi ± 0, 0 ± 0, 0 ± 0, 0 ± 0),
170+
IntervalBox(-pi ± 0, pi ± 0, 0 ± 0, 0 ± 0),
171+
IntervalBox(-0.5pi ± 0, -0.5pi ± 0, 0 ± 0, 0 ± 0),
172+
IntervalBox(-0.5pi ± 0, 0.5pi ± 0, 0 ± 0, 0 ± 0),
173+
174+
IntervalBox( 0 ± 0, -pi ± 0, 0 ± 0, 0 ± 0),
175+
IntervalBox( 0 ± 0, 0 ± 0, 0 ± 0, 0 ± 0),
176+
IntervalBox( 0 ± 0, pi ± 0, 0 ± 0, 0 ± 0),
177+
IntervalBox( 0.5pi ± 0, -0.5pi ± 0, 0 ± 0, 0 ± 0),
178+
IntervalBox( 0.5pi ± 0, 0.5pi ± 0, 0 ± 0, 0 ± 0),
179+
180+
IntervalBox( pi ± 0, -pi ± 0, 0 ± 0, 0 ± 0),
181+
IntervalBox( pi ± 0, 0 ± 0, 0 ± 0, 0 ± 0),
182+
IntervalBox( pi ± 0, pi ± 0, 0 ± 0, 0 ± 0),
183+
# period 2 points
184+
IntervalBox( (0.33419 ± 1e-5)pi, 0 ± 0, (0.48025 ± 1e-5)pi, 0 ± 0),
185+
IntervalBox(-(0.33419 ± 1e-5)pi, 0 ± 0, -(0.48025 ± 1e-5)pi, 0 ± 0),
186+
187+
IntervalBox( 0 ± 0, (0.24702 ± 1e-5)pi, 0 ± 0, (0.24699 ± 1e-5)pi),
188+
IntervalBox( 0 ± 0, -(0.24702 ± 1e-5)pi, 0 ± 0, -(0.24699 ± 1e-5)pi),
189+
IntervalBox( (0.09648 ± 1e-5)pi, (0.18318 ± 1e-5)pi, (0.13864 ± 1e-5)pi, (0.18316 ± 1e-5)pi),
190+
IntervalBox(-(0.09648 ± 1e-5)pi, -(0.18318 ± 1e-5)pi, -(0.13864 ± 1e-5)pi, -(0.18316 ± 1e-5)pi),
191+
IntervalBox(-(0.09648 ± 1e-5)pi, (0.18318 ± 1e-5)pi, -(0.13864 ± 1e-5)pi, (0.18316 ± 1e-5)pi),
192+
193+
IntervalBox( (0.09648 ± 1e-5)pi, -(0.18318 ± 1e-5)pi, (0.13864 ± 1e-5)pi, -(0.18316 ± 1e-5)pi),
194+
IntervalBox(-(0.66580 ± 1e-5)pi, -(1 ± 0)pi, (0.48025 ± 1e-5)pi, 0 ± 0),
195+
IntervalBox( (0.66580 ± 1e-5)pi, -(1 ± 0)pi, -(0.48025 ± 1e-5)pi, 0 ± 0),
196+
IntervalBox(-(0.66580 ± 1e-5)pi, (1 ± 0)pi, (0.48025 ± 1e-5)pi, 0 ± 0),
197+
IntervalBox( (0.66580 ± 1e-5)pi, (1 ± 0)pi, -(0.48025 ± 1e-5)pi, 0 ± 0),
198+
199+
IntervalBox( (1 ± 0)pi, -(0.75298 ± 1e-5)pi, 0 ± 0, (0.24699 ± 1e-5)pi),
200+
IntervalBox( (1 ± 0)pi, (0.75298 ± 1e-5)pi, 0 ± 0, -(0.24699 ± 1e-5)pi),
201+
IntervalBox(-(1 ± 0)pi, -(0.75298 ± 1e-5)pi, 0 ± 0, (0.24699 ± 1e-5)pi),
202+
IntervalBox(-(1 ± 0)pi, (0.75298 ± 1e-5)pi, 0 ± 0, -(0.24699 ± 1e-5)pi),
203+
IntervalBox( (0.90352 ± 1e-5)pi, (0.81682 ± 1e-5)pi, -(0.13864 ± 1e-5)pi, -(0.18316 ± 1e-5)pi),
204+
205+
IntervalBox(-(0.90352 ± 1e-5)pi, -(0.81682 ± 1e-5)pi, (0.13864 ± 1e-5)pi, (0.18316 ± 1e-5)pi),
206+
IntervalBox( (0.90352 ± 1e-5)pi, -(0.81682 ± 1e-5)pi, -(0.13864 ± 1e-5)pi, (0.18316 ± 1e-5)pi),
207+
IntervalBox(-(0.90352 ± 1e-5)pi, (0.81682 ± 1e-5)pi, (0.13864 ± 1e-5)pi, -(0.18316 ± 1e-5)pi),
208+
IntervalBox( (0.34989 ± 1e-5)pi, -(0.64408 ± 1e-5)pi, -(0.21572 ± 1e-5)pi, -(0.14406 ± 1e-5)pi),
209+
IntervalBox( (0.65011 ± 1e-5)pi, -(0.35592 ± 1e-5)pi, (0.21572 ± 1e-5)pi, (0.14406 ± 1e-5)pi),
210+
211+
IntervalBox( (0.34989 ± 1e-5)pi, (0.64408 ± 1e-5)pi, -(0.21572 ± 1e-5)pi, (0.14406 ± 1e-5)pi),
212+
IntervalBox( (0.65011 ± 1e-5)pi, (0.35592 ± 1e-5)pi, (0.21572 ± 1e-5)pi, -(0.14406 ± 1e-5)pi),
213+
IntervalBox(-(0.34989 ± 1e-5)pi, -(0.64408 ± 1e-5)pi, (0.21572 ± 1e-5)pi, -(0.14406 ± 1e-5)pi),
214+
IntervalBox(-(0.65011 ± 1e-5)pi, -(0.35592 ± 1e-5)pi, -(0.21572 ± 1e-5)pi, (0.14406 ± 1e-5)pi),
215+
IntervalBox(-(0.34989 ± 1e-5)pi, (0.64408 ± 1e-5)pi, (0.21572 ± 1e-5)pi, (0.14406 ± 1e-5)pi),
216+
217+
IntervalBox(-(0.65011 ± 1e-5)pi, (0.35592 ± 1e-5)pi, -(0.21572 ± 1e-5)pi, -(0.14406 ± 1e-5)pi)
218+
]
219+
220+
end

test/test_smiley.jl

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
include("smiley_examples.jl")
2+
3+
using Base.Test
4+
using IntervalArithmetic, IntervalRootFinding
5+
using SmileyExample22, SmileyExample52, SmileyExample54, SmileyExample55
6+
7+
function test_all_unique(xs)
8+
for x in xs
9+
@test x.status == :unique
10+
end
11+
return nothing
12+
end
13+
14+
const tol = 1e-6
15+
const method = Newton # NOTE: Bisection method performs badly in all examples
16+
17+
info("testing method $(method)")
18+
19+
@testset "$(SmileyExample22.title)" begin
20+
roots_found = roots(SmileyExample22.f, SmileyExample22.region, method, tol)
21+
@test length(roots_found) == 8
22+
test_all_unique(roots_found)
23+
# no reference data for roots given
24+
end
25+
26+
for example in (SmileyExample52, SmileyExample54) #, SmileyExample55)
27+
@testset "$(example.title)" begin
28+
roots_found = roots(example.f, example.region, method, tol)
29+
@test length(roots_found) == length(example.known_roots)
30+
test_all_unique(roots_found)
31+
for rf in roots_found
32+
# check there is exactly one known root for each found root
33+
@test sum(!isempty(rk rf.interval)
34+
for rk in example.known_roots) == 1
35+
end
36+
end
37+
end

0 commit comments

Comments
 (0)