Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 0 additions & 12 deletions src/Quaternion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,9 @@ const QuaternionF32 = Quaternion{Float32}
const QuaternionF64 = Quaternion{Float64}

Quaternion{T}(x::Real) where {T<:Real} = Quaternion(convert(T, x))
function Quaternion{T}(x::Complex) where {T<:Real}
Base.depwarn("`Complex`-`Quaternion` compatibility is deprecated and will be removed in the next breaking release (v0.7.0).", :Quaternion)
Quaternion(convert(Complex{T}, x))
end
Quaternion{T}(q::Quaternion) where {T<:Real} = Quaternion{T}(q.s, q.v1, q.v2, q.v3)
Quaternion(s::Real, v1::Real, v2::Real, v3::Real) = Quaternion(promote(s, v1, v2, v3)...)
Quaternion(x::Real) = Quaternion(x, zero(x), zero(x), zero(x))
function Quaternion(z::Complex)
Base.depwarn("`Complex`-`Quaternion` compatibility is deprecated and will be removed in the next breaking release (v0.7.0).", :Quaternion)
Quaternion(z.re, z.im, zero(z.re), zero(z.re))
end
function Quaternion(s::Real, a::AbstractVector)
Base.depwarn("`Quaternion(s::Real, a::AbstractVector)` is deprecated and will be removed in the next breaking release (v0.7.0). Please use `Quaternion(s, a[1], a[2], a[3])` instead.", :Quaternion)
Quaternion(s, a[1], a[2], a[3])
Expand All @@ -41,10 +33,6 @@ function Quaternion(a::AbstractVector)
end

Base.promote_rule(::Type{Quaternion{T}}, ::Type{S}) where {T <: Real, S <: Real} = Quaternion{promote_type(T, S)}
function Base.promote_rule(::Type{Quaternion{T}}, ::Type{Complex{S}}) where {T <: Real, S <: Real}
Base.depwarn("`Complex`-`Quaternion` compatibility is deprecated and will be removed in the next breaking release (v0.7.0).", :Quaternion)
Quaternion{promote_type(T, S)}
end
Base.promote_rule(::Type{Quaternion{T}}, ::Type{Quaternion{S}}) where {T <: Real, S <: Real} = Quaternion{promote_type(T, S)}

"""
Expand Down
43 changes: 16 additions & 27 deletions test/Quaternion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ struct MyReal <: Real
end
Base.:(/)(a::MyReal, b::Real) = a.val / b

function _quat(c::Complex{T}) where T
Quaternion(reim(c)...,zero(T),zero(T))
end
function _quat(a::Real)
Quaternion(a)
end

@testset "Quaternion" begin
@testset "type aliases" begin
@test QuaternionF16 === Quaternion{Float16}
Expand All @@ -33,16 +40,6 @@ Base.:(/)(a::MyReal, b::Real) = a.val / b
@test @inferred(Quaternion(T(x))) === Quaternion{T}(coef...)
end
end
@testset "from complex" begin
@testset for z in (1 + 0im, -im, 1 + 2im),
T in (Float32, Float64, Int, Rational{Int})

coef = T.((reim(z)..., 0, 0))
z2 = Complex{T}(z)
@test Quaternion{T}(z) === Quaternion{T}(coef...)
@test @inferred(Quaternion(z2)) === Quaternion{T}(coef...)
end
end
@testset "from quaternion" begin
@testset for q in (Quaternion(1, 2, 3, 4), QuaternionF64(0, 1, 0, 0)),
T in (Float32, Float64)
Expand Down Expand Up @@ -70,7 +67,6 @@ Base.:(/)(a::MyReal, b::Real) = a.val / b

@testset "convert" begin
@test convert(Quaternion{Float64}, 1) === Quaternion(1.0)
@test convert(Quaternion{Float64}, Complex(1, 2)) === Quaternion(1.0, 2.0, 0.0, 0.0)
@test convert(Quaternion{Float64}, Quaternion(1, 2, 3, 4)) ===
Quaternion(1.0, 2.0, 3.0, 4.0)
@test convert(Quaternion{Float64}, Quaternion(1.0, 2.0, 3.0, 4.0)) ===
Expand All @@ -84,13 +80,10 @@ Base.:(/)(a::MyReal, b::Real) = a.val / b
(Quaternion(1.0, 2, 3, 4), Quaternion(1.0))
@test promote(Quaternion(1.0f0, 2, 3, 4), 2.0) ===
(Quaternion(1.0, 2, 3, 4), Quaternion(2.0))
@test promote(Quaternion(1.0f0), 2 + 3im) ===
(Quaternion(1.0f0), Quaternion(2.0f0 + 3.0f0im))
@test promote(Quaternion(1.0f0), Quaternion(2.0)) ===
(Quaternion(1.0), Quaternion(2.0))

@test Quaternion(1) == 1.0
@test Quaternion(1, 2, 0, 0) == Complex(1.0, 2.0)
end

@testset "shorthands" begin
Expand Down Expand Up @@ -174,20 +167,14 @@ Base.:(/)(a::MyReal, b::Real) = a.val / b
for _ in 1:100, T in (Float32, Float64, Int32, Int64)
if T <: Integer
q, q1, q2, q3 = [Quaternion(rand((-T(100)):T(100), 4)...) for _ in 1:4]
c1, c2 = [complex(rand((-T(100)):T(100), 2)...) for _ in 1:2]
else
q, q1, q2, q3 = randn(Quaternion{T}, 4)
c1, c2 = randn(Complex{T}, 2)
end

# skewfield
test_group(q1, q2, q3, +, zero(q), -)
test_group(q1, q2, q3, *, one(q), inv)
test_multiplicative(q1, q2, *, norm)

# complex embedding
test_multiplicative(c1, c2, *, Quaternion)
test_multiplicative(c1, c2, +, Quaternion)
end
end

Expand Down Expand Up @@ -271,9 +258,11 @@ Base.:(/)(a::MyReal, b::Real) = a.val / b
@test qk * qk == -q1
end

@testset "abs2" for _ in 1:100, T in (Float16, Float32, Float64)
q = rand(Quaternion{T})
@test abs2(q) == q'*q
@testset "abs2 with $(T)" for T in (Float16, Float32, Float64)
for _ in 1:100
q = rand(Quaternion{T})
@test abs2(q) == q'*q
end
end

@testset "/" begin
Expand Down Expand Up @@ -320,8 +309,8 @@ Base.:(/)(a::MyReal, b::Real) = a.val / b
@testset for fun in unary_funs
for _ in 1:100
c = randn(ComplexF64)
q = quat(c)
@test @inferred(fun(q)) ≈ fun(c)
q = _quat(c)
@test @inferred(fun(q)) ≈ _quat(fun(c))
@test q2 * fun(q) * inv(q2) ≈ fun(q2 * q * inv(q2))
end
end
Expand All @@ -343,8 +332,8 @@ Base.:(/)(a::MyReal, b::Real) = a.val / b
q, q2 = randn(QuaternionF64, 2)
for _ in 1:100
c = randn(ComplexF64)
q = quat(c)
@test @inferred(fun(q)) ≈ fun(c)
q = _quat(c)
@test @inferred(fun(q)) ≈ _quat(fun(c))
@test q2 * fun(q) * inv(q2) ≈ fun(q2 * q * inv(q2))
end
end
Expand Down