Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove ieee754_rem_pio2 in favor of a rem_pio2_kernel written in Julia. #22603

Merged
merged 39 commits into from
Aug 2, 2017
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
3f951d1
Remove ieee754_rem_pio2 in favor of a rem_pio2_kernel written in Julia.
pkofod Jun 28, 2017
62a91ed
Add missing begin key.
pkofod Jun 29, 2017
16ec5f0
Remove _approx.
pkofod Jun 29, 2017
6f8e725
Move to separate files.
pkofod Jun 29, 2017
c6f593e
Fix LICENSE.md to mention FDLIBM instead of Openlibm.
pkofod Jun 29, 2017
5fd35f4
Address comments.
pkofod Jun 30, 2017
1d2faa6
Strengthen test to faithfully rounded.
pkofod Jun 30, 2017
7878d2c
Fix LICENSE.md message for rem_pio2.
pkofod Jun 30, 2017
0017edd
Fix style in LICENSE.md entry.
pkofod Jun 30, 2017
8258c48
Remove semicolons.
pkofod Jun 30, 2017
83da1a2
Move highword up, and remove duplicate unsafe_trunc.
pkofod Jun 30, 2017
27455bf
Fix LICENSE.md by removing a bullet and changing license of base/spec…
pkofod Jun 30, 2017
bb626b3
Change license info for base/special/exp.jl.
pkofod Jul 1, 2017
45d4ba1
Small changes.
pkofod Jul 1, 2017
ff19e40
Get and reset precision for BigFloats, and space before rem in -rem.
pkofod Jul 1, 2017
375b8af
setprecision do
pkofod Jul 1, 2017
8ca63c1
Add comments, move test, and switch to muladd in some places.
pkofod Jul 5, 2017
1ef4918
Fix y1 branches of rem2pi.
pkofod Jul 5, 2017
a1f1c34
Small changes.
pkofod Jul 5, 2017
ecc6963
Move comment in rem_pio2.jl and add test for fast branch of mod2pi.
pkofod Jul 6, 2017
f8090f5
rint docstring fix and make it clear what the constant is.
pkofod Jul 6, 2017
eed7e62
Update comment for INV2PI.
pkofod Jul 6, 2017
dd2c152
Fix wrong test set name.
pkofod Jul 6, 2017
c06e2f3
Tests against ieee754_rem_pio2 output.
pkofod Jul 8, 2017
6a5dc4a
Inline cody_waite functions.
pkofod Jul 8, 2017
50e52e3
rint -> round, remove rint, remove one argument cody waite, replace I…
pkofod Jul 9, 2017
7b6213e
Add some tests.
pkofod Jul 9, 2017
ae8577c
Inline rem_pio2_kernel, and rearrange code slightly.
pkofod Jul 13, 2017
ba62caf
fix xhp
pkofod Jul 14, 2017
f209c0a
Use DoubleFloat64.
pkofod Jul 21, 2017
994e158
Move constants into functions.
pkofod Jul 22, 2017
aba4579
Fix escaping of mod
pkofod Jul 22, 2017
4865a41
Fix tests and remove specific variables.
pkofod Jul 22, 2017
6dda42c
Fix tests
pkofod Jul 23, 2017
8adb120
Fix issues raised in comments.
pkofod Jul 26, 2017
0545479
More appropriate ulp test (test against eps of reference number).
pkofod Jul 26, 2017
8ee70a1
Merge branch 'master' into rempio2gsoc
pkofod Jul 30, 2017
765c566
Change link to a stable github link.
pkofod Jul 31, 2017
32d2839
Merge remote-tracking branch 'pkofod/rempio2gsoc' into rempio2gsoc
pkofod Jul 31, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ The following components of Julia's standard library have separate licenses:
- base/grisu/* (see [double-conversion](https://github.com/google/double-conversion/blob/master/LICENSE))
- base/sparse/umfpack.jl (see [SUITESPARSE](http://faculty.cse.tamu.edu/davis/suitesparse.html))
- base/sparse/cholmod.jl (see [SUITESPARSE](http://faculty.cse.tamu.edu/davis/suitesparse.html))
- base/special/exp.jl (see [FREEBSD MSUN](https://github.com/freebsd/freebsd) [FreeBSD/2-clause BSD/Simplified BSD License])
- base/special/exp.jl (see [FDLIBM](http://www.netlib.org/fdlibm/e_exp.c) [Freely distributable with preserved copyright notice])
- base/special/rem_pio2.jl (see [FDLIBM](http://www.netlib.org/fdlibm/e_rem_pio2.c) [Freely distributable with preserved copyright notice])


Julia's build process uses the following external tools:
Expand Down
76 changes: 29 additions & 47 deletions base/math.jl
Original file line number Diff line number Diff line change
Expand Up @@ -738,25 +738,6 @@ function add22condh(xh::Float64, xl::Float64, yh::Float64, yl::Float64)
return zh
end

function ieee754_rem_pio2(x::Float64)
# rem_pio2 essentially computes x mod pi/2 (ie within a quarter circle)
# and returns the result as
# y between + and - pi/4 (for maximal accuracy (as the sign bit is exploited)), and
# n, where n specifies the integer part of the division, or, at any rate,
# in which quadrant we are.
# The invariant fulfilled by the returned values seems to be
# x = y + n*pi/2 (where y = y1+y2 is a double-double and y2 is the "tail" of y).
# Note: for very large x (thus n), the invariant might hold only modulo 2pi
# (in other words, n might be off by a multiple of 4, or a multiple of 100)

# this is just wrapping up
# https://github.com/JuliaLang/openspecfun/blob/master/rem_pio2/e_rem_pio2.c

y = [0.0,0.0]
n = ccall((:__ieee754_rem_pio2, openspecfun), Cint, (Float64,Ptr{Float64}), x, y)
return (n,y)
end

# multiples of pi/2, as double-double (ie with "tail")
const pi1o2_h = 1.5707963267948966 # convert(Float64, pi * BigFloat(1/2))
const pi1o2_l = 6.123233995736766e-17 # convert(Float64, pi * BigFloat(1/2) - pi1o2_h)
Expand Down Expand Up @@ -804,47 +785,47 @@ function rem2pi end
function rem2pi(x::Float64, ::RoundingMode{:Nearest})
abs(x) < pi && return x

(n,y) = ieee754_rem_pio2(x)
n,y1,y2 = rem_pio2_kernel(x)

if iseven(n)
if n & 2 == 2 # n % 4 == 2: add/subtract pi
if y[1] <= 0
return add22condh(y[1],y[2],pi2o2_h,pi2o2_l)
if y1 <= 0
return add22condh(y1,y2,pi2o2_h,pi2o2_l)
else
return add22condh(y[1],y[2],-pi2o2_h,-pi2o2_l)
return add22condh(y1,y2,-pi2o2_h,-pi2o2_l)
end
else # n % 4 == 0: add 0
return y[1]
return y1+y2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was this a bug or does your version work differently?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a bug. If you look at

function add22condh(xh::Float64, xl::Float64, yh::Float64, yl::Float64)
you can see that the offending lines are trying to be fast paths for add22condh(y1, y2, 0.0, 0.0). This would then be

    r = xh+0.0 # xh
    s = (0.0 > 0.0) ? (xh-r+0.0+0.0+xl) : (0.0-r+xh+xl+0.0) # this is xl as r == xh
    zh = r+s # xh + xl
    return zh

so basically we can just return y1+y2 directly.

Are you asking because you'd like a test added, a separate commit for this change, or something else?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a test for the values that caused this to fail before in terms of the output of rem_pio2_kernel and the returned values of mod2pi.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is this new test?

Copy link
Contributor Author

@pkofod pkofod Jul 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue was that mod2pi didn't sum in the fast path, so I believe this should test regressions for the problematic cases https://github.com/JuliaLang/julia/pull/22603/files#diff-19d4f20c458e9ad8dbbfb73aea003c5eR211 ?

end
else
if n & 2 == 2 # n % 4 == 3: subtract pi/2
return add22condh(y[1],y[2],-pi1o2_h,-pi1o2_l)
return add22condh(y1,y2,-pi1o2_h,-pi1o2_l)
else # n % 4 == 1: add pi/2
return add22condh(y[1],y[2],pi1o2_h,pi1o2_l)
return add22condh(y1,y2,pi1o2_h,pi1o2_l)
end
end
end
function rem2pi(x::Float64, ::RoundingMode{:ToZero})
ax = abs(x)
ax <= 2*Float64(pi,RoundDown) && return x

(n,y) = ieee754_rem_pio2(ax)
n,y1,y2 = rem_pio2_kernel(ax)

if iseven(n)
if n & 2 == 2 # n % 4 == 2: add pi
z = add22condh(y[1],y[2],pi2o2_h,pi2o2_l)
z = add22condh(y1,y2,pi2o2_h,pi2o2_l)
else # n % 4 == 0: add 0 or 2pi
if y[1] > 0
z = y[1]
if y1 > 0
z = y1+y2
else # negative: add 2pi
z = add22condh(y[1],y[2],pi4o2_h,pi4o2_l)
z = add22condh(y1,y2,pi4o2_h,pi4o2_l)
end
end
else
if n & 2 == 2 # n % 4 == 3: add 3pi/2
z = add22condh(y[1],y[2],pi3o2_h,pi3o2_l)
z = add22condh(y1,y2,pi3o2_h,pi3o2_l)
else # n % 4 == 1: add pi/2
z = add22condh(y[1],y[2],pi1o2_h,pi1o2_l)
z = add22condh(y1,y2,pi1o2_h,pi1o2_l)
end
end
copysign(z,x)
Expand All @@ -858,23 +839,23 @@ function rem2pi(x::Float64, ::RoundingMode{:Down})
end
end

(n,y) = ieee754_rem_pio2(x)
n,y1,y2 = rem_pio2_kernel(x)

if iseven(n)
if n & 2 == 2 # n % 4 == 2: add pi
return add22condh(y[1],y[2],pi2o2_h,pi2o2_l)
return add22condh(y1,y2,pi2o2_h,pi2o2_l)
else # n % 4 == 0: add 0 or 2pi
if y[1] > 0
return y[1]
if y1 > 0
return y1+y2
else # negative: add 2pi
return add22condh(y[1],y[2],pi4o2_h,pi4o2_l)
return add22condh(y1,y2,pi4o2_h,pi4o2_l)
end
end
else
if n & 2 == 2 # n % 4 == 3: add 3pi/2
return add22condh(y[1],y[2],pi3o2_h,pi3o2_l)
return add22condh(y1,y2,pi3o2_h,pi3o2_l)
else # n % 4 == 1: add pi/2
return add22condh(y[1],y[2],pi1o2_h,pi1o2_l)
return add22condh(y1,y2,pi1o2_h,pi1o2_l)
end
end
end
Expand All @@ -887,23 +868,23 @@ function rem2pi(x::Float64, ::RoundingMode{:Up})
end
end

(n,y) = ieee754_rem_pio2(x)
n,y1,y2 = rem_pio2_kernel(x)

if iseven(n)
if n & 2 == 2 # n % 4 == 2: sub pi
return add22condh(y[1],y[2],-pi2o2_h,-pi2o2_l)
return add22condh(y1,y2,-pi2o2_h,-pi2o2_l)
else # n % 4 == 0: sub 0 or 2pi
if y[1] < 0
return y[1]
if y1 < 0
return y1+y2
else # positive: sub 2pi
return add22condh(y[1],y[2],-pi4o2_h,-pi4o2_l)
return add22condh(y1,y2,-pi4o2_h,-pi4o2_l)
end
end
else
if n & 2 == 2 # n % 4 == 3: sub pi/2
return add22condh(y[1],y[2],-pi1o2_h,-pi1o2_l)
return add22condh(y1,y2,-pi1o2_h,-pi1o2_l)
else # n % 4 == 1: sub 3pi/2
return add22condh(y[1],y[2],-pi3o2_h,-pi3o2_l)
return add22condh(y1,y2,-pi3o2_h,-pi3o2_l)
end
end
end
Expand Down Expand Up @@ -977,6 +958,7 @@ include(joinpath("special", "exp.jl"))
include(joinpath("special", "exp10.jl"))
include(joinpath("special", "trig.jl"))
include(joinpath("special", "gamma.jl"))
include(joinpath("special", "rem_pio2.jl"))

module JuliaLibm
include(joinpath("special", "log.jl"))
Expand Down
2 changes: 1 addition & 1 deletion base/special/exp.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Based on FreeBSD lib/msun/src/e_exp.c
# Based on FDLIBM http://www.netlib.org/fdlibm/e_exp.c
# which is made available under the following licence

## Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. Permission
Expand Down
Loading