Compact way to store Diagonal static matrices?

I want to store a large number of Diagonal 3x3 matrices. I am considering using a HybridArray whose individual elements are these 3x3 matrices. In my case I know that the matrices are Diagonal. I’m not sure which of these two are the best choices:

  1. Diagonal(::SVector{3}): preserves structure, but not static. It might be possible to wrap the size around this to obtain that information in at compile time.
  2. SMatrix{3,3}: Static, but stores unnecessary zeros and does not preserve structure.

Assuming that memory isn’t the main limitation, is it better to use the SMatrix approach over the Diagonal one? Of course the specific choice will depend on the limiting factor in the problem, but I just wanted to know if there is any obvious pitfall with either of these approaches when it comes to performance.

Diagonal(::SVector{3}) should still be completely static. Thanks to constant prop, the size information will even be known at compile time in a lot of cases, i.e.:


julia> using StaticArrays, LinearAlgebra

julia> m = Diagonal(SA[1., 2., 3.])
3×3 Diagonal{Float64, SVector{3, Float64}}:
 1.0   ⋅    ⋅ 
  ⋅   2.0   ⋅ 
  ⋅    ⋅   3.0

julia> @code_typed size(m)
CodeInfo(
1 ─     return (3, 3)
) => Tuple{Int64, Int64}
3 Likes

If you need to store a lot of diagonal 3x3 matrices then an array of diagonal static matrices looks like a good choice, something like [Diagonal(SA[i, 1.0, 2.0]) for i in 1:10]. Size information should be correctly propagated, and if it’s not for some operation, please report it :slightly_smiling_face: . By the way, HybridArray doesn’t currently support representing this kind of structure.

1 Like