@@ -306,7 +306,7 @@ function emptyITensor((::Type{ElT}) = EmptyNumber) where {ElT <: Number}
306306 return itensor (EmptyTensor (ElT, ()))
307307end
308308
309- using NDTensors. TypeParameterAccessors : set_eltype, type_parameters, specify_type_parameters
309+ using NDTensors: AllowAlias, NeverAlias
310310"""
311311 ITensor([ElT::Type, ]A::AbstractArray, inds)
312312 ITensor([ElT::Type, ]A::AbstractArray, inds::Index...)
@@ -350,17 +350,35 @@ T[i => 1, j => 1] == 3.3
350350"""
351351function ITensor (
352352 as:: AliasStyle ,
353- eltype :: Type{<:Number} ,
353+ elt :: Type{<:Number} ,
354354 A:: AbstractArray{<:Number} ,
355355 inds:: Indices ;
356356 kwargs... ,
357357 )
358- length (A) ≠ dim (inds) && throw (
359- DimensionMismatch (
360- " In ITensor(::AbstractArray, inds), length of AbstractArray ($(length (A)) ) must match total dimension of IndexSet ($(dim (inds)) )" ,
361- ),
362- )
363- data = set_eltype (typeof (A), eltype)(as, A)
358+ check_dims (A, inds)
359+ # Other cases already handle when `elt ≡ eltype(A)`
360+ # so here we only need to handle when they differ
361+ # (which always involves a copy).
362+ # This is equivalent to `copy!(similar(A, elt), A)`.
363+ data = AbstractArray {elt} (A)
364+ return itensor (Dense (data), inds)
365+ end
366+
367+ function ITensor (
368+ as:: AliasStyle ,
369+ eltype:: Type{T} ,
370+ A:: AbstractArray{T} ,
371+ inds:: Indices ;
372+ kwargs... ,
373+ ) where {T <: Number }
374+ check_dims (A, inds)
375+ data = if as ≡ AllowAlias ()
376+ A
377+ elseif as ≡ NeverAlias ()
378+ copy (A)
379+ else
380+ error (" Unknown AliasStyle: $as " )
381+ end
364382 return itensor (Dense (data), inds)
365383end
366384
@@ -381,6 +399,15 @@ function ITensor(
381399 return ITensor (as, eltype, Matrix (A), inds; kwargs... )
382400end
383401
402+ function check_dims (A:: AbstractArray , inds:: Indices )
403+ length (A) ≠ dim (inds) && throw (
404+ DimensionMismatch (
405+ " In ITensor(::AbstractArray, inds), length of AbstractArray ($(length (A)) ) must match total dimension of IndexSet ($(dim (inds)) )" ,
406+ ),
407+ )
408+ return nothing
409+ end
410+
384411function ITensor (
385412 as:: AliasStyle , eltype:: Type{<:Number} , A:: AbstractArray{<:Number} , is... ; kwargs...
386413 )
@@ -470,13 +497,36 @@ The version `diagitensor` might output an ITensor whose storage data
470497is an alias of the input vector data in order to minimize operations.
471498"""
472499function diag_itensor (
473- as:: AliasStyle , eltype :: Type{<:Number} , v:: AbstractVector{<:Number} , is:: Indices
500+ as:: AliasStyle , elt :: Type{<:Number} , v:: AbstractVector{<:Number} , is:: Indices
474501 )
502+ check_diag_dims (v, is)
503+ # Other cases already handle when `elt ≡ eltype(v)`
504+ # so here we only need to handle when they differ
505+ # (which always involves a copy).
506+ # This is equivalent to `copy!(similar(v, elt), v)`.
507+ data = AbstractVector {elt} (v)
508+ return itensor (Diag (data), is)
509+ end
510+
511+ function diag_itensor (
512+ as:: AliasStyle , elt:: Type{T} , v:: AbstractVector{T} , is:: Indices
513+ ) where {T <: Number }
514+ check_diag_dims (v, is)
515+ data = if as ≡ AllowAlias ()
516+ v
517+ elseif as ≡ NeverAlias ()
518+ copy (v)
519+ else
520+ error (" Unknown AliasStyle: $as " )
521+ end
522+ return itensor (Diag (data), is)
523+ end
524+
525+ function check_diag_dims (v:: AbstractVector , is:: Indices )
475526 length (v) ≠ mindim (is) && error (
476527 " Length of vector for diagonal must equal minimum of the dimension of the input indices" ,
477528 )
478- data = set_eltype (typeof (v), eltype)(as, v)
479- return itensor (Diag (data), is)
529+ return nothing
480530end
481531
482532function diag_itensor (
@@ -671,16 +721,6 @@ zero(T::ITensor)::ITensor = itensor(zero(tensor(T)))
671721# Construct from Array
672722#
673723
674- # Helper functions for different view behaviors
675- # TODO : Move to NDTensors.jl
676- function (arraytype:: Type{<:AbstractArray} )(:: NeverAlias , A:: AbstractArray )
677- return specify_type_parameters (arraytype, type_parameters (A))(A)
678- end
679-
680- function (arraytype:: Type{<:AbstractArray} )(:: AllowAlias , A:: AbstractArray )
681- return convert (specify_type_parameters (arraytype, type_parameters (A)), A)
682- end
683-
684724"""
685725 Array{ElT, N}(T::ITensor, i:Index...)
686726 Array{ElT}(T::ITensor, i:Index...)
0 commit comments