4949function ITP (; scaled_k1:: Real = 0.2 , k2:: Real = 2 , n0:: Int = 10 )
5050 scaled_k1 < 0 && error (" Hyper-parameter κ₁ should not be negative" )
5151 n0 < 0 && error (" Hyper-parameter n₀ should not be negative" )
52- if k2 < 1 || k2 > ( 1.5 + sqrt (5 ) / 2 )
52+ if ! ( 1 <= k2 <= 1.5 + sqrt (5 ) / 2 )
5353 throw (ArgumentError (" Hyper-parameter κ₂ should be between 1 and 1 + ϕ where \
5454 ϕ ≈ 1.618... is the golden ratio" ))
5555 end
@@ -63,22 +63,23 @@ function CommonSolve.solve(
6363 @assert ! SciMLBase. isinplace (prob) " `ITP` only supports out-of-place problems."
6464
6565 f = Base. Fix2 (prob. f, prob. p)
66- left, right = prob. tspan
66+ left, right = minmax ( promote ( prob. tspan... ) ... )
6767 fl, fr = f (left), f (right)
6868
6969 abstol = NonlinearSolveBase. get_tolerance (
7070 left, abstol, promote_type (eltype (left), eltype (right))
7171 )
7272
73+ stats = SciMLBase. NLStats (2 ,0 ,0 ,0 ,0 )
7374 if iszero (fl)
7475 return SciMLBase. build_solution (
75- prob, alg, left, fl; retcode = ReturnCode. ExactSolutionLeft, left, right
76+ prob, alg, left, fl; retcode = ReturnCode. ExactSolutionLeft, left, right, stats
7677 )
7778 end
7879
7980 if iszero (fr)
8081 return SciMLBase. build_solution (
81- prob, alg, right, fr; retcode = ReturnCode. ExactSolutionRight, left, right
82+ prob, alg, right, fr; retcode = ReturnCode. ExactSolutionRight, left, right, stats
8283 )
8384 end
8485
@@ -87,73 +88,63 @@ function CommonSolve.solve(
8788 @warn " The interval is not an enclosing interval, opposite signs at the \
8889 boundaries are required."
8990 return SciMLBase. build_solution (
90- prob, alg, left, fl; retcode = ReturnCode. InitialFailure, left, right
91+ prob, alg, left, fl; retcode = ReturnCode. InitialFailure, left, right, stats
9192 )
9293 end
9394
9495 ϵ = abstol
9596 k2 = alg. k2
96- k1 = alg. scaled_k1 * abs (right - left)^ (1 - k2)
97+ span = right - left
98+ k1 = alg. scaled_k1 * span^ (1 - k2) # k1 > 0
9799 n0 = alg. n0
98- mid = (left + right) / 2
99- x_f = left + (right - left) * (fl / (fl - fr))
100- xt = left
101- xp = left
102- r = zero (left) # minmax radius
103- δ = zero (left) # truncation error
104- σ = one (mid)
105- n_h = exponent (abs (right - left) / (2 * ϵ))
100+ n_h = exponent (span / (2 * ϵ))
106101 ϵ_s = ϵ * exp2 (n_h + n0)
102+ T0 = zero (fl)
107103
108104 i = 1
109105 while i ≤ maxiters
110- span = abs (right - left)
106+ stats. nsteps += 1
107+ span = right - left
108+ mid = (left + right) / 2
111109 r = ϵ_s - (span / 2 )
112- δ = k1 * span^ k2
113110
114- x_f = left + (right - left) * (fl / (fl - fr)) # Interpolation Step
111+ x_f = left + span * (fl / (fl - fr)) # Interpolation Step
115112
113+ δ = max (k1 * span^ k2, eps (x_f))
116114 diff = mid - x_f
117- σ = sign (diff)
118- xt = ifelse (δ ≤ diff, x_f + σ * δ, mid) # Truncation Step
119115
120- xp = ifelse (abs (xt - mid) ≤ r, xt , mid - σ * r ) # Projection Step
116+ xt = ifelse (δ ≤ abs (diff), x_f + copysign (δ, diff) , mid) # Truncation Step
121117
122- if abs ((left - right) / 2 ) < ϵ
118+ xp = ifelse (abs (xt - mid) ≤ r, xt, mid - copysign (r, diff)) # Projection Step
119+ if span < 2 ϵ
123120 return SciMLBase. build_solution (
124- prob, alg, xt, f (xt); retcode = ReturnCode. Success, left, right
121+ prob, alg, xt, f (xt); retcode = ReturnCode. Success, left, right, stats
125122 )
126123 end
127-
128- # update
129- tmin, tmax = minmax (xt, xp)
130- xp ≥ tmax && (xp = prevfloat (tmax))
131- xp ≤ tmin && (xp = nextfloat (tmin))
132124 yp = f (xp)
125+ stats. nf += 1
133126 yps = yp * sign (fr)
134- T0 = zero (yps)
135127 if yps > T0
136128 right, fr = xp, yp
137129 elseif yps < T0
138130 left, fl = xp, yp
139131 else
140132 return SciMLBase. build_solution (
141- prob, alg, xp, yps; retcode = ReturnCode. Success, left, right
133+ prob, alg, xp, yps; retcode = ReturnCode. Success, left, right, stats
142134 )
143135 end
144136
145137 i += 1
146- mid = (left + right) / 2
147138 ϵ_s /= 2
148139
149- if Impl . nextfloat_tdir (left, prob . tspan ... ) == right
140+ if nextfloat (left) == right
150141 return SciMLBase. build_solution (
151- prob, alg, right, fr; retcode = ReturnCode. FloatingPointLimit, left, right
142+ prob, alg, right, fr; retcode = ReturnCode. FloatingPointLimit, left, right, stats
152143 )
153144 end
154145 end
155146
156147 return SciMLBase. build_solution (
157- prob, alg, left, fl; retcode = ReturnCode. MaxIters, left, right
148+ prob, alg, left, fl; retcode = ReturnCode. MaxIters, left, right, stats
158149 )
159150end
0 commit comments