1+ using IntervalRootFinding, IntervalArithmetic, StaticArrays, ForwardDiff, BenchmarkTools, Compat
12"""
23Preconditions the matrix A and b with the inverse of mid(A)
34"""
45function preconditioner (A:: AbstractMatrix , b:: AbstractArray )
56
67 Aᶜ = mid .(A)
7- B = pinv (Aᶜ) # TODO If Aᶜ is singular
8+ B = inv (Aᶜ) # TODO If Aᶜ is singular
89
910 return B* A, B* b
1011
@@ -23,7 +24,10 @@ function newtonnd(f::Function, deriv::Function, x::IntervalBox{NUM, T}; reltol=e
2324 if ! all (0 .∈ f (Xᴵ))
2425 continue
2526 end
27+
2628 Xᴵ¹ = copy (Xᴵ)
29+ use_B = false
30+
2731 debug && (print (" Current interval popped: " ); println (Xᴵ))
2832
2933 if (isempty (Xᴵ))
@@ -45,22 +49,33 @@ function newtonnd(f::Function, deriv::Function, x::IntervalBox{NUM, T}; reltol=e
4549
4650 while true
4751
48- use_B = false
4952 next_iter = false
5053
5154 initial_width = diam (Xᴵ)
5255 debug && (print (" Current interval popped: " ); println (Xᴵ))
56+ X = mid (Xᴵ)
5357 if use_B
54- # TODO Compute X using B in Step 19
55- else
56- X = mid (Xᴵ)
58+ for i in 1 : 3
59+ z = X .- B * f (X)
60+ if all (z .∈ Xᴵ)
61+ if max (abs .(f (z))... ) ≥ max (abs .(f (X))... )
62+ break
63+ end
64+ X = z
65+ else
66+ break
67+ end
68+ end
69+ if any (X .∉ Xᴵ)
70+ X = mid .(Xᴵ)
71+ end
5772 end
5873
5974 J = SMatrix{n}{n}(deriv (Xᴵ)) # either jacobian or calculated using slopes
60-
61- # Xᴵ = IntervalBox((X + linear_hull(J, -f(interval.(X)) )) .∩ Xᴵ)
75+ B, r = preconditioner (J, - f ( interval .(X)))
76+ # Xᴵ = IntervalBox((X + linear_hull(B, r, precondition=false )) .∩ Xᴵ)
6277 Xᴵ = IntervalBox ((X + (J \ - f (interval .(X)))) .∩ Xᴵ)
63-
78+ use_B = true
6479 if (isempty (Xᴵ))
6580 next_iter = true
6681 break
@@ -110,3 +125,7 @@ function newtonnd(f::Function, deriv::Function, x::IntervalBox{NUM, T}; reltol=e
110125end
111126
112127newtonnd (f:: Function , x:: IntervalBox{NUM, T} ; args... ) where {T<: AbstractFloat } where {NUM} = newtonnd (f, x-> ForwardDiff. jacobian (f,x), x; args... )
128+
129+ f (x, y) = SVector (x^ 2 + y^ 2 - 1 , y - 2 x)
130+ f (X) = f (X... )
131+ X = (0 .. 1.23 ) × (0 .. 1.123 )
0 commit comments