Skip to content

norm of StaticArray inaccurate #913

Closed
@baggepinnen

Description

@baggepinnen

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions