Closed
Description
I have traced a bug in my code to the fact that norm(::StaticArray)
is considerably less accurate than norm(::Array)
. In code working with rotations, the norm of a small vector, length 2-4, is often used required to very high precision.
To verify that the problem is the naive implementation of norm for static arrays, I modified the norm function like so
@generated function _norm(::Size{S}, a::StaticArray) where {S}
if prod(S) == 0
return :(zero(real(eltype(a))))
end
expr = :(abs2(a[1]))
for j = 2:prod(S)
expr = :($expr + abs2(a[$j]))
end
return quote
return norm(Array(a)) # <------------- convert to standard array and return norm of this instead
$(Expr(:meta, :inline))
@inbounds return sqrt($expr)
end
end
after which the problem goes away.
Would it be feasible to have an implementation of norm that is more accurate, at least for small vectors?
MWE:
julia> using StaticArrays, LinearAlgebra
julia> a = SA[0, 1e-180]
2-element SVector{2, Float64} with indices SOneTo(2):
0.0
1.0e-180
julia> norm(a)
0.0
julia> norm(Array(a))
1.0e-180