@@ -5,14 +5,16 @@ Optional keyword arguments give the tolerances `reltol` and `abstol`.
5
5
and a `debug` boolean argument that prints out diagnostic information."""
6
6
7
7
function 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 )
9
9
10
10
L = Interval{T}[]
11
11
12
12
R = Root{Interval{T}}[]
13
+ reps = reps1 = 0
13
14
14
15
push! (L, x)
15
-
16
+ initial_width = ∞
17
+ X = emptyinterval (T)
16
18
while ! isempty (L)
17
19
X = pop! (L)
18
20
@@ -28,56 +30,111 @@ function newton1d{T}(f::Function, f′::Function, x::Interval{T};
28
30
debug && println (" 0 ∉ f′(X)" )
29
31
30
32
while true
31
- m = mid (X)
32
- N = m - (f (Interval (m)) / f′ (X))
33
-
34
- debug && (print (" Newton step: " ); @show (X, X ∩ N))
35
33
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
36
45
X = X ∩ N
37
46
38
- if isempty (X)
47
+ if ( isempty (X) || diam (X) == 0 )
39
48
break
40
49
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
45
94
46
95
break
47
96
end
48
97
end
49
98
50
99
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)
53
110
debug && println (" 0 ∈ f'(X)" )
54
111
55
112
expansion_pt = Inf
56
113
# expansion point for the newton step might be m, X.lo or X.hi according to some conditions
57
114
58
- if 0 ∈ f (Interval ( mid (X)))
115
+ if 0 ∈ f (interval ( prevfloat ( mid (X)), nextfloat ( mid (X) )))
59
116
# 0 ∈ fⁱ(x)
60
117
61
118
debug && println (" 0 ∈ fⁱ(x)" )
62
119
63
- if 0 ∉ f (Interval ( X. lo))
120
+ if 0 ∉ f (interval ( prevfloat ( X. lo), nextfloat (X . lo) ))
64
121
expansion_pt = X. lo
65
122
66
- elseif 0 ∉ f (Interval ( X. hi))
123
+ elseif 0 ∉ f (interval ( prevfloat ( X. hi), nextfloat (X . hi) ))
67
124
expansion_pt = X. hi
68
125
69
126
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))
75
132
continue
76
133
77
134
else
78
135
push! (R, Root (X, :unknown ))
79
136
80
- debug && @show " Multiple root found" , X
137
+ debugroot && @show " Multiple root found" , X
81
138
82
139
continue
83
140
end
@@ -91,7 +148,7 @@ function newton1d{T}(f::Function, f′::Function, x::Interval{T};
91
148
if (diam (X)/ mag (X)) < reltol && diam (f (X)) < abstol
92
149
push! (R, Root (X, :unknown ))
93
150
94
- debug && @show " Tolerance root found" , X
151
+ debugroot && @show " Tolerance root found" , X
95
152
96
153
continue
97
154
end
@@ -102,28 +159,27 @@ function newton1d{T}(f::Function, f′::Function, x::Interval{T};
102
159
expansion_pt = mid (X)
103
160
end
104
161
105
- initial_width = diam (X)
106
162
107
- a = f (Interval (expansion_pt))
163
+ a = f (interval (expansion_pt))
108
164
b = f′ (X)
109
165
110
166
if 0 < b. hi && 0 > b. lo && 0 ∉ a
111
167
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 )))
114
170
115
171
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 )))
118
174
119
175
end
120
176
121
177
continue
122
178
123
179
else
124
- N = expansion_pt - (f (Interval (expansion_pt))/ f′ (X))
180
+ N = expansion_pt - (f (interval (expansion_pt))/ f′ (X))
125
181
126
- debug && (print (" Newton step : " ); @show (X, X ∩ N))
182
+ debug && (print (" Newton step2 : " ); @show (X, X ∩ N))
127
183
128
184
X = X ∩ N
129
185
m = mid (X)
@@ -133,11 +189,6 @@ function newton1d{T}(f::Function, f′::Function, x::Interval{T};
133
189
end
134
190
end
135
191
136
- if diam (X) > initial_width/ 2
137
- push! (L, Interval (m, X. hi))
138
- X = Interval (X. lo, m)
139
- end
140
-
141
192
push! (L, X)
142
193
end
143
194
end
0 commit comments