Skip to content

Commit

Permalink
Merge pull request #5468 from JuliaLang/sk/no-imaginary
Browse files Browse the repository at this point in the history
No more ImaginaryUnit: `const im = Complex(false,true)`.
  • Loading branch information
StefanKarpinski committed Jan 22, 2014
2 parents a196cf0 + 7bd82cf commit 562f015
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 70 deletions.
8 changes: 8 additions & 0 deletions base/bool.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ abs2(x::Bool) = x
^(x::Bool, y::Bool) = x|!y
^(x::Integer, y::Bool) = y ? x : one(x)

function *{T<:Number}(x::Bool, y::T)
S = promote_type(Bool,T)
z = convert(S,0)
z = ifelse(signbit(y)==0, z, -z)
ifelse(x, convert(S,y), z)
end
*(y::Number, x::Bool) = x * y

div(x::Bool, y::Bool) = y ? x : throw(DivideError())
fld(x::Bool, y::Bool) = div(x,y)
rem(x::Bool, y::Bool) = y ? false : throw(DivideError())
Expand Down
103 changes: 37 additions & 66 deletions base/complex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,41 @@ end
Complex(x::Real, y::Real) = Complex(promote(x,y)...)
Complex(x::Real) = Complex(x, zero(x))

const im = Complex(false,true)

typealias Complex128 Complex{Float64}
typealias Complex64 Complex{Float32}
typealias Complex32 Complex{Float16}

sizeof(::Type{Complex128}) = 16
sizeof(::Type{Complex64}) = 8
sizeof(::Type{Complex32}) = 4
sizeof{T<:Real}(::Type{Complex{T}}) = 2*sizeof(T)

real(z::Complex) = z.re
imag(z::Complex) = z.im
real(x::Real) = x
imag(x::Real) = zero(x)
convert{T<:Real}(::Type{Complex{T}}, x::Real) = Complex{T}(x,0)
convert{T<:Real}(::Type{Complex{T}}, z::Complex) = Complex{T}(real(z),imag(z))
convert{T<:Real}(::Type{T}, z::Complex) =
isreal(z) ? convert(T,real(z)) : throw(InexactError())

convert{T<:Real}(::Type{Complex{T}}, x::Real) =
Complex{T}(convert(T,x), convert(T,0))
convert{T<:Real}(::Type{Complex{T}}, z::Complex{T}) = z
convert{T<:Real}(::Type{Complex{T}}, z::Complex) =
Complex{T}(convert(T,real(z)),convert(T,imag(z)))

convert{T<:Real}(::Type{T}, z::Complex) = (imag(z)==0 ? convert(T,real(z)) :
throw(InexactError()))
convert(::Type{Complex}, z::Complex) = z
convert(::Type{Complex}, x::Real) = Complex(x)

promote_rule{T<:Real,S<:Real}(::Type{Complex{T}}, ::Type{S}) =
Complex{promote_type(T,S)}
promote_rule{T<:Real,S<:Real}(::Type{Complex{T}}, ::Type{Complex{S}}) =
Complex{promote_type(T,S)}

complex(x, y) = Complex(x, y)
complex(x) = Complex(x)
real(z::Complex) = z.re
imag(z::Complex) = z.im
real(x::Real) = x
imag(x::Real) = zero(x)
reim(z) = (real(z), imag(z))

isreal(x::Real) = true
isreal(z::Complex) = imag(z) == 0
isimag(z::Number) = real(z) == 0
isinteger(z::Complex) = isreal(z) && isinteger(real(z))
isfinite(z::Complex) = isfinite(real(z)) && isfinite(imag(z))

complex(x::Real, y::Real) = Complex(x, y)
complex(x::Real) = Complex(x)
complex(z::Complex) = z

complex128(r::Float64, i::Float64) = Complex{Float64}(r, i)
Expand All @@ -50,32 +56,23 @@ for fn in _numeric_conversion_func_names
@eval $fn(z::Complex) = complex($fn(real(z)),$fn(imag(z)))
end

isreal{T<:Real}(z::Complex{T}) = imag(z) == 0
isinteger(z::Complex) = isreal(z) && isinteger(real(z))

isfinite(z::Complex) = isfinite(real(z)) && isfinite(imag(z))
reim(z) = (real(z), imag(z))

