-
Notifications
You must be signed in to change notification settings - Fork 17
/
root_finding.jl
98 lines (64 loc) · 2.54 KB
/
root_finding.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# This file is part of the ValidatedNumerics.jl package; MIT licensed
using ForwardDiff
const D = ForwardDiff.derivative
immutable Root{T<:Real}
interval::Interval{T}
root_type::Symbol
end
show(io::IO, root::Root) = print(io, "Root($(root.interval), :$(root.root_type))")
is_unique{T}(root::Root{T}) = root.root_type == :unique
⊆(a::Interval, b::Root) = a ⊆ b.interval # the Root object has the interval in the first entry
⊆(a::Root, b::Root) = a.interval ⊆ b.interval
# include("automatic_differentiation.jl")
include("newton.jl")
include("krawczyk.jl")
function find_roots{T}(f::Function, a::Interval{T}, method::Function = newton;
tolerance = eps(T), debug = false, maxlevel = 30)
method(f, a; tolerance=tolerance, debug=debug, maxlevel=maxlevel)
end
function find_roots{T}(f::Function, f_prime::Function, a::Interval{T}, method::Function=newton;
tolerance=eps(T), debug=false, maxlevel=30)
method(f, f_prime, a; tolerance=tolerance, debug=debug, maxlevel=maxlevel)
end
function find_roots(f::Function, a::Real, b::Real, method::Function=newton;
tolerance=eps(1.0*a), debug=false, maxlevel=30, precision::Int=-1)
if precision >= 0
with_interval_precision(precision) do
find_roots(f, @interval(a, b), method; tolerance=tolerance, debug=debug, maxlevel=maxlevel)
end
else # use current precision
find_roots(f, @interval(a, b), method; tolerance=tolerance, debug=debug, maxlevel=maxlevel)
end
end
function find_roots_midpoint(f::Function, a::Real, b::Real, method::Function=newton;
tolerance=eps(1.0*a), debug=false, maxlevel=30, precision=-1)
roots = find_roots(f, a, b, method; tolerance=tolerance, debug=debug, maxlevel=maxlevel, precision=precision)
T = eltype(roots[1].interval)
midpoints = T[]
radii = T[]
root_symbols = Symbol[] # :unique or :unknown
if length(roots) == 0
return (midpoints, radii, root_symbols) # still empty
end
for root in roots
midpoint, radius = midpoint_radius(root.interval)
push!(midpoints, midpoint)
push!(radii, radius)
push!(root_symbols, root.root_type)
end
(midpoints, radii, root_symbols)
end
function Base.lexcmp{T}(a::Interval{T}, b::Interval{T})
#@show a, b
if a.lo < b.lo
return -1
elseif a.lo == b.lo
if a.hi < b.hi
return -1
else
return 0
end
end
return 1
end
Base.lexcmp{T}(a::Root{T}, b::Root{T}) = lexcmp(a.interval, b.interval)