Skip to content

Commit a5c07a1

Browse files
committed
Inner iteration to improve choice of point of expansion
1 parent b6de4a3 commit a5c07a1

File tree

2 files changed

+32
-8
lines changed

2 files changed

+32
-8
lines changed

src/linear_eq.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,17 @@ function linear_hull(M::AbstractMatrix, r::AbstractArray)
153153
n = size(M, 1)
154154

155155
((M, r) = preconditioner(M, r))
156+
M = interval.((2*eye(n) - sup.(M)), sup.(M))
156157
M_lo = inf.(M)
157158
M_hi = sup.(M)
159+
P = eye(n)
158160
if all(.≤(M_lo, zero(M_lo)))
159161
return M \ r
160162
end
161163
P = inv(M_lo)
164+
if any(isinf.(P)) || any(isnan.(P))
165+
return gauss_seidel_interval(M, r, precondition=false, maxiter=2)
166+
end
162167
if all(.≤(eye(n), (P)))
163168
H1 = P * sup.(r)
164169
C = 1 ./ (2diag(P) - 1)

src/newtonnd.jl

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
using IntervalRootFinding, IntervalArithmetic, StaticArrays, ForwardDiff, BenchmarkTools, Compat
12
"""
23
Preconditions the matrix A and b with the inverse of mid(A)
34
"""
45
function 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
110125
end
111126

112127
newtonnd(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 - 2x)
130+
f(X) = f(X...)
131+
X = (0..1.23) × (0..1.123)

0 commit comments

Comments
 (0)