Skip to content
This repository was archived by the owner on Nov 26, 2025. It is now read-only.

Commit b050477

Browse files
dpsanderslbenet
authored andcommitted
Fix 1D Newton by checking correctly whether midpoint is exactly a root (#254)
* Fix 1D Newton by checking correctly whether midpoint is exactly a root * Fix Krawczyk with new definition of guarded_mid * Fix Krawczyk and logistic tests * Fix Krawczyk
1 parent 2d5f2a9 commit b050477

File tree

3 files changed

+29
-9
lines changed

3 files changed

+29
-9
lines changed

src/root_finding/krawczyk.jl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ does not contain zero, and the second is the inverse of its derivative"""
1010
function guarded_derivative_midpoint{T}(f::Function, f_prime::Function, x::Interval{T})
1111

1212
α = convert(T, 0.46875) # close to 0.5, but exactly representable as a floating point
13-
m = Interval( guarded_mid(x) )
13+
# m = Interval( guarded_mid(f, x) )
14+
m = Interval(mid(x))
1415

1516
C = inv(f_prime(m))
1617

1718
# Check that 0 is not in C; if so, consider another point rather than m
1819
i = 0
19-
while zero(T) C
20+
while zero(T) C || isempty(C)
2021
m = Interval( α*x.lo + (one(T)-α)*x.hi )
2122
C = inv(f_prime(m))
2223

@@ -70,12 +71,12 @@ function krawczyk{T}(f::Function, f_prime::Function, x::Interval{T}, level::Int=
7071

7172
isempty(Kx x) && return Root{T}[] # [(x, :none)]
7273

73-
if Kx x
74+
if Kx x # isinterior
7475
debug && (print("Refining "); @show(x))
7576
return krawczyk_refine(f, f_prime, Kx, tolerance=tolerance, debug=debug)
7677
end
7778

78-
m = guarded_mid(x)
79+
m = guarded_mid(f, x)
7980

8081
debug && @show(x,m)
8182

src/root_finding/newton.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44

55
# What is this guarded_mid for? Shouldn't it be checking if f(m)==0?
66
doc"""Returns the midpoint of the interval x, slightly shifted in case
7-
it is zero"""
8-
function guarded_mid{T}(x::Interval{T})
7+
the midpoint is an exact root"""
8+
function guarded_mid{T}(f, x::Interval{T})
99
m = mid(x)
10-
if m == zero(T) # midpoint exactly 0
10+
11+
if f(m) == 0 # midpoint exactly a root
1112
α = convert(T, 0.46875) # close to 0.5, but exactly representable as a floating point
1213
m = α*x.lo + (one(T)-α)*x.hi # displace to another point in the interval
1314
end
@@ -19,7 +20,7 @@ end
1920

2021

2122
function N{T}(f::Function, x::Interval{T}, deriv::Interval{T})
22-
m = guarded_mid(x)
23+
m = guarded_mid(f, x)
2324
m = Interval(m)
2425

2526
m - (f(m) / deriv)
@@ -85,7 +86,7 @@ function newton{T}(f::Function, f_prime::Function, x::Interval{T}, level::Int=0;
8586
return newton_refine(f, f_prime, Nx, tolerance=tolerance, debug=debug)
8687
end
8788

88-
m = guarded_mid(x)
89+
m = guarded_mid(f, x)
8990

9091
debug && @show(x,m)
9192

test/root_finding_tests/findroots.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,24 @@ end
147147
end
148148
end
149149

150+
@testset "Iterated logistic function fixed points" begin
151+
(f, g) = x -> f(g(x))
152+
iterate(f, n) = n == 1 ? f : f iterate(f, n-1)
153+
154+
f(x) = 4x*(1-x) # logistic map
155+
156+
for n in 1:10
157+
g = x -> iterate(f, n)(x) - x # look for fixed points of f^n
158+
159+
roots = newton(g, 0..1)
160+
@test length(roots) == 2^n
161+
162+
roots = krawczyk(g, 0..1)
163+
@test length(roots) == 2^n
164+
165+
end
166+
end
167+
150168

151169

152170
# Example of a function with a double root at 0 from Burden & Faires, 9th ed, p.84

0 commit comments

Comments
 (0)