Skip to content

Commit 260b4eb

Browse files
committed
Fixes in power with rationals and nthroot
1 parent b19f757 commit 260b4eb

1 file changed

Lines changed: 37 additions & 56 deletions

File tree

src/intervals/arithmetic/power.jl

Lines changed: 37 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ function ^(a::F, x::Rational{R}) where {F<:Interval, R<:Integer}
130130

131131
isempty(a) && return emptyinterval(a)
132132
iszero(x) && return one(a)
133+
# x < 0 && return inv(a^(-x))
134+
x < 0 && return F( inv(bigequiv(a^(-x)) ) )
133135

134136
if isthinzero(a)
135137
x > zero(x) && return zero(a)
@@ -140,44 +142,26 @@ function ^(a::F, x::Rational{R}) where {F<:Interval, R<:Integer}
140142

141143
x == (1//2) && return sqrt(a)
142144

143-
alo = inf(a)
144-
ahi = sup(a)
145-
146-
if x >= 0
147-
if alo 0
148-
abig = @biginterval(a)
149-
ui = convert(Culong, q)
150-
low = BigFloat()
151-
high = BigFloat()
152-
ccall((:mpfr_rootn_ui, :libmpfr) , Int32 , (Ref{BigFloat}, Ref{BigFloat}, Culong, MPFRRoundingMode) , low , inf(abig) , ui, MPFRRoundDown)
153-
ccall((:mpfr_rootn_ui, :libmpfr) , Int32 , (Ref{BigFloat}, Ref{BigFloat}, Culong, MPFRRoundingMode) , high , sup(abig) , ui, MPFRRoundUp)
154-
b = interval(low, high)
155-
b = convert(F, b)
156-
return b^p
157-
end
158-
159-
if alo < 0 && ahi 0
160-
a = a F(0, Inf)
161-
abig = @biginterval(a)
162-
ui = convert(Culong, q)
163-
low = BigFloat()
164-
high = BigFloat()
165-
ccall((:mpfr_rootn_ui, :libmpfr) , Int32 , (Ref{BigFloat}, Ref{BigFloat}, Culong, MPFRRoundingMode) , low , inf(abig) , ui, MPFRRoundDown)
166-
ccall((:mpfr_rootn_ui, :libmpfr) , Int32 , (Ref{BigFloat}, Ref{BigFloat}, Culong, MPFRRoundingMode) , high , sup(abig) , ui, MPFRRoundUp)
167-
b = interval(low, high)
168-
b = convert(F, b)
169-
return b^p
170-
end
171-
172-
if ahi < 0
173-
return emptyinterval(a)
174-
end
145+
alo, ahi = bounds(a)
175146

147+
if ahi < 0
148+
return emptyinterval(a)
176149
end
177150

178-
if x < 0
179-
return inv(a^(-x))
151+
if alo < 0 && ahi 0
152+
a = a F(0, Inf)
180153
end
154+
155+
abig = bigequiv(a)
156+
abiglo, abighi = bounds(abig)
157+
ui = convert(Culong, q)
158+
low = BigFloat()
159+
high = BigFloat()
160+
ccall((:mpfr_rootn_ui, :libmpfr) , Int32 , (Ref{BigFloat}, Ref{BigFloat}, Culong, MPFRRoundingMode) , low , abiglo , ui, MPFRRoundDown)
161+
ccall((:mpfr_rootn_ui, :libmpfr) , Int32 , (Ref{BigFloat}, Ref{BigFloat}, Culong, MPFRRoundingMode) , high , abighi , ui, MPFRRoundUp)
162+
b = interval(low, high) ^ p
163+
return F(b)
164+
181165
end
182166

183167
# Interval power of an interval:
@@ -297,35 +281,32 @@ end
297281
Compute the real n-th root of Interval.
298282
"""
299283
function nthroot(a::Interval{BigFloat}, n::Integer)
284+
isempty(a) && return a
300285
n == 1 && return a
301286
n == 2 && return sqrt(a)
302-
n < 0 && isthinzero(a) && return emptyinterval(a)
303-
isempty(a) && return a
304-
if n > 0
305-
alo = inf(a)
306-
ahi = sup(a)
307-
ahi < 0 && iseven(n) && return emptyinterval(BigFloat)
308-
if alo < 0 && ahi >= 0 && iseven(n)
309-
a = a Interval{BigFloat}(0, Inf)
310-
end
311-
ui = convert(Culong, n)
312-
low = BigFloat()
313-
high = BigFloat()
314-
ccall((:mpfr_rootn_ui, :libmpfr), Int32 , (Ref{BigFloat}, Ref{BigFloat}, Culong, MPFRRoundingMode) , low , a.lo , ui, MPFRRoundDown)
315-
ccall((:mpfr_rootn_ui, :libmpfr), Int32 , (Ref{BigFloat}, Ref{BigFloat}, Culong, MPFRRoundingMode) , high , a.hi , ui, MPFRRoundUp)
316-
b = interval(low , high)
317-
return b
318-
elseif n < 0
319-
return inv(nthroot(a, -n))
320-
elseif n == 0
321-
return emptyinterval(a)
287+
n == 0 && return emptyinterval(a)
288+
# n < 0 && isthinzero(a) && return emptyinterval(a)
289+
n < 0 && return inv(nthroot(a, -n))
290+
291+
alo, ahi = bounds(a)
292+
ahi < 0 && iseven(n) && return emptyinterval(BigFloat)
293+
if alo < 0 && ahi >= 0 && iseven(n)
294+
a = a Interval{BigFloat}(0, Inf)
295+
alo, ahi = bounds(a)
322296
end
297+
ui = convert(Culong, n)
298+
low = BigFloat()
299+
high = BigFloat()
300+
ccall((:mpfr_rootn_ui, :libmpfr), Int32 , (Ref{BigFloat}, Ref{BigFloat}, Culong, MPFRRoundingMode) , low , alo , ui, MPFRRoundDown)
301+
ccall((:mpfr_rootn_ui, :libmpfr), Int32 , (Ref{BigFloat}, Ref{BigFloat}, Culong, MPFRRoundingMode) , high , ahi , ui, MPFRRoundUp)
302+
return interval(low , high)
323303
end
324304

325-
function nthroot(a::Interval{T}, n::Integer) where T
305+
function nthroot(a::F, n::Integer) where {T, F<:Interval{T}}
326306
n == 1 && return a
327307
n == 2 && return sqrt(a)
308+
n < 0 && return inv(nthroot(a, -n))
328309
abig = @biginterval(a)
329310
b = nthroot(abig, n)
330-
return convert(Interval{T}, b)
311+
return F(b)
331312
end

0 commit comments

Comments
 (0)