@@ -31,6 +31,8 @@ struct TensorMap{T, S <: IndexSpace, N₁, N₂, A <: DenseVector{T}} <: Abstrac
3131 I = sectortype (S)
3232 T <: Real && ! (sectorscalartype (I) <: Real ) &&
3333 @warn (" Tensors with real data might be incompatible with sector type $I " , maxlog = 1 )
34+ d = fusionblockstructure (space). totaldim
35+ length (data) == d || throw (DimensionMismatch (" invalid length of data" ))
3436 return new {T, S, N₁, N₂, A} (data, space)
3537 end
3638end
@@ -47,19 +49,20 @@ i.e. a tensor map with only a non-trivial output space.
4749const Tensor{T, S, N, A} = TensorMap{T, S, N, 0 , A}
4850
4951function tensormaptype (S:: Type{<:IndexSpace} , N₁, N₂, TorA:: Type )
50- if TorA <: Number
51- return TensorMap{TorA, S, N₁, N₂, Vector{TorA}}
52- elseif TorA <: DenseVector
53- return TensorMap{scalartype (TorA), S, N₁, N₂, TorA}
54- else
55- throw (ArgumentError (" argument $TorA should specify a scalar type (`<:Number`) or a storage type `<:DenseVector{<:Number}`" ))
56- end
52+ A = _tensormap_storagetype (TorA)
53+ A <: DenseVector || throw (ArgumentError (" Cannot determine a valid storage type from argument $TorA " ))
54+ return TensorMap{scalartype (A), S, N₁, N₂, A}
5755end
5856
5957# hook for mapping input types to storage types -- to be implemented in extensions
60- _tensormap_storagetype (:: Type{A} ) where {A <: AbstractArray } = _tensormap_storagetype (scalartype (A))
6158_tensormap_storagetype (:: Type{A} ) where {A <: DenseVector{<:Number} } = A
59+ _tensormap_storagetype (:: Type{A} ) where {A <: Array } = _tensormap_storagetype (scalartype (A))
6260_tensormap_storagetype (:: Type{T} ) where {T <: Number } = Vector{T}
61+ function _tensormap_storagetype (:: Type{A} ) where {A <: AbstractArray }
62+ PA = parenttype (A)
63+ PA === A && throw (MethodError (_tensormap_storagetype, A)) # avoid infinite recursion
64+ return _tensormap_storagetype (PA)
65+ end
6366
6467# Basic methods for characterising a tensor:
6568# --------------------------------------------
@@ -95,7 +98,7 @@ const TensorWithStorage{T, A <: DenseVector{T}, S, N} = Tensor{T, S, N, A}
9598Construct a `TensorMap` with uninitialized data with elements of type `T`.
9699"""
97100TensorMap {T} (:: UndefInitializer , V:: TensorMapSpace ) where {T} =
98- TensorMapWithStorage {T, _tensormap_storagetype(T)} (undef, V)
101+ tensormaptype ( spacetype (V), numout (V), numin (V), T) (undef, V)
99102TensorMap {T} (:: UndefInitializer , codomain:: TensorSpace , domain:: TensorSpace ) where {T} =
100103 TensorMap {T} (undef, codomain ← domain)
101104Tensor {T} (:: UndefInitializer , V:: TensorSpace ) where {T} = TensorMap {T} (undef, V ← one (V))
@@ -108,7 +111,7 @@ Tensor{T}(::UndefInitializer, V::TensorSpace) where {T} = TensorMap{T}(undef, V
108111Construct a `TensorMap` with uninitialized data stored as `A <: DenseVector{T}`.
109112"""
110113TensorMapWithStorage {T, A} (:: UndefInitializer , V:: TensorMapSpace ) where {T, A} =
111- TensorMap {T, spacetype(V), numout(V), numin(V), A} (undef, V)
114+ tensormaptype ( spacetype (V), numout (V), numin (V), A) (undef, V)
112115TensorMapWithStorage {T, A} (:: UndefInitializer , codomain:: TensorSpace , domain:: TensorSpace ) where {T, A} =
113116 TensorMapWithStorage {T, A} (undef, codomain ← domain)
114117TensorWithStorage {T, A} (:: UndefInitializer , V:: TensorSpace ) where {T, A} = TensorMapWithStorage {T, A} (undef, V ← one (V))
@@ -128,7 +131,7 @@ Construct a `TensorMap` from the given raw data.
128131This constructor takes ownership of the provided vector, and will not make an independent copy.
129132"""
130133TensorMap {T} (data:: DenseVector{T} , V:: TensorMapSpace ) where {T} =
131- TensorMapWithStorage {T, typeof(data)} (data, V)
134+ tensormaptype ( spacetype (V), numout (V), numin (V), typeof (data)) (data, V)
132135TensorMap {T} (data:: DenseVector{T} , codomain:: TensorSpace , domain:: TensorSpace ) where {T} =
133136 TensorMap {T} (data, codomain ← domain)
134137
@@ -141,8 +144,7 @@ Construct a `TensorMap` from the given raw data.
141144This constructor takes ownership of the provided vector, and will not make an independent copy.
142145"""
143146function TensorMapWithStorage {T, A} (data:: A , V:: TensorMapSpace ) where {T, A}
144- length (data) == dim (V) || throw (DimensionMismatch (" invalid length of data" ))
145- return TensorMap {T, spacetype(V), numout(V), numin(V), A} (data, V)
147+ return tensormaptype (spacetype (V), numout (V), numin (V), typeof (data))(data, V)
146148end
147149TensorMapWithStorage {T, A} (data:: A , codomain:: TensorSpace , domain:: TensorSpace ) where {T, A} =
148150 TensorMapWithStorage {T, A} (data, codomain ← domain)
@@ -213,11 +215,11 @@ function TensorMapWithStorage{T, A}(
213215 ) where {T, A}
214216 # refer to specific raw data constructors if input is a vector of the correct length
215217 ndims (data) == 1 && length (data) == dim (V) &&
216- return TensorMap {T, spacetype(V), numout(V), numin(V), A} (data, V)
218+ return tensormaptype ( spacetype (V), numout (V), numin (V), A) (data, V)
217219
218220 # special case trivial: refer to same method, but now with vector argument
219221 sectortype (V) === Trivial &&
220- return TensorMap {T, spacetype(V), numout(V), numin(V), A} (reshape (data, length (data)), V)
222+ return tensormaptype ( spacetype (V), numout (V), numin (V), A) (reshape (data, length (data)), V)
221223
222224 # do projection
223225 t = TensorMapWithStorage {T, A} (undef, V)
@@ -230,7 +232,7 @@ function TensorMapWithStorage{T, A}(
230232 return t
231233end
232234TensorMapWithStorage {T, A} (data:: AbstractArray , codom:: TensorSpace , dom:: TensorSpace ; kwargs... ) where {T, A} =
233- TensorMapWithStorage (data, codom ← dom; kwargs... )
235+ TensorMapWithStorage {T, A} (data, codom ← dom; kwargs... )
234236TensorWithStorage {T, A} (data:: AbstractArray , codom:: TensorSpace ; kwargs... ) where {T, A} =
235237 TensorMapWithStorage {T, A} (data, codom ← one (codom); kwargs... )
236238
0 commit comments