Skip to content

Commit b6de4a3

Browse files
committed
Initial implementation of multidim interval Newton method
1 parent 375deab commit b6de4a3

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

src/newtonnd.jl

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
"""
2+
Preconditions the matrix A and b with the inverse of mid(A)
3+
"""
4+
function preconditioner(A::AbstractMatrix, b::AbstractArray)
5+
6+
Aᶜ = mid.(A)
7+
B = pinv(Aᶜ) # TODO If Aᶜ is singular
8+
9+
return B*A, B*b
10+
11+
end
12+
13+
function newtonnd(f::Function, deriv::Function, x::IntervalBox{NUM, T}; reltol=eps(T), abstol=eps(T), debug=false, debugroot=false) where {T<:AbstractFloat} where {NUM} # TODO Incorporate Hull and Box consistencies
14+
15+
L = IntervalBox{NUM, T}[] # Array to hold the interval boxes still to be processed
16+
17+
R = Root{IntervalBox{NUM, T}}[] # Array to hold the `root` objects obtained
18+
19+
push!(L, x) # Initialize
20+
n = size(X, 1)
21+
while !isempty(L) # Until all interval boxes have been processed
22+
Xᴵ = pop!(L) # Process next interval box
23+
if !all(0 .∈ f(Xᴵ))
24+
continue
25+
end
26+
Xᴵ¹ = copy(Xᴵ)
27+
debug && (print("Current interval popped: "); println(Xᴵ))
28+
29+
if (isempty(Xᴵ))
30+
continue
31+
end
32+
if diam(Xᴵ) < reltol
33+
if max((abs.(IntervalBox(f(Xᴵ))))...) < abstol
34+
35+
debugroot && @show "Tolerance root found", Xᴵ
36+
37+
push!(R, Root(Xᴵ, :unknown))
38+
continue
39+
else
40+
continue
41+
end
42+
end
43+
44+
next_iter = false
45+
46+
while true
47+
48+
use_B = false
49+
next_iter = false
50+
51+
initial_width = diam(Xᴵ)
52+
debug && (print("Current interval popped: "); println(Xᴵ))
53+
if use_B
54+
# TODO Compute X using B in Step 19
55+
else
56+
X = mid(Xᴵ)
57+
end
58+
59+
J = SMatrix{n}{n}(deriv(Xᴵ)) # either jacobian or calculated using slopes
60+
61+
# Xᴵ = IntervalBox((X + linear_hull(J, -f(interval.(X)))) .∩ Xᴵ)
62+
Xᴵ = IntervalBox((X + (J \ -f(interval.(X)))) .∩ Xᴵ)
63+
64+
if (isempty(Xᴵ))
65+
next_iter = true
66+
break
67+
end
68+
69+
if diam(Xᴵ) < reltol
70+
if max((abs.(IntervalBox(f(Xᴵ))))...) < abstol
71+
72+
debugroot && @show "Tolerance root found", Xᴵ
73+
next_iter = true
74+
push!(R, Root(Xᴵ, :unknown))
75+
break
76+
else
77+
next_iter = true
78+
break
79+
end
80+
end
81+
82+
if all(0 .∈ f(interval.(X))) && initial_width > 0.9diam(Xᴵ)
83+
next_iter = true
84+
push!(R, Root(Xᴵ, :unique))
85+
break
86+
end
87+
88+
if diam(Xᴵ) > initial_width / 8
89+
break
90+
end
91+
92+
#Criterion C
93+
94+
95+
end
96+
97+
if next_iter
98+
continue
99+
end
100+
101+
if 0.25 * diam(Xᴵ¹) max((diam.(Xᴵ¹) .- diam.(Xᴵ))...)
102+
push!(L, Xᴵ)
103+
else
104+
push!(L, bisect(Xᴵ)...)
105+
end
106+
end
107+
108+
R
109+
110+
end
111+
112+
newtonnd(f::Function, x::IntervalBox{NUM, T}; args...) where {T<:AbstractFloat} where {NUM} = newtonnd(f, x->ForwardDiff.jacobian(f,x), x; args...)

0 commit comments

Comments
 (0)