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,7 +63,7 @@ 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 (
@@ -93,45 +93,34 @@ function CommonSolve.solve(
9393
9494 ϵ = abstol
9595 k2 = alg. k2
96- k1 = alg. scaled_k1 * abs (right - left)^ (1 - k2)
96+ span = right - left
97+ k1 = alg. scaled_k1 * span^ (1 - k2) # k1 > 0
9798 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 * ϵ))
99+ n_h = exponent (span / (2 * ϵ))
106100 ϵ_s = ϵ * exp2 (n_h + n0)
101+ T0 = zero (fl)
107102
108103 i = 1
109104 while i ≤ maxiters
110- span = abs (right - left)
105+ span = right - left
106+ mid = (left + right) / 2
111107 r = ϵ_s - (span / 2 )
112- δ = k1 * span^ k2
113108
114- x_f = left + (right - left) * (fl / (fl - fr)) # Interpolation Step
109+ x_f = left + span * (fl / (fl - fr)) # Interpolation Step
115110
111+ δ = max (k1 * span^ k2, eps (x_f))
116112 diff = mid - x_f
117- σ = sign (diff)
118- xt = ifelse (δ ≤ diff, x_f + σ * δ, mid) # Truncation Step
119113
120- xp = ifelse (abs (xt - mid) ≤ r, xt , mid - σ * r ) # Projection Step
114+ xt = ifelse (δ ≤ abs (diff), x_f + copysign (δ, diff) , mid) # Truncation Step
121115
122- if abs ((left - right) / 2 ) < ϵ
116+ xp = ifelse (abs (xt - mid) ≤ r, xt, mid - copysign (r, diff)) # Projection Step
117+ if span < 2 ϵ
123118 return SciMLBase. build_solution (
124119 prob, alg, xt, f (xt); retcode = ReturnCode. Success, left, right
125120 )
126121 end
127-
128- # update
129- tmin, tmax = minmax (xt, xp)
130- xp ≥ tmax && (xp = prevfloat (tmax))
131- xp ≤ tmin && (xp = nextfloat (tmin))
132122 yp = f (xp)
133123 yps = yp * sign (fr)
134- T0 = zero (yps)
135124 if yps > T0
136125 right, fr = xp, yp
137126 elseif yps < T0
@@ -143,10 +132,9 @@ function CommonSolve.solve(
143132 end
144133
145134 i += 1
146- mid = (left + right) / 2
147135 ϵ_s /= 2
148136
149- if Impl . nextfloat_tdir (left, prob . tspan ... ) == right
137+ if nextfloat (left) == right
150138 return SciMLBase. build_solution (
151139 prob, alg, right, fr; retcode = ReturnCode. FloatingPointLimit, left, right
152140 )
0 commit comments