Skip to content

Commit

Permalink
Add support for RealDot (#119)
Browse files Browse the repository at this point in the history
* add support for RealDot

* add tests for realdot

* add compat table for RealDot

* Add `@inferred` in test for `realdot`

Co-authored-by: Seth Axen <seth@sethaxen.com>

* use realdot in slerp

* replace ≈ with == in realdot test

* remove muladd in realdot definition

* Add suggested comment

Co-authored-by: Seth Axen <seth@sethaxen.com>

* Use explicit RealDot.realdot

Co-authored-by: Seth Axen <seth@sethaxen.com>

* use RealDot.realdot in abs2

* add commutative law test for realdot

* add commutative law test for real∘dot

* bump version to v0.7.3

Co-authored-by: Seth Axen <seth@sethaxen.com>
  • Loading branch information
hyrodium and sethaxen committed Dec 16, 2022
1 parent 268cee0 commit 7e0efc6
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 3 deletions.
4 changes: 3 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
name = "Quaternions"
uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0"
version = "0.7.2"
version = "0.7.3"

[deps]
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
RealDot = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9"

[compat]
Aqua = "0.5"
RealDot = "0.1"
julia = "1"

[extras]
Expand Down
7 changes: 5 additions & 2 deletions src/Quaternion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ Base.conj(q::Quaternion) = Quaternion(q.s, -q.v1, -q.v2, -q.v3)
Base.abs(q::Quaternion) = sqrt(abs2(q))
Base.float(q::Quaternion{T}) where T = convert(Quaternion{float(T)}, q)
abs_imag(q::Quaternion) = sqrt(q.v2 * q.v2 + (q.v1 * q.v1 + q.v3 * q.v3)) # ordered to match abs2
Base.abs2(q::Quaternion) = (q.s * q.s + q.v2 * q.v2) + (q.v1 * q.v1 + q.v3 * q.v3)
Base.abs2(q::Quaternion) = RealDot.realdot(q,q)
Base.inv(q::Quaternion) = conj(q) / abs2(q)

Base.isreal(q::Quaternion) = iszero(q.v1) & iszero(q.v2) & iszero(q.v3)
Expand Down Expand Up @@ -320,7 +320,7 @@ true
iszero(qb0) && throw(DomainError(qb0, "The input quaternion must be non-zero."))
qa = qa0 / abs(qa0)
qb = qb0 / abs(qb0)
coshalftheta = qa.s * qb.s + qa.v1 * qb.v1 + qa.v2 * qb.v2 + qa.v3 * qb.v3
coshalftheta = RealDot.realdot(qa, qb)

if coshalftheta < 0
qb = -qb
Expand Down Expand Up @@ -386,6 +386,9 @@ LinearAlgebra.lyap(a::Quaternion, c::Quaternion) = lyap(promote(a, c)...)
LinearAlgebra.lyap(a::Real, c::Quaternion) = c / -2a
LinearAlgebra.lyap(a::Quaternion, c::Real) = c / -2real(a)

## RealDot
# ordering chosen so that real(p'q) == real(q'p) == realdot(p, q) == realdot(q, p), i.e. exact equality
@inline RealDot.realdot(p::Quaternion, q::Quaternion) = (p.s * q.s + p.v2 * q.v2) + (p.v1 * q.v1 + p.v3 * q.v3)
Base.widen(::Type{Quaternion{T}}) where {T} = Quaternion{widen(T)}

Base.flipsign(x::Quaternion, y::Real) = ifelse(signbit(y), -x, x)
Expand Down
1 change: 1 addition & 0 deletions src/Quaternions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module Quaternions

using Random
using LinearAlgebra
using RealDot

include("Quaternion.jl")

Expand Down
15 changes: 15 additions & 0 deletions test/Quaternion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,21 @@ end
end
end

@testset "RealDot with $T" for T in (Float32, Float64)
for _ in 1:10
q1 = randn(Quaternion{T})
q2 = randn(Quaternion{T})
# Check real∘dot is equal to realdot.
@test real(dot(q1,q2)) == @inferred(realdot(q1,q2))
# Check realdot is commutative.
@test realdot(q1,q2) == realdot(q2,q1)
# Check real∘dot is also commutative just in case.
@test real(dot(q1,q2)) == real(dot(q2,q1))
# Check the return type of realdot is correct.
@test realdot(q1,q2) isa T
end
end

@testset "widen" begin
@test widen(Quaternion{Int}) === Quaternion{Int128}
@test widen(QuaternionF32) === QuaternionF64
Expand Down
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Test
using Quaternions
using Aqua
using RealDot

Aqua.test_all(Quaternions)

Expand Down

2 comments on commit 7e0efc6

@hyrodium
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/74227

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.7.3 -m "<description of version>" 7e0efc67c9ff9bba39e349af7c0fe2d20fde9ae5
git push origin v0.7.3

Please sign in to comment.