Skip to content

Commit

Permalink
Factor out multi-argument methods into separate file
Browse files Browse the repository at this point in the history
  • Loading branch information
Joel-Dahne committed Aug 19, 2023
1 parent db6745f commit 4f600c0
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 91 deletions.
1 change: 1 addition & 0 deletions src/Arblib.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ include("minmax.jl")
include("rand.jl")
include("float.jl")
include("interval.jl")
include("multi-argument.jl")

include("ref.jl")
include("vector.jl")
Expand Down
25 changes: 0 additions & 25 deletions src/arithmetic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,31 +32,6 @@ for (jf, af) in [(:+, :add!), (:-, :sub!), (:*, :mul!), (:/, :div!)]
@eval Base.$jf(x::Union{ArfOrRef,_BitInteger,Irrational}, y::ArbOrRef) = $jf(y, x)

@eval Base.$jf(x::Union{ArbOrRef,_BitInteger,Irrational}, y::AcbOrRef) = $jf(y, x)

# Define more efficient multi argument versions, similar to BigFloat
# TODO: Now precision is determined by first two arguments
for T in (MagOrRef, ArfOrRef, ArbOrRef, AcbOrRef)
@eval function Base.$jf(a::$T, b::$T, c::$T)
z = $jf(a, b)
$af(z, z, c)
return z
end

@eval function Base.$jf(a::$T, b::$T, c::$T, d::$T)
z = $jf(a, b)
$af(z, z, c)
$af(z, z, d)
return z
end

@eval function Base.$jf(a::$T, b::$T, c::$T, d::$T, e::$T)
z = $jf(a, b)
$af(z, z, c)
$af(z, z, d)
$af(z, z, e)
return z
end
end
else
@eval function Base.$jf(x::Irrational, y::Union{ArbOrRef,AcbOrRef})
z = zero(y)
Expand Down
19 changes: 0 additions & 19 deletions src/minmax.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,6 @@ for T in (ArfOrRef, ArbOrRef)
@eval Base.max(x::$T, y::$T) =
Arblib.max!($(_nonreftype(T))(prec = _precision(x, y)), x, y)
@eval Base.minmax(x::$T, y::$T) = (min(x, y), max(x, y))

# Define more efficient multi argument versions, similar to + and *
# TODO: Now precision is determined by first two arguments
for (f, f!) in ((:min, :min!), (:max, :max!))
@eval function Base.$f(a::$T, b::$T, c::$T)
z = $f(a, b)
return $f!(z, z, c)
end

@eval function Base.$f(a::$T, b::$T, c::$T, d::$T)
z = $f(a, b)
return $f!(z, $f!(z, z, c), d)
end

@eval function Base.$f(a::$T, b::$T, c::$T, d::$T, e::$T)
z = $f(a, b)
return $f!(z, $f!(z, $f!(z, z, c), d), e)
end
end
end

### minimum and maximum
Expand Down
61 changes: 61 additions & 0 deletions src/multi-argument.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Contains implementation of multi-argument versions of +, *, min and max

for (jf, af) in [(:+, :add!), (:*, :mul!), (:min, :min!), (:max, :max!)]
@eval function Base.$jf(a::MagOrRef, b::MagOrRef, c::MagOrRef)
res = Mag()
$af(res, a, b)
$af(res, res, c)
return res
end

@eval function Base.$jf(a::MagOrRef, b::MagOrRef, c::MagOrRef, d::MagOrRef)
res = Mag()
$af(res, a, b)
$af(res, res, c)
$af(res, res, d)
return res
end

@eval function Base.$jf(a::MagOrRef, b::MagOrRef, c::MagOrRef, d::MagOrRef, e::MagOrRef)
res = Mag()
$af(res, a, b)
$af(res, res, c)
$af(res, res, d)
$af(res, res, e)
return res
end
end

for T in (ArfOrRef, ArbOrRef, AcbOrRef)
@eval @inline _precision(x::$T, y::$T, z::$T, rest::Vararg{S}) where {S<:$T} =
max(precision(x), _precision(y, z, rest...))

for (jf, af) in [(:+, :add!), (:*, :mul!), (:min, :min!), (:max, :max!)]
T == AcbOrRef && jf == :min && continue
T == AcbOrRef && jf == :max && continue

@eval function Base.$jf(a::$T, b::$T, c::$T)
res = $(_nonreftype(T))(prec = _precision(a, b, c))
$af(res, a, b)
$af(res, res, c)
return res
end

@eval function Base.$jf(a::$T, b::$T, c::$T, d::$T)
res = $(_nonreftype(T))(prec = _precision(a, b, c, d))
$af(res, a, b)
$af(res, res, c)
$af(res, res, d)
return res
end

@eval function Base.$jf(a::$T, b::$T, c::$T, d::$T, e::$T)
res = $(_nonreftype(T))(prec = _precision(a, b, c, d, e))
$af(res, a, b)
$af(res, res, c)
$af(res, res, d)
$af(res, res, e)
return res
end
end
end
21 changes: 0 additions & 21 deletions test/arithmetic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,6 @@

@test Mag(1 / 4) <= inv(Mag(4)) <= Mag(1 / 3)

@test Mag(6) <= +(Mag.((1, 2, 3))...) <= Mag(7)
@test Mag(10) <= +(Mag.((1, 2, 3, 4))...) <= Mag(11)
@test Mag(15) <= +(Mag.((1, 2, 3, 4, 5))...) <= Mag(16)
@test Mag(6) <= *(Mag.((1, 2, 3))...) <= Mag(7)
@test Mag(24) <= *(Mag.((1, 2, 3, 4))...) <= Mag(25)
@test Mag(120) <= *(Mag.((1, 2, 3, 4, 5))...) <= Mag(121)

# signbit, sign and abs
@test !signbit(Mag(0))
@test !signbit(Mag(2))
Expand Down Expand Up @@ -63,13 +56,6 @@
UInt8(6) / Arf(2) ==
3

@test +(Arf.((1, 2, 3))...) == 6
@test +(Arf.((1, 2, 3, 4))...) == 10
@test +(Arf.((1, 2, 3, 4, 5))...) == 15
@test *(Arf.((1, 2, 3))...) == 6
@test *(Arf.((1, 2, 3, 4))...) == 24
@test *(Arf.((1, 2, 3, 4, 5))...) == 120

# fma and muladd
@test fma(Arf(2), Arf(3), Arf(4)) == muladd(Arf(2), Arf(3), Arf(4)) == 10

Expand Down Expand Up @@ -100,13 +86,6 @@
@test T(2) * T(3) == T(2) * 3 == 3 * T(2) == T(2) * UInt(3) == UInt(3) * T(2) == 6
@test T(6) / T(2) == T(6) / 2 == T(6) / UInt(2) == 3

@test +(T.((1, 2, 3))...) == 6
@test +(T.((1, 2, 3, 4))...) == 10
@test +(T.((1, 2, 3, 4, 5))...) == 15
@test *(T.((1, 2, 3))...) == 6
@test *(T.((1, 2, 3, 4))...) == 24
@test *(T.((1, 2, 3, 4, 5))...) == 120

# ^
@test Base.literal_pow(^, T(2), Val(-2)) ==
T(2)^-2 ==
Expand Down
26 changes: 0 additions & 26 deletions test/minmax.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,6 @@
@test min(T(1), T(2)) == T(1)
@test max(T(1), T(2)) == T(2)
@test minmax(T(1), T(2)) == minmax(T(2), T(1)) == (T(1), T(2))

@test min(T.((1, 2, 2))...) == T(1)
@test min(T.((1, 1, 2))...) == T(1)
@test min(T.((2, 2, 1))...) == T(1)
@test min(T.((1, 2, 2, 2))...) == T(1)
@test min(T.((1, 1, 2, 2))...) == T(1)
@test min(T.((2, 2, 1, 2))...) == T(1)
@test min(T.((2, 2, 2, 1))...) == T(1)
@test min(T.((1, 2, 2, 2, 2))...) == T(1)
@test min(T.((1, 1, 2, 2, 2))...) == T(1)
@test min(T.((2, 2, 1, 2, 2))...) == T(1)
@test min(T.((2, 2, 2, 1, 2))...) == T(1)
@test min(T.((2, 2, 2, 2, 1))...) == T(1)

