-
Notifications
You must be signed in to change notification settings - Fork 44
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
Correct UnitQuaternion
with Quaternions.jl
#175
Correct UnitQuaternion
with Quaternions.jl
#175
Conversation
Quaternions.jl
UnitQuaternion
with Quaternions.jl
Codecov Report
@@ Coverage Diff @@
## master #175 +/- ##
==========================================
- Coverage 86.33% 86.11% -0.23%
==========================================
Files 14 14
Lines 1325 1340 +15
==========================================
+ Hits 1144 1154 +10
- Misses 181 186 +5
Continue to review full report at Codecov.
|
Please ignore the coverage changes. This will be fixed when changing the field of |
The operators for |
I haven't added the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice @hyrodium.
I have no idea whether this is a bugfix or a breaking change. It's not exactly a new feature. It's possible that someone will rely on the current functionality.
src/unitquaternion.jl
Outdated
vecnorm(q::UnitQuaternion) = sqrt(q.x^2 + q.y^2 + q.z^2) | ||
vecnorm(q::Quaternion) = sqrt(q.v1^2 + q.v2^2 + q.v3^2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't be defining things on behalf of Quaternions.jl.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, that was my mistake. I've removed the line.
src/unitquaternion.jl
Outdated
|
||
# Norms | ||
LinearAlgebra.norm(q::UnitQuaternion) = sqrt(q.w^2 + q.x^2 + q.y^2 + q.z^2) | ||
vecnorm(q::UnitQuaternion) = sqrt(q.x^2 + q.y^2 + q.z^2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The vecnorm
must be defined in terms of the matrix. Which is orthogonal, so that's easy. Should we just define this instead?
vecnorm(::Rotation{N, T}) where {N, T} = convert(T, N)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The vecnorm
function was to calculate the norm of the imaginary part of a quaternion, and it was used only in _log_as_quat
. So, I've removed the function. (09e0313)
src/unitquaternion.jl
Outdated
(\)(q1::UnitQuaternion, q2::UnitQuaternion) = inv(q1)*q2 # Equivalent to inv(q1)*q2 | ||
(/)(q1::UnitQuaternion, q2::UnitQuaternion) = q1*inv(q2) # Equivalent to q1*inv(q2) | ||
|
||
|
||
(\)(q1::UnitQuaternion, q2::UnitQuaternion) = conj(q1)*q2 # Equivalent to inv(q1)*q2 | ||
(/)(q1::UnitQuaternion, q2::UnitQuaternion) = q1*conj(q2) # Equivalent to q1*inv(q2) | ||
|
||
(\)(q::UnitQuaternion, r::SVector{3}) = conj(q)*r # Equivalent to inv(q)*r | ||
(\)(q::UnitQuaternion, r::SVector{3}) = inv(q)*r # Equivalent to inv(q)*r |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aren't these defined for all rotations? (I.e. can they be deleted instead?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With original definition:
julia> @benchmark q\SVector(1,2,3) # q isa UnitQuaternion
BenchmarkTools.Trial: 10000 samples with 996 evaluations.
Range (min … max): 25.933 ns … 1.724 μs ┊ GC (min … max): 0.00% … 97.61%
Time (median): 26.546 ns ┊ GC (median): 0.00%
Time (mean ± σ): 28.727 ns ± 42.051 ns ┊ GC (mean ± σ): 3.85% ± 2.59%
▂▆█▇▄▂ ▁▂▂▂▂▂▁▁ ▁
██████▇▆▇▆▆▆▅▅▅▅▃▅▅▆▆▆▅▅▅▆▇▇▇██████████▇▆▆▆▅▄▄▆▆▆▅▅▆▅▄▅▄▄▄▆ █
25.9 ns Histogram: log(frequency) by time 38.8 ns <
Memory estimate: 32 bytes, allocs estimate: 1.
If Removing the definition:
julia> @benchmark q\SVector(1,2,3) # q isa UnitQuaternion
BenchmarkTools.Trial: 10000 samples with 780 evaluations.
Range (min … max): 160.083 ns … 2.153 μs ┊ GC (min … max): 0.00% … 92.03%
Time (median): 164.683 ns ┊ GC (median): 0.00%
Time (mean ± σ): 167.640 ns ± 44.395 ns ┊ GC (mean ± σ): 0.59% ± 2.06%
▂▃█▁▁
▂▂▁▁▃▇█████▇▇▇▄▄▃▃▃▃▃▃▃▄▄▄▄▃▃▃▃▃▃▃▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂ ▃
160 ns Histogram: frequency by time 186 ns <
Memory estimate: 32 bytes, allocs estimate: 1.
This performance deterioration is because (\)(::Rotation, ::SVector{3})
is not defined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, we need to update the \
definition here. With this update, we'll get more performance with other rotation types.
julia> using Rotations, StaticArrays, BenchmarkTools
julia> r = RotX(2.3)
3×3 RotX{Float64} with indices SOneTo(3)×SOneTo(3)(2.3):
1.0 0.0 0.0
0.0 -0.666276 -0.745705
0.0 0.745705 -0.666276
julia> @benchmark r\SVector(1,2,3)
BenchmarkTools.Trial: 10000 samples with 861 evaluations.
Range (min … max): 138.636 ns … 1.605 μs ┊ GC (min … max): 0.00% … 90.34%
Time (median): 154.602 ns ┊ GC (median): 0.00%
Time (mean ± σ): 156.485 ns ± 31.911 ns ┊ GC (mean ± σ): 0.45% ± 2.01%
▂▇▇▅█▆▄▃▄
▂▁▁▁▁▂▁▂▂▁▂▂▂▂▂▂▂▂▃▂▂▃▃▄▄▄▆█████████▇█▄▃▄▃▄▃▄▄▄▄▅▅▅▄▃▃▂▂▂▂▂▂ ▄
139 ns Histogram: frequency by time 168 ns <
Memory estimate: 32 bytes, allocs estimate: 1.
julia> Base.:\(r::Rotation, v::SVector{3}) = inv(r)*v
julia> @benchmark r\SVector(1,2,3)
BenchmarkTools.Trial: 10000 samples with 994 evaluations.
Range (min … max): 29.926 ns … 1.726 μs ┊ GC (min … max): 0.00% … 97.98%
Time (median): 30.742 ns ┊ GC (median): 0.00%
Time (mean ± σ): 32.839 ns ± 44.139 ns ┊ GC (mean ± σ): 3.54% ± 2.59%
▃███▇▅▃▂ ▁▂▂▂▂▂▂▂▁ ▂
██████████▇▇▇▆▇█▆▆▆▆▅▆▇▆▆▇▇▇███████████▇▆▆▅▅▅▆▅▅▆▅▄▄▄▅▅▅▅▅▆ █
29.9 ns Histogram: log(frequency) by time 43.2 ns <
Memory estimate: 32 bytes, allocs estimate: 1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added the method. (9647c84)
Should we release |
@andyferris |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hyrodium yes feel free to merge
* remove incorrect log(::Quaternion) * add method for log(::Rotation) and return SMatrix * fix log method for Rotation{2} * update tests for logarithm function * add dependency on Quaternions.jl * update exports for deprecated types * update around pure_quaternion * remove incorrect LinearAlgebra.norm * remove incorrect *(::Real, UnitQuaternion) * remove incorrect conj(Quaternion) * remove incorrect -(::UnitQuaternion) * update tests around norm related functions * update src and test around norm related functions * remove unnecessary import from Base * remove exp method for Quaternion * update type conversions UnitQuaternion <-> Quaternion * fix tests for Julia under v1.5 * remove unnecessary lines * remove vecnorm(q::UnitQuaternion) function * update comments * add methods for Base.:\(r::Rotation, v) * update UnitQuaternion constructor
Kindly request in future to please add deprecation cycles as per semver for breaking changes. You can easily overload |
@dehann And related things, I think we need to distinguish among exported method, non-exported method and internal use method.
|
This PR branch is based on #173, so please merge the PR first.
Done
conj(::UnitQuaternion)
-(::UnitQuaternion)
*(::Real, ::UnitQuaternion)
LinearAlgebra.norm(::Real, ::UnitQuaternion)
LinearAlgebra.normalize(::Real, ::UnitQuaternion)
UnitQuaterinon
<->Quaternion
Rotations.pure_quaternion
_pure_quaternion
because this is "private" method.Quaternion
. (previously,UnitQuaternion
)WIP, not in this PR
UnitQuaternoin{T}
sitll have fieldsw::T
,x::T
,y::T
andz::T
, notq::Quaternion{T}
.UnitQuaternion
.QuatRotation
in the future._pure_quaternion
isQuaternion
.InfinitesimalQuatRotation <: InfinitesimalRotation
in the future.