diff --git a/Project.toml b/Project.toml index 86da7e3..ee8cbb6 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "Tau" uuid = "c544e3c2-d3e5-5802-ac44-44683f340e4a" -version = "1.0.0" +version = "1.1.0" [deps] IrrationalConstants = "92d709cd-6900-40b7-9082-c6be49f344b6" diff --git a/src/Tau.jl b/src/Tau.jl index c5e7cbf..a8256d9 100644 --- a/src/Tau.jl +++ b/src/Tau.jl @@ -3,8 +3,8 @@ module Tau import IrrationalConstants export tau, τ, - sintau, costau, modtau, - sinτ, cosτ, modτ + sintau, costau, sincostau, modtau, + sinτ, cosτ, sincosτ, modτ # Definition of τ as irrational constant const τ = IrrationalConstants.twoπ @@ -16,12 +16,26 @@ const modtau = modτ # Trigonometric functions sinτ(x) = sinpi(2 * x) cosτ(x) = cospi(2 * x) +function sincosτ(x) + y = 2 * x + # sincospi was added in https://github.com/JuliaLang/julia/pull/35816 + @static if VERSION < v"1.6.0-DEV.292" + return (sinpi(y), cospi(y)) + else + return sincospi(y) + end +end # Optimization for integers sinτ(x::Integer) = zero(float(x)) cosτ(x::Integer) = one(float(x)) +function sincosτ(x::Integer) + y = float(x) + return (zero(y), one(y)) +end const sintau = sinτ const costau = cosτ +const sincostau = sincosτ end diff --git a/test/runtests.jl b/test/runtests.jl index 5a90675..edae625 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -29,12 +29,13 @@ end end end -@testset "sintau/costau" begin +@testset "sintau/costau/sincostau" begin @testset "approximate results for fractional inputs" begin @testset "real values" begin for T = (Float32, Float64), x = -3:0.1:3.0 @test @inferred(sintau(T(x))) ≈ T(sinpi(2 * parse(BigFloat, string(x)))) @test @inferred(costau(T(x))) ≈ T(cospi(2 * parse(BigFloat, string(x)))) + @test @inferred(sincostau(T(x))) == (sintau(T(x)), costau(T(x))) end end @@ -43,6 +44,7 @@ end z = complex(x, y) @test @inferred(sintau(z)) ≈ sinpi(2 * z) @test @inferred(costau(z)) ≈ cospi(2 * z) + @test @inferred(sincostau(z)) == (sintau(z), costau(z)) end end end @@ -52,6 +54,7 @@ end for T = (Int, Complex), x = -3:3 @test @inferred(sintau(T(x))) == zero(T) @test @inferred(costau(T(x))) == one(T) + @test @inferred(sincostau(T(x))) == (sintau(T(x)), costau(T(x))) end end @@ -59,6 +62,7 @@ end for T = (Float32, Float64, BigFloat, Complex), x = -3.0:3.0 @test @inferred(sintau(T(x))) == sign(x) * zero(T) @test @inferred(costau(T(x))) == one(T) + @test @inferred(sincostau(T(x))) == (sintau(T(x)), costau(T(x))) end end end @@ -68,9 +72,11 @@ end for x in (Inf, -Inf) @test_throws DomainError sintau(x) @test_throws DomainError costau(x) + @test_throws DomainError sincostau(x) end @test isequal(@inferred(sintau(NaN)), sinpi(NaN)) @test isequal(@inferred(costau(NaN)), cospi(NaN)) + @test isequal(@inferred(sincostau(NaN)), (sintau(NaN), costau(NaN))) end @testset "complex values" begin @@ -78,17 +84,28 @@ end z = complex(x, y) @test isequal(@inferred(sintau(z)), sinpi(2 * z)) @test isequal(@inferred(costau(z)), cospi(2 * z)) + @test isequal(@inferred(sincostau(z)), (sintau(z), costau(z))) end end end # Adapted from julia/test/math.jl @testset "type stability" begin - for T = (Int, Float32, Float64, BigFloat), f = (sintau, costau) - @test Base.return_types(f, Tuple{T}) == [float(T)] - @test Base.return_types(f, Tuple{Complex{T}}) == [Complex{float(T)}] + for T = (Int, Float32, Float64, BigFloat) + for f = (sintau, costau) + @test Base.return_types(f, Tuple{T}) == [float(T)] + @test Base.return_types(f, Tuple{Complex{T}}) == [Complex{float(T)}] + end + @test Base.return_types(sincostau, Tuple{T}) == [Tuple{float(T), float(T)}] + @test Base.return_types(sincostau, Tuple{Complex{T}}) == [Tuple{Complex{float(T)}, Complex{float(T)}}] end end + + @testset "aliases" begin + @test sinτ === sintau + @test cosτ === costau + @test sincosτ === sincostau + end end # Adapted from julia/test/mod2pi.jl @@ -101,4 +118,8 @@ end @test modtau(355.0) ≈ 3.1416227979431572 @test modtau(355.0f0) ≈ 3.1416228f0 @test modtau(Int64(2)^60) == modtau(2.0^60) + + # aliases + @test modtau === mod2pi + @test modτ === modtau end