@@ -316,11 +316,14 @@ end
316316
317317for randf in (:rand , :randn , :randexp , :randisometry )
318318 _docstr = """
319- $randf ([rng=default_rng()], [T =Float64], codomain::ProductSpace{S,N₁},
319+ $randf ([rng=default_rng()], [TorA =Float64], codomain::ProductSpace{S,N₁},
320320 domain::ProductSpace{S,N₂}) where {S,N₁,N₂,T} -> t
321- $randf ([rng=default_rng()], [T =Float64], codomain ← domain) -> t
321+ $randf ([rng=default_rng()], [TorA =Float64], codomain ← domain) -> t
322322
323323 Generate a tensor `t` with entries generated by `$randf `.
324+ The type `TorA` can be used to control the element type and
325+ data type generated. For example, if `TorA` is a `SparseVector{ComplexF32}`,
326+ then the final output `TensorMap` will have that as its storage type.
324327
325328 See also [`Random.$(randf) !`](@ref).
326329 """
@@ -349,25 +352,25 @@ for randf in (:rand, :randn, :randexp, :randisometry)
349352 return $ randfun (codomain ← domain)
350353 end
351354 function $randfun (
352- :: Type{T } , codomain:: TensorSpace{S} , domain:: TensorSpace{S}
353- ) where {T , S <: IndexSpace }
354- return $ randfun (T , codomain ← domain)
355+ :: Type{TorA } , codomain:: TensorSpace{S} , domain:: TensorSpace{S}
356+ ) where {TorA , S <: IndexSpace }
357+ return $ randfun (TorA , codomain ← domain)
355358 end
356359 function $randfun (
357- rng:: Random.AbstractRNG , :: Type{T } , codomain:: TensorSpace{S} , domain:: TensorSpace{S}
358- ) where {T , S <: IndexSpace }
359- return $ randfun (rng, T , codomain ← domain)
360+ rng:: Random.AbstractRNG , :: Type{TorA } , codomain:: TensorSpace{S} , domain:: TensorSpace{S}
361+ ) where {TorA , S <: IndexSpace }
362+ return $ randfun (rng, TorA , codomain ← domain)
360363 end
361364
362365 # accepting single `TensorSpace`
363366 $ randfun (codomain:: TensorSpace ) = $ randfun (codomain ← one (codomain))
364- function $randfun (:: Type{T } , codomain:: TensorSpace ) where {T }
365- return $ randfun (T , codomain ← one (codomain))
367+ function $randfun (:: Type{TorA } , codomain:: TensorSpace ) where {TorA }
368+ return $ randfun (TorA , codomain ← one (codomain))
366369 end
367370 function $randfun (
368- rng:: Random.AbstractRNG , :: Type{T } , codomain:: TensorSpace
369- ) where {T }
370- return $ randfun (rng, T , codomain ← one (domain))
371+ rng:: Random.AbstractRNG , :: Type{TorA } , codomain:: TensorSpace
372+ ) where {TorA }
373+ return $ randfun (rng, TorA , codomain ← one (domain))
371374 end
372375
373376 # filling in default eltype
@@ -377,16 +380,16 @@ for randf in (:rand, :randn, :randexp, :randisometry)
377380 end
378381
379382 # filling in default rng
380- function $randfun (:: Type{T } , V:: TensorMapSpace ) where {T }
381- return $ randfun (Random. default_rng (), T , V)
383+ function $randfun (:: Type{TorA } , V:: TensorMapSpace ) where {TorA }
384+ return $ randfun (Random. default_rng (), TorA , V)
382385 end
383386 $ randfun! (t:: AbstractTensorMap ) = $ randfun! (Random. default_rng (), t)
384387
385388 # implementation
386389 function $randfun (
387- rng:: Random.AbstractRNG , :: Type{T } , V:: TensorMapSpace
388- ) where {T }
389- t = TensorMap {T} (undef, V)
390+ rng:: Random.AbstractRNG , :: Type{TorA } , V:: TensorMapSpace
391+ ) where {TorA }
392+ t = tensormaptype ( spacetype (V), numout (V), numin (V), TorA) (undef, V)
390393 $ randfun! (rng, t)
391394 return t
392395 end
@@ -406,18 +409,22 @@ Base.copy(t::TensorMap) = typeof(t)(copy(t.data), t.space)
406409
407410# Conversion between TensorMap and Dict, for read and write purpose
408411# ------------------------------------------------------------------
412+ # We want to store the block data using simple data types,
413+ # rather tha reshaped views or some other wrapped array type.
414+ # Since this method is meant for storing data on disk, we can
415+ # freely collect data to the CPU
409416function Base. convert (:: Type{Dict} , t:: AbstractTensorMap )
410417 d = Dict {Symbol, Any} ()
411418 d[:codomain ] = repr (codomain (t))
412419 d[:domain ] = repr (domain (t))
413420 data = Dict {String, Any} ()
414421 for (c, b) in blocks (t)
415- data[repr (c)] = b
422+ data[repr (c)] = Array (b)
416423 end
417424 d[:data ] = data
418425 return d
419426end
420- function Base. convert (:: Type{<: TensorMap} , d:: Dict{Symbol, Any} )
427+ function Base. convert (:: Type{TensorMap} , d:: Dict{Symbol, Any} )
421428 try
422429 codomain = eval (Meta. parse (d[:codomain ]))
423430 domain = eval (Meta. parse (d[:domain ]))
@@ -522,6 +529,11 @@ function Base.convert(::Type{TensorMap}, t::AbstractTensorMap)
522529 return copy! (TensorMap {scalartype(t)} (undef, space (t)), t)
523530end
524531
532+ function Base. convert (:: Type{TensorMapWithStorage{T, A}} , t:: TensorMap ) where {T, A}
533+ d_data = convert (A, t. data)
534+ return TensorMapWithStorage {T, A} (d_data, space (t))
535+ end
536+
525537function Base. convert (
526538 TT:: Type{TensorMap{T, S, N₁, N₂, A}} , t:: AbstractTensorMap{<:Any, S, N₁, N₂}
527539 ) where {T, S, N₁, N₂, A}
536548function Base. promote_rule (
537549 :: Type{<:TT₁} , :: Type{<:TT₂}
538550 ) where {S, N₁, N₂, TT₁ <: TensorMap{<:Any, S, N₁, N₂} , TT₂ <: TensorMap{<:Any, S, N₁, N₂} }
539- A = VectorInterface. promote_add (storagetype (TT₁), storagetype (TT₂))
540- T = scalartype (A )
541- return TensorMap{T, S, N₁, N₂, A}
551+ T = VectorInterface. promote_add (scalartype (TT₁), scalartype (TT₂))
552+ A = promote_storagetype ( similarstoragetype (TT₁, T), similarstoragetype (TT₂, T) )
553+ return tensormaptype ( S, N₁, N₂, A)
542554end
0 commit comments