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

improve promotion and equality checking #52

Merged
merged 24 commits into from
Feb 20, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
da6c867
improve promotion and equality checking
mikmoore Dec 20, 2021
fc1d79a
Apply suggestions from code review
mikmoore Dec 31, 2021
2043d2a
change && to & in ==
mikmoore Dec 31, 2021
a90f73f
extend promotion and equality improvements to Octonion, DualQuaternion
mikmoore Dec 31, 2021
092ccf9
Update src/Octonion.jl
mikmoore Feb 20, 2022
c9e5035
add promotion and equality tests for DualQuaternion and Octonion
mikmoore Feb 20, 2022
902a852
Update test/test_Quaternion.jl
mikmoore Feb 20, 2022
359fb0b
reorganize testing and add convert() tests
mikmoore Feb 20, 2022
3809886
fix troublesome shorthand constructors that gave potentially-wrong .n…
mikmoore Feb 20, 2022
d21747b
fix broken DualQuaternion interactions with DualNumbers.Dual
mikmoore Feb 20, 2022
627f820
Update src/DualQuaternion.jl
mikmoore Feb 20, 2022
1823d86
revert mistake to norm field
mikmoore Feb 20, 2022
4083684
Revert "fix troublesome shorthand constructors that gave potentially-…
mikmoore Feb 20, 2022
1f60958
quat(), dualquat(), and octo() don't set their own defaults for norm
mikmoore Feb 20, 2022
c9bf65e
make Quaternion(1) === Quaternion{T}(1)
mikmoore Feb 20, 2022
1a80a42
fix norm fields of DualQuaternion(::Dual)
mikmoore Feb 20, 2022
a259170
Merge branch 'master' of https://github.com/JuliaGeometry/Quaternions…
mikmoore Feb 20, 2022
8d3eedc
Merge branch 'JuliaGeometry-master' into promotion
mikmoore Feb 20, 2022
f83d75c
fix test that was broken because it was misplaced
mikmoore Feb 20, 2022
8c534e2
Update test/test_Quaternion.jl
mikmoore Feb 20, 2022
6787ccc
increase test coverage
mikmoore Feb 20, 2022
94a65a4
a few more tests
mikmoore Feb 20, 2022
693eaa0
Merge branch 'master' into promotion
sethaxen Feb 20, 2022
c333db7
Update test/test_Quaternion.jl
mikmoore Feb 20, 2022
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
10 changes: 4 additions & 6 deletions src/DualQuaternion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,11 @@ DualQuaternion(q::Quaternion) = DualQuaternion(q, zero(q), q.norm)

DualQuaternion(a::Vector) = DualQuaternion(zero(Quaternion{typeof(a[1])}), Quaternion(a))

convert(::Type{DualQuaternion{T}}, x::Real) where {T} =
DualQuaternion(convert(Quaternion{T}, x), convert(Quaternion{T}, 0))
convert(::Type{DualQuaternion{T}}, x::Real) where {T} = DualQuaternion(convert(T, x))

convert(::Type{DualQuaternion{T}}, d::Dual) where {T} =
DualQuaternion(convert(Dual{T}, d), convert(Dual{T}, 0), convert(Dual{T}, 0), convert(Dual{T}, 0))
convert(::Type{DualQuaternion{T}}, d::Dual) where {T} = DualQuaternion(convert(Dual{T}, d))

convert(::Type{DualQuaternion{T}}, q::Quaternion) where {T} =
DualQuaternion(convert(Quaternion{T}, q), convert(Quaternion{T}, 0), q.norm)
convert(::Type{DualQuaternion{T}}, q::Quaternion) where {T} = DualQuaternion(convert(Quaternion{T}, q))

convert(::Type{DualQuaternion{T}}, q::DualQuaternion{T}) where {T <: Real} = q

Expand Down Expand Up @@ -112,6 +109,7 @@ end
dq.q0 * dw.qe + dq.qe * dw.q0,
dq.norm && dw.norm)
(/)(dq::DualQuaternion, dw::DualQuaternion) = dq * inv(dw)
(==)(q::DualQuaternion, w::DualQuaternion) = (q.q0 == w.q0) & (q.qe == w.qe) # ignore .norm field
sethaxen marked this conversation as resolved.
Show resolved Hide resolved

function angleaxis(dq::DualQuaternion)
tq = dq.qe * conj(dq.q0)
Expand Down
12 changes: 6 additions & 6 deletions src/Octonion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,9 @@ Octonion(q::Quaternion) = Octonion(q.s, q.v1, q.v2, q.v3, zero(q.s), zero(q.s),
Octonion(s::Real, a::Vector) = Octonion(s, a[1], a[2], a[3], a[4], a[5], a[6], a[7])
Octonion(a::Vector) = Octonion(0, a[1], a[2], a[3], a[4], a[5], a[6], a[7])

convert(::Type{Octonion{T}}, x::Real) where {T} =
Octonion(convert(T, x), convert(T, 0), convert(T, 0), convert(T, 0), convert(T, 0), convert(T, 0), convert(T, 0), convert(T, 0))
convert(::Type{Octonion{T}}, z::Complex) where {T} =
Octonion(convert(T, real(z)), convert(T, imag(z)), convert(T, 0), convert(T, 0), convert(T, 0), convert(T, 0), convert(T, 0), convert(T, 0))
convert(::Type{Octonion{T}}, q::Quaternion) where {T} =
Octonion(convert(T, real(q)), convert(T, q.v1), convert(T, q.v2), convert(T, q.v3), convert(T, 0), convert(T, 0), convert(T, 0), convert(T, 0))
convert(::Type{Octonion{T}}, x::Real) where {T} = Octonion(convert(T, x))
convert(::Type{Octonion{T}}, z::Complex) where {T} = Octonion(convert(Complex{T}, z))
convert(::Type{Octonion{T}}, q::Quaternion) where {T} = Octonion(convert(Quaternion{T}, q))
convert(::Type{Octonion{T}}, o::Octonion{T}) where {T <: Real} = o
convert(::Type{Octonion{T}}, o::Octonion) where {T} =
Octonion(convert(T, o.s), convert(T, o.v1), convert(T, o.v2), convert(T, o.v3), convert(T, o.v4), convert(T, o.v5), convert(T, o.v6), convert(T, o.v7), o.norm)
Expand Down Expand Up @@ -113,6 +110,9 @@ end

(/)(o::Octonion, w::Octonion) = o * inv(w)

(==)(q::Octonion, w::Octonion) = (q.s == w.s) & (q.v1 == w.v1) & (q.v2 == w.v2) & (q.v3 == w.v3) &
(q.v4 == w.v4) & (q.v5 == w.v5) & (q.v6 == w.v6) & (q.v7 == w.v7) # ignore .norm field

function exp(o::Octonion)
s = o.s
se = exp(s)
Expand Down
8 changes: 4 additions & 4 deletions src/Quaternion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ Quaternion(z::Complex) = Quaternion(z.re, z.im, zero(z.re), zero(z.re), abs(z) =
Quaternion(s::Real, a::Vector) = Quaternion(s, a[1], a[2], a[3])
Quaternion(a::Vector) = Quaternion(0, a[1], a[2], a[3])

convert(::Type{Quaternion{T}}, x::Real) where {T} =
Quaternion(convert(T, x), convert(T, 0), convert(T, 0), convert(T, 0))
convert(::Type{Quaternion{T}}, z::Complex) where {T} =
Quaternion(convert(T, real(z)), convert(T, imag(z)), convert(T, 0), convert(T, 0))
convert(::Type{Quaternion{T}}, x::Real) where {T} = Quaternion(convert(T, x))
convert(::Type{Quaternion{T}}, z::Complex) where {T} = Quaternion(convert(Complex{T}, z))
convert(::Type{Quaternion{T}}, q::Quaternion{T}) where {T <: Real} = q
convert(::Type{Quaternion{T}}, q::Quaternion) where {T} =
Quaternion(convert(T, q.s), convert(T, q.v1), convert(T, q.v2), convert(T, q.v3), q.norm)
Expand Down Expand Up @@ -96,6 +94,8 @@ end
q.norm && w.norm)
(/)(q::Quaternion, w::Quaternion) = q * inv(w)

(==)(q::Quaternion, w::Quaternion) = (q.s == w.s) & (q.v1 == w.v1) & (q.v2 == w.v2) & (q.v3 == w.v3) # ignore .norm field

angleaxis(q::Quaternion) = angle(q), axis(q)

angle(q::Quaternion) = 2 * atan(√(q.v1^2 + q.v2^2 + q.v3^2), q.s)
Expand Down
2 changes: 1 addition & 1 deletion src/Quaternions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ __precompile__()

module Quaternions

import Base: +, -, *, /, ^
import Base: +, -, *, /, ^, ==
import Base: abs, abs2, angle, conj, cos, exp, inv, isfinite, log, real, sin, sqrt
import Base: convert, promote_rule, float
import LinearAlgebra: norm, normalize
Expand Down
19 changes: 19 additions & 0 deletions test/test_Quaternion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,25 @@ for _ in 1:10, T in (Float32, Float64, Int32, Int64)
test_multiplicative(c1, c2, +, Quaternion)
end

let # test promotions and equalities
mikmoore marked this conversation as resolved.
Show resolved Hide resolved
@test Quaternion(1,0,0,0,false) == Quaternion(1,0,0,0,true) # test that .norm field does not affect equality
@test Quaternion(1) == 1.0 # test promotion
@test Quaternion(1,2,0,0) == Complex(1.0,2.0) # test promotion

@test Quaternion(1.0,2,3,4) == DualQuaternion(Quaternion(1,2,3,4))
@test Quaternion(1.0,2,3,4) != DualQuaternion(Quaternion(1,2,3,4),Quaternion(5,6,7,8))
@test DualQuaternion(1) == 1.0
@test DualQuaternion(Quaternion(1,2,3,4),Quaternion(5,6,7,8)) == DualQuaternion(Quaternion(1.0,2,3,4),Quaternion(5,6,7,8))
@test DualQuaternion(Quaternion(1,2,3,4),Quaternion(5,6,7,8)) != DualQuaternion(Quaternion(1.0,2,3,4),Quaternion(1,2,3,4))

@test Quaternion(1.0,2,3,4) == Octonion(1,2,3,4,0,0,0,0)
@test Quaternion(1.0,2,3,4) != Octonion(1,2,3,4,5,6,7,8)
@test Octonion(1,0,0,0,0,0,0,0,false) == Octonion(1,0,0,0,0,0,0,0,true) # test that .norm field does not affect equality
@test Octonion(1) == 1.0
@test Octonion(1.0,2,3,4,5,6,7,8) == Octonion(1,2,3,4,5,6,7,8)
@test Octonion(1.0,2,3,4,5,6,7,8) != Octonion(1,2,3,4,1,2,3,4)
end

let # test rotations
qx = qrotation([1, 0, 0], pi / 4)
@test qx * qx ≈ qrotation([1, 0, 0], pi / 2)
Expand Down