function complex_show(io::IO, z::Complex, compact::Bool)
r, i = reim(z)
if isnan(r) || isfinite(i)
compact ? showcompact(io,r) : show(io,r)
if signbit(i)==1 && !isnan(i)
i = -i
print(io, compact ? "-" : " - ")
else
print(io, compact ? "+" : " + ")
end
compact ? showcompact(io, i) : show(io, i)
if !(isa(i,Integer) || isa(i,Rational) ||
isa(i,FloatingPoint) && isfinite(i))
print(io, "*")
end
print(io, "im")
compact ? showcompact(io,r) : show(io,r)
if signbit(i)==1 && !isnan(i)
i = -i
print(io, compact ? "-" : " - ")
else
print(io, "complex(",r,",",i,")")
print(io, compact ? "+" : " + ")
end
compact ? showcompact(io, i) : show(io, i)
if !(isa(i,Integer) && !isa(i,Bool) || isa(i,FloatingPoint) && isfinite(i))
print(io, "*")
end
print(io, "im")
end
complex_show(io::IO, z::Complex{Bool}, compact::Bool) =
print(io, z == im ? "im" : "Complex($(z.re),$(z.im))")
show(io::IO, z::Complex) = complex_show(io, z, false)
showcompact(io::IO, z::Complex) = complex_show(io, z, true)

Expand All @@ -90,28 +87,8 @@ function write(s::IO, z::Complex)
end


## singleton type for imaginary unit constant ##

type ImaginaryUnit <: Number end
const im = ImaginaryUnit()

convert{T<:Real}(::Type{Complex{T}}, ::ImaginaryUnit) = Complex{T}(zero(T),one(T))
convert(::Type{Complex}, ::ImaginaryUnit) = Complex(real(im),imag(im))

real(::ImaginaryUnit) = int(0)
imag(::ImaginaryUnit) = int(1)

promote_rule{T<:Complex}(::Type{ImaginaryUnit}, ::Type{T}) = T
promote_rule{T<:Real}(::Type{ImaginaryUnit}, ::Type{T}) = Complex{T}

show(io::IO, ::ImaginaryUnit) = print(io, "im")


## generic functions of complex numbers ##

convert(::Type{Complex}, z::Complex) = z
convert(::Type{Complex}, x::Real) = complex(x)

==(z::Complex, w::Complex) = (real(z) == real(w)) & (imag(z) == imag(w))
==(z::Complex, x::Real) = isreal(z) && real(z) == x
==(x::Real, z::Complex) = isreal(z) && real(z) == x
Expand All @@ -127,28 +104,22 @@ inv(z::Complex) = conj(z)/abs2(z)
inv{T<:Integer}(z::Complex{T}) = inv(float(z))
sign(z::Complex) = z/abs(z)

(-)(::ImaginaryUnit) = complex(0, -1)
-(z::Complex) = complex(-real(z), -imag(z))
+(z::Complex, w::Complex) = complex(real(z) + real(w), imag(z) + imag(w))
-(z::Complex, w::Complex) = complex(real(z) - real(w), imag(z) - imag(w))
*(z::Complex, w::Complex) = complex(real(z) * real(w) - imag(z) * imag(w),
real(z) * imag(w) + imag(z) * real(w))

# adding or multiplying real & complex is common
*(x::Bool, z::Complex) = ifelse(x, z, zero(z))
*(z::Complex, x::Bool) = ifelse(x, z, zero(z))
*(x::Real, z::Complex) = complex(x * real(z), x * imag(z))
*(z::Complex, x::Real) = complex(x * real(z), x * imag(z))
+(x::Real, z::Complex) = complex(x + real(z), imag(z))
+(z::Complex, x::Real) = complex(x + real(z), imag(z))
-(x::Real, z::Complex) = complex(x - real(z), -imag(z))
-(z::Complex, x::Real) = complex(real(z) - x, imag(z))

# multiplying by im is common
*(z::ImaginaryUnit, w::ImaginaryUnit) = complex(-imag(z), real(z))
*(z::ImaginaryUnit, x::Real) = complex(zero(x), x)
*(x::Real, z::ImaginaryUnit) = complex(zero(x), x)
*(z::ImaginaryUnit, w::Complex) = complex(-imag(w), real(w))
*(w::Complex, z::ImaginaryUnit) = complex(-imag(w), real(w))

/(z::Number, w::Complex) = z*inv(w)
/(a::Real , w::Complex) = a*inv(w)
/(z::Complex, x::Real) = complex(real(z)/x, imag(z)/x)
Expand Down
3 changes: 0 additions & 3 deletions base/constants.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ for op in {:+, :-, :*, :/, :^}
@eval $op(x::MathConst, y::MathConst) = $op(float64(x),float64(y))
end

*(x::MathConst, i::ImaginaryUnit) = float64(x)*i
*(i::ImaginaryUnit, x::MathConst) = i*float64(x)

macro math_const(sym, val, def)
esym = esc(sym)
qsym = esc(Expr(:quote, sym))
Expand Down
1 change: 0 additions & 1 deletion base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ export
GeneralizedSVD,
Hermitian,
Hessenberg,
ImaginaryUnit,
InsertionSort,
IntSet,
IO,
Expand Down

0 comments on commit 562f015

Please sign in to comment.