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

Use numerically robust norm #622

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

baggepinnen
Copy link

This PR is mostly a FYI regarding JuliaArrays/StaticArrays.jl#913
Depending on whether or not that issue is closed, you may want to switch to explicitly calling generic_norm2 on static vectors to circumvent the accuracy issue. The issue arises when combining static arrays with ForwardDiff, in our case it occured in exp(::SkewSymmetric) using my implementation in Robotlib
https://github.com/baggepinnen/Robotlib.jl/blob/master/src/utils.jl#L94

I did some benchmarking, and generic_norm2 is faster than norm for all standard arrays up to at least length 9. For static arrays, it appears to do okay as well, while avoiding the accuracy issue.

julia> a
3-element SVector{3, Int64} with indices SOneTo(3):
 1
 2
 3

julia> @btime norm($(Ref(a))[]) # standard norm of static array
  5.135 ns (0 allocations: 0 bytes)
3.74166

julia> @btime norm($(Ref(Vector(a)))[]) # standard norm of  array
  8.545 ns (0 allocations: 0 bytes)
3.74166

julia> @btime LinearAlgebra.generic_norm2($(Ref((a)))[]) # generic_norm2 of static array
  4.490 ns (0 allocations: 0 bytes)
3.74166

julia> @btime LinearAlgebra.generic_norm2($(Ref(Vector(a)))[]) # generic_norm2 of array
  7.671 ns (0 allocations: 0 bytes)
3.74166

This PR is mostly a FYI regarding JuliaArrays/StaticArrays.jl#913
Depending on whether or not that issue is closed, you may want to switch to explicitly calling `generic_norm2` on static vectors to circumvent the accuracy issue. The issue arises when combining static arrays with ForwardDiff, in our case it occured in `exp(::SkewSymmetric)`. 

I did some benchmarking, and `generic_norm2` is faster than `norm` for all standard arrays up to at least length 9. For static arrays, it appears to do okay as well, while avoiding the accuracy issue.
```julia
julia> a
3-element SVector{3, Int64} with indices SOneTo(3):
 1
 2
 3

julia> @Btime norm($(Ref(a))[]) # standard norm of static array
  5.135 ns (0 allocations: 0 bytes)
3.74166

julia> @Btime norm($(Ref(Vector(a)))[]) # standard norm of  array
  8.545 ns (0 allocations: 0 bytes)
3.74166

julia> @Btime LinearAlgebra.generic_norm2($(Ref((a)))[]) # generic_norm2 of static array
  4.490 ns (0 allocations: 0 bytes)
3.74166

julia> @Btime LinearAlgebra.generic_norm2($(Ref(Vector(a)))[]) # generic_norm2 of array
  7.671 ns (0 allocations: 0 bytes)
3.74166

```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant