Skip to content

Commit bf3803b

Browse files
hyrodiumsethaxen
andauthored
Add more methods to quat (#132)
* add more methods to `quat` * fix typo * Fix docstring in `src/Quaternion.jl` Co-authored-by: Seth Axen <[email protected]> * avoid tests on unbound_args * add more tests on `quat` * add more tests on `quat` * replace `function quat end` with `quat` --------- Co-authored-by: Seth Axen <[email protected]>
1 parent 0877cfd commit bf3803b

File tree

3 files changed

+49
-5
lines changed

3 files changed

+49
-5
lines changed

src/Quaternion.jl

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ Base.promote_rule(::Type{Quaternion{T}}, ::Type{S}) where {T <: Real, S <: Real}
2828
Base.promote_rule(::Type{Quaternion{T}}, ::Type{Quaternion{S}}) where {T <: Real, S <: Real} = Quaternion{promote_type(T, S)}
2929

3030
"""
31-
quat(r, [i, j, k])
31+
quat(w, [x, y, z])
3232
33-
Convert real numbers or arrays to quaternion. `i, j, k` defaults to zero.
33+
Convert real numbers or arrays to quaternion. `x, y, z` defaults to zero.
3434
3535
# Examples
3636
```jldoctest
@@ -49,15 +49,45 @@ julia> quat([1, 2, 3])
4949
"""
5050
quat
5151

52-
quat(p, v1, v2, v3) = Quaternion(p, v1, v2, v3)
53-
quat(x) = Quaternion(x)
52+
quat(q::Quaternion) = q
53+
quat(s::Real) = Quaternion(s)
54+
quat(s::Real, v1::Real, v2::Real, v3::Real) = Quaternion(s, v1, v2, v3)
55+
56+
## Array operations on quaternions ##
57+
quat(A::AbstractArray{<:Quaternion}) = A
5458
function quat(A::AbstractArray{T}) where T
5559
if !isconcretetype(T)
5660
error("`quat` not defined on abstractly-typed arrays; please convert to a more specific type")
5761
end
5862
convert(AbstractArray{typeof(quat(zero(T)))}, A)
5963
end
6064

65+
"""
66+
quat(T::Type)
67+
68+
Return an appropriate type that can represent a value of type `T` as a quaternion.
69+
Equivalent to `typeof(quat(zero(T)))`.
70+
71+
# Examples
72+
```jldoctest
73+
julia> quat(Quaternion{Int})
74+
Quaternion{Int64}
75+
76+
julia> quat(Int)
77+
Quaternion{Int64}
78+
```
79+
"""
80+
quat(::Type{T}) where {T<:Real} = Quaternion{T}
81+
quat(::Type{Quaternion{T}}) where {T<:Real} = Quaternion{T}
82+
83+
quat(::Missing) = missing
84+
# Same definitioin as in Base: https://github.com/JuliaLang/julia/blob/v1.9.3/base/missing.jl#L111-L115
85+
quat(::Type{Missing}) = Missing
86+
function quat(::Type{Union{T, Missing}}) where T
87+
T === Any && throw(MethodError(quat, (Any,))) # To prevent StackOverflowError
88+
Union{quat(T), Missing}
89+
end
90+
6191
"""
6292
real(T::Type{<:Quaternion})
6393

test/Quaternion.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,18 @@ end
9393
@test quat(Quaternion(1, 2, 3, 4)) === Quaternion(1, 2, 3, 4)
9494
@test quat([2, 3, 4]) == Quaternion{Int}[2, 3, 4]
9595
@test_throws ErrorException quat(Real[1,2,3])
96+
@test quat(Quaternion[1,2]) == Quaternion[1,2]
97+
98+
@test quat(Int) === Quaternion{Int}
99+
@test quat(Float32) === Quaternion{Float32}
100+
@test quat(Quaternion{Int}) === Quaternion{Int}
101+
@test quat(Quaternion{Float32}) === Quaternion{Float32}
102+
103+
# Note that `quat(1,missing,0,0)` throws an error.
104+
# This is the same behavior as `complex(1,missing)`.
105+
@test quat(missing) === missing
106+
@test quat(Missing) === Missing
107+
@test quat(Union{Missing, Int}) === Union{Missing, Quaternion{Int}}
96108
end
97109

98110
@testset "random generation" begin

test/runtests.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ using Quaternions
33
using Aqua
44
using RealDot
55

6-
Aqua.test_all(Quaternions)
6+
# Avoid tests on unbound_args.
7+
# https://github.com/JuliaGeometry/Quaternions.jl/pull/132#discussion_r1383817950
8+
Aqua.test_all(Quaternions, unbound_args=false)
79

810
include("helpers.jl")
911
include("Quaternion.jl")

0 commit comments

Comments
 (0)