@@ -5,14 +5,16 @@ Optional keyword arguments give the tolerances `reltol` and `abstol`.
55and a `debug` boolean argument that prints out diagnostic information."""
66
77function newton1d {T} (f:: Function , f′:: Function , x:: Interval{T} ;
8- reltol= 10 eps (T), abstol= eps (T), debug= false )
8+ reltol= eps (T), abstol= eps (T), debug= false , debugroot = false )
99
1010 L = Interval{T}[]
1111
1212 R = Root{Interval{T}}[]
13+ reps = reps1 = 0
1314
1415 push! (L, x)
15-
16+ initial_width = ∞
17+ X = emptyinterval (T)
1618 while ! isempty (L)
1719 X = pop! (L)
1820
@@ -28,56 +30,111 @@ function newton1d{T}(f::Function, f′::Function, x::Interval{T};
2830 debug && println (" 0 ∉ f′(X)" )
2931
3032 while true
31- m = mid (X)
32- N = m - (f (Interval (m)) / f′ (X))
33-
34- debug && (print (" Newton step: " ); @show (X, X ∩ N))
3533
34+ m = mid (X)
35+ N = m - (f (interval (m)) / f′ (X))
36+
37+ debug && (print (" Newton step1: " ); @show (X, X ∩ N))
38+ if X == X ∩ N
39+ reps1 += 1
40+ if reps1 > 20
41+ reps1 = 0
42+ break
43+ end
44+ end
3645 X = X ∩ N
3746
38- if isempty (X)
47+ if ( isempty (X) || diam (X) == 0 )
3948 break
4049
41- elseif 0 ∈ f (Interval (prevfloat (m), nextfloat (m)))
42- push! (R, Root (X, :unique ))
43-
44- debug && @show " Root found" , X
50+ elseif 0 ∈ f (interval (prevfloat (mid (X)), nextfloat (mid (X))))
51+ n = fa = fb = 0
52+ root_exist = true
53+ while (n < 4 && (fa == 0 || fb == 0 ))
54+ if fa == 0
55+ if 0 ∈ f (interval (prevfloat (X. lo), nextfloat (X. lo)))
56+ fa = 1
57+ else
58+ N = X. lo - (f (interval (X. lo)) / f′ (X))
59+ X = X ∩ N
60+ if (isempty (X) || diam (X) == 0 )
61+ root_exist = false
62+ break
63+ end
64+ end
65+ end
66+ if fb == 0
67+ if 0 ∈ f (interval (prevfloat (X. hi), nextfloat (X. hi)))
68+ fb = 1
69+ else
70+ if 0 ∈ f (interval (prevfloat (mid (X)), nextfloat (mid (X))))
71+ N = X. hi - (f (interval (X. hi)) / f′ (X))
72+ else
73+ N = mid (X) - (f (interval (mid (X))) / f′ (X))
74+ end
75+ X = X ∩ N
76+ if (isempty (X) || diam (X) == 0 )
77+ root_exist = false
78+ break
79+ end
80+ end
81+ end
82+ N = mid (X) - (f (interval (mid (X))) / f′ (X))
83+ X = X ∩ N
84+ if (isempty (X) || diam (X) == 0 )
85+ root_exist = false
86+ break
87+ end
88+ n += 1
89+ end
90+ if root_exist
91+ push! (R, Root (X, :unique ))
92+ debugroot && @show " Root found" , X
93+ end
4594
4695 break
4796 end
4897 end
4998
5099 else
51- # 0 ∈ f'(X)
52-
100+ if diam (X) == initial_width
101+ reps += 1
102+ if reps > 10
103+ push! (R, Root (X, :unknown ))
104+ debugroot && @show " Repititive root found" , X
105+ reps = 0
106+ continue
107+ end
108+ end
109+ initial_width = diam (X)
53110 debug && println (" 0 ∈ f'(X)" )
54111
55112 expansion_pt = Inf
56113 # expansion point for the newton step might be m, X.lo or X.hi according to some conditions
57114
58- if 0 ∈ f (Interval ( mid (X)))
115+ if 0 ∈ f (interval ( prevfloat ( mid (X)), nextfloat ( mid (X) )))
59116 # 0 ∈ fⁱ(x)
60117
61118 debug && println (" 0 ∈ fⁱ(x)" )
62119
63- if 0 ∉ f (Interval ( X. lo))
120+ if 0 ∉ f (interval ( prevfloat ( X. lo), nextfloat (X . lo) ))
64121 expansion_pt = X. lo
65122
66- elseif 0 ∉ f (Interval ( X. hi))
123+ elseif 0 ∉ f (interval ( prevfloat ( X. hi), nextfloat (X . hi) ))
67124 expansion_pt = X. hi
68125
69126 else
70- x1 = mid (Interval (X. lo, mid (X)))
71- x2 = mid (Interval (mid (X), X. hi))
72- if 0 ∉ f (Interval ( x1)) || 0 ∉ f (Interval (x2 ))
73- push! (L, Interval (X. lo, m))
74- push! (L, Interval (m, X. hi))
127+ x1 = mid (interval (X. lo, mid (X)))
128+ x2 = mid (interval (mid (X), X. hi))
129+ if 0 ∉ f (interval ( prevfloat ( x1), nextfloat (x1))) || 0 ∉ f (interval ( prevfloat (x2), nextfloat (x2) ))
130+ push! (L, interval (X. lo, m))
131+ push! (L, interval (m, X. hi))
75132 continue
76133
77134 else
78135 push! (R, Root (X, :unknown ))
79136
80- debug && @show " Multiple root found" , X
137+ debugroot && @show " Multiple root found" , X
81138
82139 continue
83140 end
@@ -91,7 +148,7 @@ function newton1d{T}(f::Function, f′::Function, x::Interval{T};
91148 if (diam (X)/ mag (X)) < reltol && diam (f (X)) < abstol
92149 push! (R, Root (X, :unknown ))
93150
94- debug && @show " Tolerance root found" , X
151+ debugroot && @show " Tolerance root found" , X
95152
96153 continue
97154 end
@@ -102,28 +159,27 @@ function newton1d{T}(f::Function, f′::Function, x::Interval{T};
102159 expansion_pt = mid (X)
103160 end
104161
105- initial_width = diam (X)
106162
107- a = f (Interval (expansion_pt))
163+ a = f (interval (expansion_pt))
108164 b = f′ (X)
109165
110166 if 0 < b. hi && 0 > b. lo && 0 ∉ a
111167 if a. hi < 0
112- push! (L, X ∩ (expansion_pt - Interval (- Inf , a. hi / b. hi)))
113- push! (L, X ∩ (expansion_pt - Interval (a. hi / b. lo, Inf )))
168+ push! (L, X ∩ (expansion_pt - interval (- Inf , a. hi / b. hi)))
169+ push! (L, X ∩ (expansion_pt - interval (a. hi / b. lo, Inf )))
114170
115171 elseif a. lo > 0
116- push! (L, X ∩ (expansion_pt - Interval (- Inf , a. lo / b. lo)))
117- push! (L, X ∩ (expansion_pt - Interval (a. lo / b. hi, Inf )))
172+ push! (L, X ∩ (expansion_pt - interval (- Inf , a. lo / b. lo)))
173+ push! (L, X ∩ (expansion_pt - interval (a. lo / b. hi, Inf )))
118174
119175 end
120176
121177 continue
122178
123179 else
124- N = expansion_pt - (f (Interval (expansion_pt))/ f′ (X))
180+ N = expansion_pt - (f (interval (expansion_pt))/ f′ (X))
125181
126- debug && (print (" Newton step : " ); @show (X, X ∩ N))
182+ debug && (print (" Newton step2 : " ); @show (X, X ∩ N))
127183
128184 X = X ∩ N
129185 m = mid (X)
@@ -133,11 +189,6 @@ function newton1d{T}(f::Function, f′::Function, x::Interval{T};
133189 end
134190 end
135191
136- if diam (X) > initial_width/ 2
137- push! (L, Interval (m, X. hi))
138- X = Interval (X. lo, m)
139- end
140-
141192 push! (L, X)
142193 end
143194 end
0 commit comments