diff --git a/src/numerics.jl b/src/numerics.jl index 421acbc..9bb67fe 100644 --- a/src/numerics.jl +++ b/src/numerics.jl @@ -169,16 +169,32 @@ as_numer_denom(x::BasicType) = as_numer_denom(Basic(x)) denominator(x::SymbolicType) = as_numer_denom(x)[2] numerator(x::SymbolicType) = as_numer_denom(x)[1] -## Complex +## Complex; real, imag for :Complex defined elsewhere via ccall +# MethodError if x not a number type. real(x::Basic) = Basic(real(SymEngine.BasicType(x))) -real(x::SymEngine.BasicType) = x +real(x::BasicType{Val{:Symbol}}) = x # issue #273 has issue here +real(x::BasicType{Val{:Integer}}) = x +real(x::BasicType{Val{:RealDouble}}) = x +real(x::BasicType{Val{:RealMPFR}}) = x +real(x::BasicType{Val{:Rational}}) = x +function real(x::BasicType{Val{:Constant}}) + any(==(x), (PI, E, EulerGamma, Catalan, oo, NAN)) && return Basic(x) + x == IM && return zero(x) + x == zoo && return oo +end + imag(x::Basic) = Basic(imag(SymEngine.BasicType(x))) imag(x::BasicType{Val{:Integer}}) = Basic(0) imag(x::BasicType{Val{:RealDouble}}) = Basic(0) imag(x::BasicType{Val{:RealMPFR}}) = Basic(0) imag(x::BasicType{Val{:Rational}}) = Basic(0) -imag(x::SymEngine.BasicType) = throw(InexactError()) +function imag(x::BasicType{Val{:Constant}}) + any(==(x), (PI, E, EulerGamma, Catalan, oo, NAN)) && return zero(x) + x == IM && return one(x) + x == zoo && return oo +end + # Because of the definitions above, `real(x) == x` for `x::Basic` # such as `x = symbols("x")`. Thus, it is consistent to define the diff --git a/test/runtests.jl b/test/runtests.jl index 3a0171f..59e75f9 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -303,6 +303,15 @@ expr = x^3 + 3*x^2*y + 3*x*y^2 + y^3 + 1 end end +@test real(Basic(1.5)) == 1.5 +@test isa(real(2 + 3IM), Basic) +@test real(2 + 3IM) == 2 + +@test imag(Basic(1.5)) == 0 +@test isa(imag(2 + 3IM), Basic) +@test imag(2 + 3IM) == Basic(3) + + @test round(Basic(3.14)) == 3.0 @test round(Basic(3.14); digits=1) == 3.1