JuliaGeometry / Quaternions.jl

A Julia implementation of quaternions
https://juliageometry.github.io/Quaternions.jl
MIT License
116 stars 37 forks source link

Add more methods to `quat` #132

Closed hyrodium closed 9 months ago

hyrodium commented 10 months ago

Abstract

This PR adds more methods to quat.

Before this PR

julia> using Quaternions

julia> quat(missing)
ERROR: MethodError: no method matching Quaternion(::Missing)

After this PR

julia> using Quaternions

julia> quat(missing)
missing

This behavior is consistent with Base.complex.

julia> complex(missing)
missing

How to find the methods to add

I have confirmed the methods with the methods function.

julia> using Quaternions

julia> methods(complex)
# 13 methods for generic function "complex" from Base:
  [1] complex(z::Complex)
     @ complex.jl:172
  [2] complex(x::Real)
     @ complex.jl:173
  [3] complex(x::Real, y::Real)
     @ complex.jl:174
  [4] complex(::Type{T}) where T<:Real
     @ complex.jl:191
  [5] complex(::Type{Complex{T}}) where T<:Real
     @ complex.jl:192
  [6] complex(S::SparseArrays.SparseMatrixCSC)
     @ SparseArrays ~/.julia/juliaup/julia-1.9.3+0.x64.linux.gnu/share/julia/stdlib/v1.9/SparseArrays/src/sparsematrix.jl:936
  [7] complex(x::SparseArrays.AbstractSparseVector{<:Complex})
     @ SparseArrays ~/.julia/juliaup/julia-1.9.3+0.x64.linux.gnu/share/julia/stdlib/v1.9/SparseArrays/src/sparsevector.jl:1083
  [8] complex(x::SparseArrays.AbstractSparseVector)
     @ SparseArrays ~/.julia/juliaup/julia-1.9.3+0.x64.linux.gnu/share/julia/stdlib/v1.9/SparseArrays/src/sparsevector.jl:1084
  [9] complex(A::AbstractArray{<:Complex})
     @ complex.jl:1117
 [10] complex(A::AbstractArray{T}) where T
     @ complex.jl:1119
 [11] complex(::Type{Missing})
     @ missing.jl:111
 [12] complex(::Type{Union{Missing, T}}) where T
     @ missing.jl:112
 [13] complex(::Missing)
     @ missing.jl:101

julia> methods(quat)
# 9 methods for generic function "quat" from Quaternions:
 [1] quat(q::Quaternion)
     @ ~/.julia/dev/Quaternions/src/Quaternion.jl:52
 [2] quat(s::Real)
     @ ~/.julia/dev/Quaternions/src/Quaternion.jl:53
 [3] quat(s::Real, v1::Real, v2::Real, v3::Real)
     @ ~/.julia/dev/Quaternions/src/Quaternion.jl:54
 [4] quat(A::AbstractArray{T}) where T
     @ ~/.julia/dev/Quaternions/src/Quaternion.jl:58
 [5] quat(::Type{T}) where T<:Real
     @ ~/.julia/dev/Quaternions/src/Quaternion.jl:80
 [6] quat(::Type{Quaternion{T}}) where T<:Real
     @ ~/.julia/dev/Quaternions/src/Quaternion.jl:81
 [7] quat(::Type{Missing})
     @ ~/.julia/dev/Quaternions/src/Quaternion.jl:85
 [8] quat(::Type{Union{Missing, T}}) where T
     @ ~/.julia/dev/Quaternions/src/Quaternion.jl:86
 [9] quat(::Missing)
     @ ~/.julia/dev/Quaternions/src/Quaternion.jl:83

Note that this PR does not contain methods with SparseArrays because there were some performance degressions.

julia> using BenchmarkTools, SparseArrays, Quaternions

julia> M = sprand(Float64, 16, 32, 0.5)
16×32 SparseMatrixCSC{Float64, Int64} with 261 stored entries:
⎡⣅⢶⡢⠫⠿⠢⢽⣃⠾⣠⣾⢕⠝⠅⠩⢗⎤
⎢⠃⢱⡜⣴⠓⣂⢼⡁⢴⣴⢘⡊⠯⡒⡚⣞⎥
⎢⣥⡕⠏⢯⠫⠲⠦⠓⢁⣂⢚⣹⣕⢺⢼⢎⎥
⎣⣜⡩⣛⢝⣄⢿⠈⠨⢴⢕⢒⡿⡡⣱⣑⡪⎦

julia> @benchmark quat(M)
BenchmarkTools.Trial: 10000 samples with 10 evaluations.
 Range (min … max):  1.300 μs … 208.680 μs  ┊ GC (min … max):  0.00% … 95.74%
 Time  (median):     1.831 μs               ┊ GC (median):     0.00%
 Time  (mean ± σ):   2.394 μs ±   7.297 μs  ┊ GC (mean ± σ):  13.67% ±  4.51%

   ▂▄▄▅▆▇██▇▆▆▆▅▄▃▁▁                       ▁▂▂▂ ▁             ▂
  ▆███████████████████▇▇▇▇▆▆▆▄▅▅▅▂▄▅▅▂▅▇▇██████████████▇▇█▇▆▆ █
  1.3 μs       Histogram: log(frequency) by time      4.88 μs <

 Memory estimate: 10.88 KiB, allocs estimate: 4.

julia> Quaternions.quat(S::SparseMatrixCSC) = SparseMatrixCSC(size(S, 1), size(S, 2), copy(SparseArrays.getcolptr(S)), copy(rowvals(S)), quat(copy(nonzeros(S))))

julia> @benchmark quat(M)
BenchmarkTools.Trial: 10000 samples with 10 evaluations.
 Range (min … max):  1.631 μs … 180.029 μs  ┊ GC (min … max):  0.00% … 94.98%
 Time  (median):     2.170 μs               ┊ GC (median):     0.00%
 Time  (mean ± σ):   2.681 μs ±   8.186 μs  ┊ GC (mean ± σ):  15.66% ±  5.05%

          ▃██▂                                                 
  ▁▂▂▂▂▃▄▇████▆▃▂▂▂▂▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ▂
  1.63 μs         Histogram: frequency by time        4.81 μs <

 Memory estimate: 13.06 KiB, allocs estimate: 5.

The above definition Quaternions.quat(S::SparseMatrixCSC) is from:

https://github.com/JuliaSparse/SparseArrays.jl/blob/bd2bda8f45ed71374223068b0a0daa2b169071c9/src/sparsematrix.jl#L984

codecov[bot] commented 9 months ago

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Comparison is base (89232ef) 100.00% compared to head (538a840) 100.00%. Report is 1 commits behind head on main.

Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #132 +/- ## ========================================= Coverage 100.00% 100.00% ========================================= Files 2 2 Lines 162 173 +11 ========================================= + Hits 162 173 +11 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.