If you don't mind adding a third parameter, you could do this:
immutable SymTensor{N,T,M} <: AbstractArray{T,N}
data::Array{T,M}
end
This doesn't enforce N=2M, but you can do that in the constructor. The
trickiest part is making the constructor type-stable. You could use a
@generated function, but I think this will work:
symtensorsize(data) = (size(data)..., size(data)...)
Base.size(A::SymTensor) = symtensorsize(A.data)
SymTensor(data) = SymTensor(data, symtensorsize(data))
SymTensor{T,N,M}(data::Array{T,M}, dims::NTuple{N,Int}) = SymTensor{N,T,M}
(data)
Let's check it:
julia> @code_warntype SymTensor(rand(5))
Variables:
data::Array{Float64,1}
Body:
begin # none, line 1:
(top(tuple))((Base.arraysize)(data::Array{Float64,1},1)::Int64,
(Base.arraysize)(data::Array{Float64,1},1)::Int64)::Tuple{Int64,Int64}
return $(Expr(:new, SymTensor{2,Float64,1}, :(data::Array{Float64,1})))
end::SymTensor{2,Float64,1}
julia> @code_warntype SymTensor(rand(5,5))
Variables:
data::Array{Float64,2}
Body:
begin # none, line 1:
(top(tuple))((Base.arraysize)(data::Array{Float64,2},1)::Int64,
(Base.arraysize)(data::Array{Float64,2},2)::Int64,(Base.arraysize)
(data::Array{Float64,2},1)::Int64,(Base.arraysize)
(data::Array{Float64,2},2)::Int64)::Tuple{Int64,Int64,Int64,Int64}
return $(Expr(:new, SymTensor{4,Float64,2}, :(data::Array{Float64,2})))
end::SymTensor{4,Float64,2}
So indeed the return type can be inferred.
Best,
--Tim
On Friday, February 19, 2016 08:53:20 AM Kristoffer Carlsson wrote:
> I think a simple example will explain better than I could myself.
>
> What I want to do is something similar to:
>
> immutable foo{1, T}
> data::Vector{T}
> end
>
> immutable foo{2, T}
> data::Matrix{T}
> end
>
> Just like you can specialize functions for different parameter value is
> there a way to specialize the type of the field for a specific parameter
> value.
>
> What I reality want to do is to store second order symmetric tensors with a
> vector as data and fourth order symmetric tensors with a matrix as data.
>
> But I still want to be able to have my type as SymmetricTensor{dimension,
> order}
>
> // Kristoffer