Skip to content

Commit

Permalink
arithmetic with other Irrational numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
jishnub committed Mar 6, 2020
1 parent fa38512 commit 56cd626
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 2 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ This package introduces the type `PiTimes` that automatically uses the functions

The number `π` is represented as an `Irrational` type in julia, and may be computed to an arbitrary degree of precision. In normal course of events it is converted to a float when it encounters another number, for example `` is computed by converting both `2` and `π` to floats and subsequently carrying out a floating-point multiplication. This is lossy, as both `2` and `π` may be represented with arbitrary precision. This package delays the conversion of the `π` to a float, treating it as a common factor in algebraic simplifications. This limits floating-point inaccuracies, especially if the terms multiplying `π` are exactly representable in binary. As an added advantage, it uses `sinpi` and `cospi` wherever possible to avoid having to convert `π` to a float altogether.

The concept isn't unknown to julia as such, having been [discussed in 2013](https://github.com/JuliaLang/julia/pull/4112#issuecomment-22961778), but I don't know of an implementation.

# Examples

## Arithmetic
Expand Down Expand Up @@ -90,4 +92,5 @@ pkg> add MultiplesOfPi

# Related packages

- [IrrationalExpressions.jl](https://github.com/jishnub/IrrationalExpressions.jl.git)
- [IrrationalExpressions.jl](https://github.com/jishnub/IrrationalExpressions.jl.git)
- [Tau.jl](https://github.com/JuliaMath/Tau.jl)
13 changes: 12 additions & 1 deletion src/MultiplesOfPi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ for f in (:iszero,:isfinite,:isnan)
end)
end

# Unfortunately Irrational numbers do not have a multiplicative identity of the same type,
# so we make do with something that works
Base.one(::Type{PiTimes{T}}) where {T} = one(T)

# Define trigonometric functions
Expand Down Expand Up @@ -57,10 +59,14 @@ end

# Arithmetic operators

Base.:(+)(p1::PiTimes,p2::PiTimes) = PiTimes(p1.x+p2.x)
Base.:(+)(p1::PiTimes,p2::PiTimes) = PiTimes(p1.x + p2.x)
Base.:(+)(p::PiTimes,::Irrational{:π}) = PiTimes(p.x + one(p.x))
Base.:(+)(::Irrational{:π},p::PiTimes) = PiTimes(p.x + one(p.x))

Base.:(-)(p::PiTimes) = PiTimes(-p.x)
Base.:(-)(p1::PiTimes,p2::PiTimes) = PiTimes(p1.x-p2.x)
Base.:(-)(p::PiTimes,::Irrational{:π}) = PiTimes(p.x - one(p.x))
Base.:(-)(::Irrational{:π},p::PiTimes) = PiTimes(one(p.x) - p.x)

Base.:(/)(p1::PiTimes,p2::PiTimes) = p1.x/p2.x
Base.:(/)(p1::PiTimes,y::Real) = PiTimes(p1.x/y)
Expand All @@ -73,6 +79,11 @@ Base.:(*)(y::Real,p1::PiTimes) = PiTimes(p1.x*y)
Base.:(*)(p1::PiTimes,p2::PiTimes) = float(p1) * float(p2)
Base.:(*)(z::Complex{Bool},p::PiTimes) = p*z # switch the orders to get to something that's non-ambiguous

for op in Symbol[:+,:-,:/,:*]
@eval Base.$op(p::PiTimes,x::AbstractIrrational) = $op(Float64(p),Float64(x))
@eval Base.$op(x::AbstractIrrational,p::PiTimes) = $op(Float64(x),Float64(p))
end

Base.:(//)(p::PiTimes,n) = PiTimes(p.x//n)

end # module
31 changes: 31 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,33 @@ end
@test p//2 == PiTimes(p.x//2)
@test Pi//2 == PiTimes(1//2)
end

@testset "irrational" begin
@testset "pi" begin
@test Pi + π == 2Pi
@test π + Pi == 2Pi
@test Pi - π == 0
@test π - Pi == 0
@test π*Pi == π^2
@test Pi*π == π^2
@test Pi/π == 1
@test π/Pi == 1
@test Pi^π == π^π
@test π^Pi == π^π
end
@testset "e" begin
@test Pi +== π +
@test+ Pi ==+ π
@test Pi -== π -
@test- Pi ==- π
@test*Pi ==*π
@test Pi*== π*
@test Pi/== π/
@test/Pi ==/π
@test Pi^== π^
@test^Pi ==^π
end
end
end

@testset "trigonometric functions" begin
Expand Down Expand Up @@ -187,6 +214,10 @@ end
@test cot(prevfloat(0.0)*π) == cot(PiTimes(prevfloat(0.0)))
end
end

@testset "sinc" begin
@test sinc(Pi) == sinc(π)
end
end

@testset "hyperbolic" begin
Expand Down

0 comments on commit 56cd626

Please sign in to comment.