@test max(T.((2, 1, 1))...) == T(2)
@test max(T.((2, 2, 1))...) == T(2)
@test max(T.((1, 1, 2))...) == T(2)
@test max(T.((2, 1, 1, 1))...) == T(2)
@test max(T.((2, 2, 1, 1))...) == T(2)
@test max(T.((1, 1, 2, 1))...) == T(2)
@test max(T.((1, 1, 1, 2))...) == T(2)
@test max(T.((2, 1, 1, 1, 1))...) == T(2)
@test max(T.((2, 2, 1, 1, 1))...) == T(2)
@test max(T.((1, 1, 2, 1, 1))...) == T(2)
@test max(T.((1, 1, 1, 2, 1))...) == T(2)
@test max(T.((1, 1, 1, 1, 2))...) == T(2)
end

@testset "Arb - specific" begin
Expand Down
49 changes: 49 additions & 0 deletions test/multi-argument.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
@testset "Multi-argument" begin
@testset "Mag + and *" begin
@test Mag(6) <= +(Mag.((1, 2, 3))...) <= Mag(7)
@test Mag(10) <= +(Mag.((1, 2, 3, 4))...) <= Mag(11)
@test Mag(15) <= +(Mag.((1, 2, 3, 4, 5))...) <= Mag(16)

@test Mag(6) <= *(Mag.((1, 2, 3))...) <= Mag(7)
@test Mag(24) <= *(Mag.((1, 2, 3, 4))...) <= Mag(25)
@test Mag(120) <= *(Mag.((1, 2, 3, 4, 5))...) <= Mag(121)
end

@testset "$T + and *" for T in [Arf, Arb, Acb]
@test +(T.((1, 2, 3))...) == 6
@test +(T.((1, 2, 3, 4))...) == 10
@test +(T.((1, 2, 3, 4, 5))...) == 15

@test *(T.((1, 2, 3))...) == 6
@test *(T.((1, 2, 3, 4))...) == 24
@test *(T.((1, 2, 3, 4, 5))...) == 120
end

@testset "$T min and max" for T in [Mag, Arf, Arb]
@test min(T.((1, 2, 2))...) == T(1)
@test min(T.((1, 1, 2))...) == T(1)
@test min(T.((2, 2, 1))...) == T(1)
@test min(T.((1, 2, 2, 2))...) == T(1)
@test min(T.((1, 1, 2, 2))...) == T(1)
@test min(T.((2, 2, 1, 2))...) == T(1)
@test min(T.((2, 2, 2, 1))...) == T(1)
@test min(T.((1, 2, 2, 2, 2))...) == T(1)
@test min(T.((1, 1, 2, 2, 2))...) == T(1)
@test min(T.((2, 2, 1, 2, 2))...) == T(1)
@test min(T.((2, 2, 2, 1, 2))...) == T(1)
@test min(T.((2, 2, 2, 2, 1))...) == T(1)

@test max(T.((2, 1, 1))...) == T(2)
@test max(T.((2, 2, 1))...) == T(2)
@test max(T.((1, 1, 2))...) == T(2)
@test max(T.((2, 1, 1, 1))...) == T(2)
@test max(T.((2, 2, 1, 1))...) == T(2)
@test max(T.((1, 1, 2, 1))...) == T(2)
@test max(T.((1, 1, 1, 2))...) == T(2)
@test max(T.((2, 1, 1, 1, 1))...) == T(2)
@test max(T.((2, 2, 1, 1, 1))...) == T(2)
@test max(T.((1, 1, 2, 1, 1))...) == T(2)
@test max(T.((1, 1, 1, 2, 1))...) == T(2)
@test max(T.((1, 1, 1, 1, 2))...) == T(2)
end
end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ using Arblib, Test, LinearAlgebra, Random, Serialization, SpecialFunctions
include("rand.jl")
include("float.jl")
include("interval.jl")
include("multi-argument.jl")
include("vector.jl")
include("matrix.jl")
include("eigen.jl")
Expand Down

0 comments on commit 4f600c0

Please sign in to comment.