Skip to content

Numbers that produce accurate results when used as arguments to trigonometric functions

License

Notifications You must be signed in to change notification settings

jishnub/MultiplesOfPi.jl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

58 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MultiplesOfPi

CI Codecov Coverage Status docs:stable docs:dev

Introduction

This package exports the type PiExpTimes that satisfies PiExpTimes(x, n) = x*π^n. It also provides the constant Pi for convenience, defined as PiExpTimes(1, 1), that behaves like π except it produces results with higher accuracy in certain trigonometric and algebraic contexts. In most scenarios the numbers Pi and π are interchangable. Expressing mathematical relations in terms of Pi instead of the more cumbersome PiExpTimes is usually cleaner, and is recommended unless it's specifically necessary to do otherwise.

Rationale

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.

Features

Arithmetic

Delaying the conversion of π to a float results in precise mathematical expressions such as

Using πUsing Pi
julia> (1//3+ (4//3== (5//3false

julia> float(sqrt(pi)^2) == float(pi)
false
julia> (1//3)Pi + (4//3)Pi == (5//3)Pi
true

julia> float(sqrt(Pi)^2) == float(Pi)
true

We may also simplify algebraic expressions involving powers of Pi as

julia> (2Pi^2//3) // (4Pi//5)
(5//6)Pi

julia> Pi^-2 / 4Pi^3
0.25*Pi^-5

Expressions involving Pi are automatically promoted to Complex as necessary, eg.

julia> (1+im)Pi^3 / 2Pi^2
0.5*Pi + 0.5*Pi*im

julia> (1+im)Pi^3 / 2Pi^2 * 2/Pi
Pi^0 + Pi^0*im

Trigonometric functions

The type PiTimes uses sinpi and cospi under the hood when it is used as an argument to sin and cos. This results in exact results in several contexts where the inaccuracies arise from floating-point conversions.

Using πUsing Pi
julia> cos(3π/2)
-1.8369701987210297e-16

julia> sin(-π)
-1.2246467991473532e-16

julia> tan/2)
1.633123935319537e16
julia> cos(3Pi/2)
0.0

julia> sin(-Pi)
-0.0

julia> tan(Pi/2)
Inf

We may compute complex exponential exactly:

Using πUsing Pi
julia> exp(im*π/2)
6.123233995736766e-17 + 1.0im

# Euler's identity : exp(iπ) + 1 == 0
julia> exp(im*π) + 1
0.0 + 1.2246467991473532e-16im
julia> exp(im*Pi/2)
0.0 + 1.0im

# Euler's identity : exp(iπ) + 1 == 0
julia> exp(im*Pi) + 1
0.0 + 0.0im

Hyperbolic functions work as expected:

Using πUsing Pi
# cosh(ix) = cos(x)
# Should be exactly zero for x = π/2
julia> cosh(im*π/2)
6.123233995736766e-17 + 0.0im
# cosh(ix) = cos(x)
# Should be exactly zero for x = π/2
julia> cosh(im*Pi/2)
0.0 + 0.0im

Interactions with π

The irrational number π is usually aggressively converted to Pi, eg:

julia> π * Pi
Pi^2

This ensures that subsequent calculation would not get promoted to a floating-point type. However if this behavior is not desired then one may specify the type explicitly while constructing the object as

julia> PiExpTimes{Irrational{:π}}(π)
π*Pi^0

Floating-point promotion

Addition and subtraction involving mixed exponents of Pi will involve floating-point conversions, and the resulting expression will have the minimum exponent out of the terms being summed.

julia> Pi + 3Pi
4Pi

julia> Pi + 3Pi^2
10.42477796076938*Pi

This fits with the intuition of the expression being factorized as Pi + 3Pi^2 == Pi*(1 + 3Pi).

Note that π is promoted to Pi in such operations, so we obtain

julia> Pi + π
2Pi

Note that addition and subtraction are not type-stable at present by design.

Performance

In general using Pi instead of pi will be less performant, as pi is aggressively promoted to a floating-point value in most calculations. The use of Pi is mainly intended for tests where exact fractions of Pi are desirable.

Installation

Install the package using

pkg> add MultiplesOfPi

Related packages