From b650ddc6a2bd3057fc28517bd8c87b68d53908f5 Mon Sep 17 00:00:00 2001 From: Benjamin Lorenz Date: Fri, 7 Jul 2023 13:06:58 +0200 Subject: [PATCH] fix sign+abs, avoid more ambiguities --- src/integers.jl | 15 +++++++++------ src/oscarnumber.jl | 10 +++++++++- src/quadraticextension.jl | 8 ++++++++ src/rationals.jl | 11 ++++++++++- test/integers.jl | 12 ++++++++++-- test/quadraticextension.jl | 13 ++++++++++++- test/rationals.jl | 10 ++++++++++ 7 files changed, 68 insertions(+), 11 deletions(-) diff --git a/src/integers.jl b/src/integers.jl index 3316552f..5e7f9c77 100644 --- a/src/integers.jl +++ b/src/integers.jl @@ -1,14 +1,15 @@ # One arguments constructors used by convert: # specialized Int64 constructors handled by Cxx side +(::Type{<:Integer})(int::BigInt) = new_integer_from_bigint(int) +(::Type{<:Integer})(int::Number) = Integer(BigInt(int)) +# to avoid ambiguities: +(::Type{<:Integer})(rat::Base.Rational) = Integer(BigInt(rat)) +(::Type{<:Integer})(flt::BigFloat) = Integer(BigInt(flt)) Integer(int::BigInt) = new_integer_from_bigint(int) Integer(int::Number) = Integer(BigInt(int)) -# to avoid ambiguities: Integer(rat::Base.Rational) = Integer(BigInt(rat)) Integer(flt::BigFloat) = Integer(BigInt(flt)) -# we need thie to make the fallbacks like Base.one work -IntegerAllocated(int::Union{BigInt,Base.Rational,BigFloat,<:Number}) = Integer(int) - import Base: ==, <, <= # These are operations we delegate to gmp for op in (:(==), :(<), :(<=)) @@ -43,15 +44,17 @@ for T in [:Int8, :Int16, :Int32, :UInt8, :UInt16, :UInt32] @eval Base.$T(int::Integer) = $T(Int64(int)) end +(::Type{<:Rational})(int::Integer) = new_rational_from_integer(int) Rational(int::Integer) = new_rational_from_integer(int) -(::Type{T})(int::Integer) where {T<:Number} = convert(T, BigInt(int)) -(::Type{T})(int::Integer) where {T<:AbstractFloat} = convert(T, Float64(int)) +(::Type{T})(int::Integer) where T <: Number = convert(T, BigInt(int)) +(::Type{T})(int::Integer) where T <: AbstractFloat = convert(T, Float64(int)) # to avoid ambiguity Float64(int::Integer) = Float64(CxxWrap.CxxRef(int)) BigFloat(int::Integer) = BigFloat(BigInt(int)) Base.float(int::Integer) = Float64(int) # no-copy converts +(::Type{<:Integer})(int::Integer) = int Integer(int::Integer) = int Base.Integer(int::Integer) = int diff --git a/src/oscarnumber.jl b/src/oscarnumber.jl index 3d271454..e5677c5d 100644 --- a/src/oscarnumber.jl +++ b/src/oscarnumber.jl @@ -3,9 +3,12 @@ function Base.promote_rule(::Type{<:OscarNumber}, return OscarNumber end -OscarNumber(a::Union{Base.Integer, Base.Rational{<:Base.Integer}}) = OscarNumber(Rational(a)) +(::Type{<:OscarNumber})(a::Union{Base.Integer, Base.Rational{<:Base.Integer}}) = OscarNumber(Rational(a)) # this needs to be separate to avoid ambiguities +OscarNumber(a::Union{Base.Integer, Base.Rational{<:Base.Integer}}) = OscarNumber(Rational(a)) +(::Type{<:OscarNumber})(a::Integer) = OscarNumber(Rational(a)) OscarNumber(a::Integer) = OscarNumber(Rational(a)) +(::Type{<:OscarNumber})(a::Rational) = OscarNumber(CxxWrap.ConstCxxRef(a)) OscarNumber(a::Rational) = OscarNumber(CxxWrap.ConstCxxRef(a)) Base.zero(::Type{<:OscarNumber}) = OscarNumber(0) @@ -301,11 +304,16 @@ function register_julia_element(e, p, t::Type) end (::Type{T})(on::OscarNumber) where T<:Number = convert(T, unwrap(on)) +(::Type{<:Integer})(on::OscarNumber) = convert(Integer, unwrap(on)) +(::Type{<:Rational})(on::OscarNumber) = convert(Rational, unwrap(on)) Integer(on::OscarNumber) = convert(Integer, unwrap(on)) Rational(on::OscarNumber) = convert(Rational, unwrap(on)) # we don't support conversion for concrete types inside the OscarNumber here +(::Type{<:QuadraticExtension{<:Rational}})(on::OscarNumber) = QuadraticExtension{Rational}(Rational(on)) +QuadraticExtension{<:Rational}(on::OscarNumber) = QuadraticExtension{Rational}(Rational(on)) QuadraticExtension{Rational}(on::OscarNumber) = QuadraticExtension{Rational}(Rational(on)) +(::Type{<:OscarNumber})(qe::QuadraticExtension) = OscarNumber(Rational(qe)) OscarNumber(qe::QuadraticExtension) = OscarNumber(Rational(qe)) Base.float(on::OscarNumber) = float(unwrap(on)) diff --git a/src/quadraticextension.jl b/src/quadraticextension.jl index 61c6e7d3..151f80a6 100644 --- a/src/quadraticextension.jl +++ b/src/quadraticextension.jl @@ -4,13 +4,17 @@ QuadraticExtension{T}(a::Number, b::Number, r::Number) where T<:qe_suppT = QuadraticExtension{T}(convert(T, a), convert(T, b), convert(T, r)) QuadraticExtension{T}(a::Number) where T<:qe_suppT = QuadraticExtension{T}(a, 0, 0) +(::Type{<:QuadraticExtension{T}})(a::Number) where T<:qe_suppT = QuadraticExtension{T}(a, 0, 0) QuadraticExtension(x...) = QuadraticExtension{Rational}(x...) +(::Type{<:QuadraticExtension})(x...) = QuadraticExtension{Rational}(x...) # needed to avoid ambiguities QuadraticExtension{T}(a::Integer) where T<:qe_suppT = QuadraticExtension{T}(a, 0, 0) +(::Type{<:QuadraticExtension{T}})(a::Integer) where T<:qe_suppT = QuadraticExtension{T}(a, 0, 0) QuadraticExtension(x::Integer) = QuadraticExtension{Rational}(x) QuadraticExtension{T}(a::Rational) where T<:qe_suppT = QuadraticExtension{T}(a, 0, 0) +(::Type{<:QuadraticExtension{T}})(a::Rational) where T<:qe_suppT = QuadraticExtension{T}(a, 0, 0) QuadraticExtension(a::Rational) = QuadraticExtension{Rational}(a, 0, 0) Base.zero(::Type{<:QuadraticExtension{T}}) where T<:qe_suppT = QuadraticExtension{T}(0) @@ -39,6 +43,8 @@ Base.:/(x::QuadraticExtension{T}, y::QuadraticExtension{T}) where T<:qe_suppT = # no-copy convert convert(::Type{<:QuadraticExtension{T}}, qe::QuadraticExtension{T}) where T<:qe_suppT = qe +(::Type{<:QuadraticExtension{T}})(qe::QuadraticExtension{T}) where T<:qe_suppT = qe +(QuadraticExtension{T})(qe::QuadraticExtension{T}) where T<:qe_suppT = qe function _qe_to_rational(::Type{T}, qe::QuadraticExtension) where T<:Number !iszero(_b(qe)) && !iszero(_r(qe)) && throw(DomainError("Given QuadraticExtension not trivial.")) @@ -52,6 +58,8 @@ Base.promote_rule(::Type{<:QuadraticExtension{Rational}}, ::Type{<:AbstractFloat (::Type{T})(qe::QuadraticExtension) where {T<:AbstractFloat} = convert(T, Float64(qe)) # avoid ambiguities +(::Type{<:Rational})(qe::QuadraticExtension) = _qe_to_rational(Rational,qe) +(::Type{<:Integer})(qe::QuadraticExtension) = _qe_to_rational(Integer,qe) Rational(qe::QuadraticExtension) = _qe_to_rational(Rational,qe) Integer(qe::QuadraticExtension) = _qe_to_rational(Integer,qe) (::Type{T})(qe::QuadraticExtension) where {T<:Base.Integer} = _qe_to_rational(T,qe) diff --git a/src/rationals.jl b/src/rationals.jl index 7b804318..bb1c4121 100644 --- a/src/rationals.jl +++ b/src/rationals.jl @@ -1,16 +1,23 @@ +(::Type{<:Rational})(num::Int64, den::Int64) = + rational_si_si(convert(CxxLong, num), convert(CxxLong, den)) Rational(num::Int64, den::Int64) = rational_si_si(convert(CxxLong, num), convert(CxxLong, den)) -function Rational(num::T, den::S) where {T<:Base.Integer, S<:Base.Integer} +function (::Type{<:Rational})(num::T, den::S) where {T<:Base.Integer, S<:Base.Integer} R = promote_type(promote_type(T, Int64), promote_type(S, Int64)) R == Int64 && return Rational(convert(Int64, num), convert(Int64, den)) return Rational(Integer(convert(BigInt, num)), Integer(convert(BigInt, den))) end +(::Type{<:Rational})(x::Base.Rational) = Rational(numerator(x), denominator(x)) Rational(x::Base.Rational) = Rational(numerator(x), denominator(x)) + @inline function Rational(x::Base.Rational{BigInt}) GC.@preserve x new_rational_from_baserational(pointer_from_objref(numerator(x)), pointer_from_objref(denominator(x))) end + +(::Type{<:Rational})(int::Base.Integer) = Rational(int, one(int)) +(::Type{<:Rational})(x::Number) = Rational(Base.Rational(x)) Rational(int::Base.Integer) = Rational(int, one(int)) Rational(x::Number) = Rational(Base.Rational(x)) @@ -51,6 +58,7 @@ end Base.Rational(rat::Rational) = Base.Rational{BigInt}(rat) Base.big(rat::Rational) = Base.Rational{BigInt}(rat) +(::Type{<:Integer})(rat::Rational) = new_integer_from_rational(rat) Integer(rat::Rational) = new_integer_from_rational(rat) (::Type{T})(rat::Rational) where T<:Number = convert(T, big(rat)) (::Type{T})(rat::Rational) where T<:AbstractFloat = convert(T, Float64(rat)) @@ -59,6 +67,7 @@ Base.float(rat::Rational) = Float64(rat) Float64(rat::Rational) = Float64(CxxWrap.CxxRef(rat)) # no-copy convert +(::Type{<:Rational})(rat::Rational) = rat Rational(rat::Rational) = rat # Rational division: diff --git a/test/integers.jl b/test/integers.jl index 2c84dcee..aced375a 100644 --- a/test/integers.jl +++ b/test/integers.jl @@ -39,8 +39,16 @@ @testset verbose=true "Arithmetic" begin a = Polymake.Integer(2) @test -a == -2 - # for T in [IntTypes; Polymake.Integer] - for T in IntTypes + + @test sign(a) == 1 + @test sign(-a) == -1 + @test sign(a-a) == 0 + + @test abs(a) * sign(a) == a + @test abs(-a) * -sign(a) == -a + + #for T in IntTypes + for T in [IntTypes; Polymake.Integer] b = T(5) # Equality @test a == T(2) diff --git a/test/quadraticextension.jl b/test/quadraticextension.jl index f933a5e2..65200fb7 100644 --- a/test/quadraticextension.jl +++ b/test/quadraticextension.jl @@ -100,7 +100,18 @@ a /= b @test a == Polymake.QuadraticExtension{Polymake.Rational}(735//40328, -85//40328, 5) end - + + @testset verbose=true "sign abs" begin + a = Polymake.QuadraticExtension{Polymake.Rational}(5) + b = Polymake.QuadraticExtension{Polymake.Rational}(17, 1, 5) + @test sign(a) == 1 + @test sign(b) == 1 + @test sign(-b) == -1 + @test sign(b-b) == 0 + + @test abs(a) * sign(a) == a + @test abs(-a) * -sign(a) == -a + end end @testset verbose=true "zero / one" begin diff --git a/test/rationals.jl b/test/rationals.jl index bb8bcbd9..a85613ca 100644 --- a/test/rationals.jl +++ b/test/rationals.jl @@ -121,6 +121,16 @@ end end + @testset verbose=true "sign abs" begin + a = Polymake.Rational(2, 3) + @test sign(a) == 1 + @test sign(-a) == -1 + @test sign(a-a) == 0 + + @test abs(a) * sign(a) == a + @test abs(-a) * -sign(a) == -a + end + @testset verbose=true "zero / one" begin ZERO = Polymake.Rational(0) ONE = Polymake.Rational(1)