Skip to content

Commit

Permalink
specialized complex^real methods (JuliaLang#24497)
Browse files Browse the repository at this point in the history
  • Loading branch information
stevengj authored and JeffBezanson committed Nov 9, 2017
1 parent d7a171e commit caa7f04
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 20 deletions.
45 changes: 26 additions & 19 deletions base/complex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,24 @@ function log1p(z::Complex{T}) where T
end
end

function ^(z::Complex{T}, p::Complex{T})::Complex{T} where T<:AbstractFloat
function exp2(z::Complex{T}) where T<:AbstractFloat
er = exp2(real(z))
theta = imag(z) * log(convert(T, 2))
s, c = sincos(theta)
Complex(er * c, er * s)
end
exp2(z::Complex) = exp2(float(z))

function exp10(z::Complex{T}) where T<:AbstractFloat
er = exp10(real(z))
theta = imag(z) * log(convert(T, 10))
s, c = sincos(theta)
Complex(er * c, er * s)
end
exp10(z::Complex) = exp10(float(z))

# _cpow helper function to avoid method ambiguity with ^(::Complex,::Real)
function _cpow(z::Complex{T}, p::Union{T,Complex{T}})::Complex{T} where T<:AbstractFloat
if p == 2 #square
zr, zi = reim(z)
x = (zr-zi)*(zr+zi)
Expand Down Expand Up @@ -665,24 +682,7 @@ function ^(z::Complex{T}, p::Complex{T})::Complex{T} where T<:AbstractFloat
Complex(one(T), zer)
end
end

function exp2(z::Complex{T}) where T<:AbstractFloat
er = exp2(real(z))
theta = imag(z) * log(convert(T, 2))
s, c = sincos(theta)
Complex(er * c, er * s)
end
exp2(z::Complex) = exp2(float(z))

function exp10(z::Complex{T}) where T<:AbstractFloat
er = exp10(real(z))
theta = imag(z) * log(convert(T, 10))
s, c = sincos(theta)
Complex(er * c, er * s)
end
exp10(z::Complex) = exp10(float(z))

function ^(z::T, p::T) where T<:Complex
function _cpow(z::Complex{T}, p::Union{T,Complex{T}}) where T<:Real
if isinteger(p)
rp = real(p)
if rp < 0
Expand Down Expand Up @@ -738,6 +738,8 @@ function ^(z::T, p::T) where T<:Complex

Complex(re, im)
end
^(z::Complex{T}, p::Complex{T}) where T<:Real = _cpow(z, p)
^(z::Complex{T}, p::T) where T<:Real = _cpow(z, p)

^(z::Complex, n::Bool) = n ? z : one(z)
^(z::Complex, n::Integer) = z^Complex(n)
Expand All @@ -749,6 +751,11 @@ end
n>=0 ? power_by_squaring(z,n) : power_by_squaring(inv(z),-n)
^(z::Complex{<:Integer}, n::Integer) = power_by_squaring(z,n) # DomainError for n<0

function ^(z::Complex{T}, p::S) where {T<:Real,S<:Real}
P = promote_type(T,S)
return Complex{P}(z) ^ P(p)
end

function sin(z::Complex{T}) where T
F = float(T)
zr, zi = reim(z)
Expand Down
2 changes: 1 addition & 1 deletion base/rational.jl
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ end

^(x::Number, y::Rational) = x^(y.num/y.den)
^(x::T, y::Rational) where {T<:AbstractFloat} = x^convert(T,y)
^(x::Complex{T}, y::Rational) where {T<:AbstractFloat} = x^convert(T,y)
^(z::Complex{T}, p::Rational) where {T<:Real} = z^convert(typeof(one(T)^p), p)

^(z::Complex{<:Rational}, n::Bool) = n ? z : one(z) # to resolve ambiguity
function ^(z::Complex{<:Rational}, n::Integer)
Expand Down
9 changes: 9 additions & 0 deletions test/complex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -989,3 +989,12 @@ end
@test isequal(one(T) / complex(one(T), -zero(T)), Complex(one(T), zero(T)))
end
end

@testset "complex^real, issue #14342" begin
for T in (Float32, Float64, BigFloat), p in (T(-21//10), -21//10)
z = T(2)+0im
@test real(z^p) 2^p
@test signbit(imag(z^p))
end
@test (2+0im)^(-21//10) === (2//1+0im)^(-21//10) === 2^-2.1 - 0.0im
end

0 comments on commit caa7f04

Please sign in to comment.