Hello,
I have a type instability according to @code_warntype
in the following code. To me it seems all types should be inferable though. What would I need to change to make it type stable?
using StaticArrays
import LinearAlgebra: norm
struct Line{T}
p1::StaticVector{2, T}
p2::StaticVector{2, T}
end
function closest_point_on_line(p::SVector{2, T}, line::Line{T}) where {T}
length_squared = (line.p1[1]-line.p2[1])^2 + (line.p1[2]-line.p2[2])^2
t = clamp(dot( p - line.p1, line.p2 - line.p1 )/length_squared, zero(T), one(T))
return line.p1 + t*(line.p2 - line.p1)
end
@code_warntype closest_point_on_line(SVector(0.0, 1.0), Line(SVector(1.0, 0.0), SVector(1.0, 1.0)))
julia> isconcretetype(StaticVector{2, Float64})
false
julia> isconcretetype(SVector{2, Float64})
true
3 Likes
Oh ok, I somehow assumed StaticVector
would be an alias of SVector
. Thanks for that tip. One instability remains though. Apparently a dot product of 2 SVector
s gives an Any
. I guess there is not much i can do about that, except assert the type of the result?
Itβs type stable for me
julia> @code_warntype dot(a, b)
MethodInstance for LinearAlgebra.dot(::SVector{2, Float64}, ::SVector{2, Float64})
from dot(a::StaticArray, b::StaticArray) @ StaticArrays ~/.julia/packages/StaticArrays/oOCPP/src/linalg.jl:208
Arguments
#self#::Core.Const(LinearAlgebra.dot)
a::SVector{2, Float64}
b::SVector{2, Float64}
Body::Float64
1 β nothing
β %2 = StaticArrays.same_size(a, b)::Core.Const(Size(2,))
β %3 = StaticArrays._vecdot(%2, a, b, StaticArrays.dot)::Float64
βββ return %3
Even if it would be type unstable, you could also implement is as a'b
or using a loop etc., there would be plenty of options
You only imported norm
from LinearAlgebra
and forgot about dot
.
2 Likes