Skip to content

Commit 0e1f782

Browse files
authored
Bugfix: preserve sign of zero (#27)
--------- Co-authored-by: Alexander Voigt <alexander.voigt@physik.rwth-aachen.de>
1 parent fad19d6 commit 0e1f782

16 files changed

Lines changed: 177 additions & 21 deletions

File tree

src/Li.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ _reli(n::Integer, x::Float32) = oftype(x, _reli(n, Float64(x)))
3232
function _reli(n::Integer, x::Real)
3333
isnan(x) && return oftype(x, NaN)
3434
isinf(x) && return oftype(x, -Inf)
35-
iszero(x) && return zero(x)
35+
iszero(x) && return x
3636
x == one(x) && return zeta(n, typeof(x))
3737
x == -one(x) && return neg_eta(n, typeof(x))
3838

@@ -120,7 +120,7 @@ function _li(n::Integer, z::Complex{T})::Complex{T} where T
120120

121121
if iszero(imag(z))
122122
if real(z) <= one(typeof(real(z))) || n <= 0
123-
return Complex(reli(n, real(z)))
123+
return Complex(reli(n, real(z)), imag(z))
124124
else
125125
return Complex(reli(n, real(z)), -convert(T, pi)*inv_fac(n - 1, T)*log(real(z))^(n - 1))
126126
end

src/Li0.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,10 @@ julia> li0(BigFloat("0.25"))
1818
0.3333333333333333333333333333333333333333333333333333333333333333333333333333348
1919
```
2020
"""
21-
li0(z::Number) = z/(1 - z)
21+
function li0(z::Number)
22+
if iszero(z)
23+
z
24+
else
25+
z/(1 - z)
26+
end
27+
end

src/Li1.jl

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ julia> reli1(BigFloat("0.5"))
1919
```
2020
"""
2121
function reli1(x::Real)
22-
if x < one(x)
22+
if x == zero(x)
23+
x
24+
elseif x < one(x)
2325
-log(one(x) - x)
2426
elseif x == one(x)
2527
oftype(x, Inf)
@@ -55,6 +57,12 @@ julia> li1(BigFloat("1.0") + 1im)
5557
-0.0 + 1.570796326794896619231321691639751442098584699687552910487472296153908203143099im
5658
```
5759
"""
58-
li1(z::Complex) = -clog1p(-z)
60+
function li1(z::Complex)
61+
if iszero(z)
62+
z
63+
else
64+
-clog1p(-z)
65+
end
66+
end
5967

6068
li1(z::Real) = li1(Complex(z))

src/Li2.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ function _reli2(x::T)::T where T
187187
elseif x < zero(x)
188188
-reli2_approx(x/(x - one(x))) - one(x)/2*log1p(-x)^2
189189
elseif iszero(x)
190-
zero(x)
190+
x
191191
elseif x < one(x)/2
192192
reli2_approx(x)
193193
elseif x == one(x)/2
@@ -242,9 +242,9 @@ function _li2(z::Complex{T})::Complex{T} where T
242242

243243
if iszero(iz)
244244
if rz <= one(T)
245-
complex(reli2(rz))
245+
Complex(reli2(rz), iz)
246246
else # Re(z) > 1
247-
complex(reli2(rz), -convert(T, pi)*log(rz))
247+
Complex(reli2(rz), -convert(T, pi)*log(rz))
248248
end
249249
else
250250
nz = abs2(z)
@@ -275,9 +275,9 @@ function _li2(z::Complex{BigFloat})::Complex{BigFloat}
275275

276276
if iszero(iz)
277277
if rz <= one(BigFloat)
278-
complex(reli2(rz))
278+
Complex(reli2(rz), iz)
279279
else # Re(z) > 1
280-
complex(reli2(rz), -convert(BigFloat, pi)*log(rz))
280+
Complex(reli2(rz), -convert(BigFloat, pi)*log(rz))
281281
end
282282
else
283283
nz = abs2(z)

src/Li3.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ function _reli3(x::Float64)::Float64
8484
elseif x < 0.0
8585
reli3_neg(x)
8686
elseif iszero(x)
87-
0.0
87+
x
8888
elseif x < 0.5
8989
reli3_pos(x)
9090
elseif x == 0.5
@@ -137,9 +137,9 @@ _li3(z::ComplexF32) = oftype(z, _li3(ComplexF64(z)))
137137
function _li3(z::ComplexF64)::ComplexF64
138138
if iszero(imag(z))
139139
if real(z) <= 1.0
140-
reli3(real(z)) + 0.0im
140+
Complex(reli3(real(z)), imag(z))
141141
else
142-
reli3(real(z)) - pi*log(real(z))^2*0.5im
142+
Complex(reli3(real(z)), -0.5*pi*log(real(z))^2)
143143
end
144144
else # Im(z) != 0
145145
nz::Float64 = abs(z)

src/Li4.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ function _reli4(x::Float64)::Float64
128128

129129
if x < 0.0
130130
rest + sgn*reli4_neg(x)
131+
elseif iszero(x)
132+
x
131133
elseif x < 0.5
132134
rest + sgn*reli4_half(x)
133135
elseif x < 0.8
@@ -172,9 +174,9 @@ _li4(z::ComplexF32) = oftype(z, _li4(ComplexF64(z)))
172174
function _li4(z::ComplexF64)::ComplexF64
173175
if iszero(imag(z))
174176
if real(z) <= 1.0
175-
reli4(real(z)) + 0.0im
177+
Complex(reli4(real(z)), imag(z))
176178
else
177-
reli4(real(z)) - pi/6*log(real(z))^3*1.0im
179+
Complex(reli4(real(z)), -pi/6*log(real(z))^3)
178180
end
179181
else
180182
nz::Float64 = abs(z)

src/Li5.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,22 @@ julia> li5(1.0 + 1.0im)
1717
"""
1818
li5(z::Complex) = _li5(float(z))
1919

20+
li5(z::Real) = li5(Complex(z))
21+
2022
_li5(z::ComplexF16) = oftype(z, _li5(ComplexF32(z)))
2123

2224
_li5(z::ComplexF32) = oftype(z, _li5(ComplexF64(z)))
2325

2426
function _li5(z::ComplexF64)::ComplexF64
2527
if iszero(imag(z))
2628
if iszero(real(z))
27-
return 0.0 + 0.0im
29+
return z
2830
end
2931
if real(z) == 1.0
30-
return ZETA5_F64 + 0.0im
32+
return complex(ZETA5_F64)
3133
end
3234
if real(z) == -1.0
33-
return -15/16*ZETA5_F64 + 0.0im
35+
return complex(-15/16*ZETA5_F64)
3436
end
3537
end
3638

src/Li6.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,22 @@ julia> li6(1.0 + 1.0im)
1717
"""
1818
li6(z::Complex) = _li6(float(z))
1919

20+
li6(z::Real) = li6(Complex(z))
21+
2022
_li6(z::ComplexF16) = oftype(z, _li6(ComplexF32(z)))
2123

2224
_li6(z::ComplexF32) = oftype(z, _li6(ComplexF64(z)))
2325

2426
function _li6(z::ComplexF64)::ComplexF64
2527
if iszero(imag(z))
2628
if iszero(real(z))
27-
return 0.0 + 0.0im
29+
return z
2830
end
2931
if real(z) == 1.0
30-
return ZETA6_F64 + 0.0im
32+
return complex(ZETA6_F64)
3133
end
3234
if real(z) == -1.0
33-
return -31/32*ZETA6_F64 + 0.0im
35+
return complex(-31/32*ZETA6_F64)
3436
end
3537
end
3638

test/Li.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,22 @@ end
5555
end
5656
end
5757

58+
# test signbit for 0.0 and -0.0 arguments
59+
for T in (Float16, Float32, Float64)
60+
@test signbit(real(PolyLog.li(n, T(-0.0))))
61+
@test !signbit(imag(PolyLog.li(n, T(-0.0))))
62+
@test !signbit(real(PolyLog.li(n, T( 0.0))))
63+
@test !signbit(imag(PolyLog.li(n, T( 0.0))))
64+
@test !signbit(real(PolyLog.li(n, Complex{T}(0.0, 0.0))))
65+
@test !signbit(imag(PolyLog.li(n, Complex{T}(0.0, 0.0))))
66+
@test signbit(real(PolyLog.li(n, Complex{T}(-0.0, 0.0))))
67+
@test !signbit(imag(PolyLog.li(n, Complex{T}(-0.0, 0.0))))
68+
@test !signbit(real(PolyLog.li(n, Complex{T}(0.0, -0.0))))
69+
@test signbit(imag(PolyLog.li(n, Complex{T}(0.0, -0.0))))
70+
@test signbit(real(PolyLog.li(n, Complex{T}(-0.0, -0.0))))
71+
@test signbit(imag(PolyLog.li(n, Complex{T}(-0.0, -0.0))))
72+
end
73+
5874
zeta = PolyLog.zeta(n, Float64)
5975

6076
@test PolyLog.reli(n, 1.0) == zeta

test/Li0.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,22 @@
1616
test_function_on_data(PolyLog.li0, map(ComplexF16, cmpl_data), 1e-2, 1e-2)
1717
test_function_on_data(PolyLog.li0, map(Float16 , real_data), 1e-2, 1e-2)
1818

19+
# test signbit for 0.0 and -0.0 arguments
20+
for T in (Float16, Float32, Float64, BigFloat)
21+
@test signbit(real(PolyLog.li0(T(-0.0))))
22+
@test !signbit(imag(PolyLog.li0(T(-0.0))))
23+
@test !signbit(real(PolyLog.li0(T( 0.0))))
24+
@test !signbit(imag(PolyLog.li0(T( 0.0))))
25+
@test !signbit(real(PolyLog.li0(Complex{T}(0.0, 0.0))))
26+
@test !signbit(imag(PolyLog.li0(Complex{T}(0.0, 0.0))))
27+
@test signbit(real(PolyLog.li0(Complex{T}(-0.0, 0.0))))
28+
@test !signbit(imag(PolyLog.li0(Complex{T}(-0.0, 0.0))))
29+
@test !signbit(real(PolyLog.li0(Complex{T}(0.0, -0.0))))
30+
@test signbit(imag(PolyLog.li0(Complex{T}(0.0, -0.0))))
31+
@test signbit(real(PolyLog.li0(Complex{T}(-0.0, -0.0))))
32+
@test signbit(imag(PolyLog.li0(Complex{T}(-0.0, -0.0))))
33+
end
34+
1935
@test PolyLog.li0(2.0) -2.0
2036
@test PolyLog.li0(2.0f0) -2.0f0
2137
@test PolyLog.li0(Float16(2.0)) Float16(-2.0)

0 commit comments

Comments
 (0)