using StaticArrays
struct JustMyType{N,M}
a::Vector{<:SMatrix{N,M,Float64}}
b:: SMatrix{N,M,Float64}
end
j = JustMyType([SMatrix{2,3,Float64}(randn(2,3)) for i=1:4],
SMatrix{2,3,Float64}(randn(2,3)) )
Note the <: . My previous version of the code without it fails, because SMatrix{N,M,Float64} is an abstract type (the single concrete type corresponding to it being SMatrix{N,M,Float64,N*M}.
Coding
a::Vector{SMatrix{N,M,Float64,N*M}}
does not work - one cannot multiply type parameters.
For some reason I do not understand, but likely related to N*M not being legit, the developers of StaticArrays.jl had to have a length parameter to an SMatrix. One way I could write my code is to let JustMyType also have this parameter. However, I am not keen, because in a real world situation with many StaticArrays in my type, this generates many parameters, a source of bugs and poor readability of code and typeofoutputs.
As coded now, my structure has fields of abstract types, and I am set for type-unstable code.
I’ll have to chose between readability and performance, unless you can point out something I missed!
Your requirements are not very clear, but something like
struct JustMyType{T}
a::Vector{T}
b::T
end
should work.
Don’t overtype things. If absolutely necessary, you can make T <: AbstractMatrix, or validate that it is an SMatrix in the constructor, or use a triangular parametrization like
struct JustMyType{N,M,T<:SMatrix{N,M}}
a::Vector{T}
b::T
end
which I had in a previous version of my code. It’s neat and performant code. However, the real-world equivalent (a structure with many different arrays) of typing typeof(j)returns a type description with the detailed description of the type of all these arrays. I want the user of my code to have a “friendly” relation to typeof(j).
So to be more specific. I wish to refactor the above code to have
few type parameters - not having to provide L which is obviously M times N
integer type parameters (for readability of the concrete type of j), so T is not welcome.
The type system is not the place to express these kind of constraints. Extra type parameters of this kind are standard in Julia, and generally innocuous. You can, of course, design your user-facing API so that L does not need to be specified by the user — see how StaticArrays does it.
The static arrays have elements have themselves complicated elements, so using your T patterm in a previous version of my real world code, typeof would return between 5 and 10 lines of hard-to-read details, and I was not happy with that.
As I said, I was fishing for ideas, but I believe now I was aware of all the options. I have now gone for a solution in which I accept the small annoyance of having L (and its real-world siblings) as an extra parameter to my type.
Tamas, it’s not the first time you help me: thank you again!
Also consider using the macros defined by ConcreteStructs.jl! They can simplify some of these extraneous type parameters, and will give you more terse and readable type printouts for free. I find it makes working with these parametric structs a bit more user friendly.