Skip to content

Commit 514424f

Browse files
authored
Merge c14150c into 74095ef
2 parents 74095ef + c14150c commit 514424f

File tree

26 files changed

+622
-143
lines changed

26 files changed

+622
-143
lines changed

NDTensors/src/NDTensors.jl

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,32 @@ include("empty/adapt.jl")
132132

133133
#####################################
134134
# Array Tensor (experimental)
135-
# TODO: Move to `Experimental` module.
136135
#
137-
include("arraytensor/arraytensor.jl")
138-
include("arraytensor/array.jl")
139-
include("arraytensor/blocksparsearray.jl")
136+
include("arraystorage/arraystorage/storage/arraystorage.jl")
137+
include("arraystorage/arraystorage/storage/conj.jl")
138+
include("arraystorage/arraystorage/storage/permutedims.jl")
139+
include("arraystorage/arraystorage/storage/contract.jl")
140+
141+
include("arraystorage/arraystorage/tensor/arraystorage.jl")
142+
include("arraystorage/arraystorage/tensor/zeros.jl")
143+
include("arraystorage/arraystorage/tensor/indexing.jl")
144+
include("arraystorage/arraystorage/tensor/permutedims.jl")
145+
include("arraystorage/arraystorage/tensor/mul.jl")
146+
include("arraystorage/arraystorage/tensor/contract.jl")
147+
include("arraystorage/arraystorage/tensor/qr.jl")
148+
include("arraystorage/arraystorage/tensor/eigen.jl")
149+
include("arraystorage/arraystorage/tensor/svd.jl")
150+
151+
# DiagonalArray storage
152+
include("arraystorage/diagonalarray/tensor/contract.jl")
153+
154+
# BlockSparseArray storage
155+
include("arraystorage/blocksparsearray/storage/contract.jl")
156+
157+
# Combiner storage
158+
include("arraystorage/combiner/storage/contract.jl")
159+
160+
include("arraystorage/combiner/tensor/contract.jl")
140161

141162
#####################################
142163
# Deprecations

NDTensors/src/abstractarray/fill.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ function generic_randn(
88
return randn!(rng, data)
99
end
1010

11-
function generic_zeros(arraytype::Type{<:AbstractArray}, dim::Integer=0)
11+
function generic_zeros(arraytype::Type{<:AbstractArray}, dims...)
1212
arraytype_specified = set_unspecified_parameters(
1313
leaf_parenttype(arraytype), DefaultParameters()
1414
)
1515
ElT = eltype(arraytype_specified)
16-
return fill!(similar(arraytype_specified, dim), zero(ElT))
16+
return fill!(similar(arraytype_specified, dims...), zero(ElT))
1717
end

NDTensors/src/abstractarray/similar.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ function similar(array::AbstractArray, eltype::Type, dims::Tuple)
7777
return NDTensors.similar(similartype(typeof(array), eltype), dims)
7878
end
7979

80+
# NDTensors.similar
81+
function similar(array::AbstractArray, eltype::Type, dims::Int)
82+
return NDTensors.similar(similartype(typeof(array), eltype), dims)
83+
end
84+
8085
# NDTensors.similar
8186
similar(array::AbstractArray, dims::Tuple) = NDTensors.similar(typeof(array), dims)
8287

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Used for dispatch to distinguish from Tensors wrapping TensorStorage.
2+
# Remove once TensorStorage is removed.
3+
const ArrayStorage{T,N} = Union{
4+
Array{T,N},
5+
ReshapedArray{T,N},
6+
SubArray{T,N},
7+
PermutedDimsArray{T,N},
8+
StridedView{T,N},
9+
BlockSparseArray{T,N},
10+
}
11+
12+
const MatrixStorage{T} = Union{
13+
ArrayStorage{T,2},
14+
Transpose{T},
15+
Adjoint{T},
16+
Symmetric{T},
17+
Hermitian{T},
18+
UpperTriangular{T},
19+
LowerTriangular{T},
20+
UnitUpperTriangular{T},
21+
UnitLowerTriangular{T},
22+
Diagonal{T},
23+
}
24+
25+
const MatrixOrArrayStorage{T} = Union{MatrixStorage{T},ArrayStorage{T}}
26+
27+
# TODO: Delete once `Dense` is removed.
28+
function to_arraystorage(x::DenseTensor)
29+
return tensor(reshape(data(x), size(x)), inds(x))
30+
end
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
conj(as::AliasStyle, A::AbstractArray) = conj(A)
2+
conj(as::AllowAlias, A::Array{<:Real}) = A

NDTensors/src/arraytensor/array.jl renamed to NDTensors/src/arraystorage/arraystorage/storage/contract.jl

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# Combiner
2-
promote_rule(::Type{<:Combiner}, arraytype::Type{<:MatrixOrArrayStorage}) = arraytype
3-
41
# Generic AbstractArray code
52
function contract(
63
array1::MatrixOrArrayStorage,
@@ -43,26 +40,21 @@ function contraction_output(
4340
end
4441

4542
# Required interface for specific AbstractArray types
43+
# TODO: Define `default_α` and `default_β`.
44+
# TODO: Define this as a `ttgt` or `matricize` backend.
4645
function contract!(
47-
arrayR::MatrixOrArrayStorage,
48-
labelsR,
46+
array_dest::MatrixOrArrayStorage,
47+
labels_dest,
4948
array1::MatrixOrArrayStorage,
5049
labels1,
5150
array2::MatrixOrArrayStorage,
5251
labels2,
52+
α=one(eltype(array_dest)),
53+
β=zero(eltype(array_dest));
5354
)
54-
props = ContractionProperties(labels1, labels2, labelsR)
55-
compute_contraction_properties!(props, array1, array2, arrayR)
55+
props = ContractionProperties(labels1, labels2, labels_dest)
56+
compute_contraction_properties!(props, array1, array2, array_dest)
5657
# TODO: Change this to just `contract!`, or maybe `contract_ttgt!`?
57-
_contract!(arrayR, array1, array2, props)
58-
return arrayR
59-
end
60-
61-
function permutedims!(
62-
output_array::MatrixOrArrayStorage, array::MatrixOrArrayStorage, perm, f::Function
63-
)
64-
output_array = permutedims!!(
65-
leaf_parenttype(output_array), output_array, leaf_parenttype(array), array, perm, f
66-
)
67-
return output_array
58+
_contract!(array_dest, array1, array2, props, α, β)
59+
return array_dest
6860
end
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
function permutedims!(
2+
output_array::MatrixOrArrayStorage, array::MatrixOrArrayStorage, perm, f::Function
3+
)
4+
output_array = permutedims!!(
5+
leaf_parenttype(output_array), output_array, leaf_parenttype(array), array, perm, f
6+
)
7+
return output_array
8+
end
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const ArrayStorageTensor{T,N,S,I} = Tensor{T,N,S,I} where {S<:ArrayStorage{T,N}}
2+
const MatrixStorageTensor{T,S,I} = Tensor{T,2,S,I} where {S<:MatrixStorage{T}}
3+
const MatrixOrArrayStorageTensor{T,S,I} =
4+
Tensor{T,N,S,I} where {N,S<:MatrixOrArrayStorage{T}}
5+
6+
function Tensor(storage::MatrixOrArrayStorageTensor, inds::Tuple)
7+
return Tensor(NeverAlias(), storage, inds)
8+
end
9+
10+
function Tensor(as::AliasStyle, storage::MatrixOrArrayStorage, inds::Tuple)
11+
return Tensor{eltype(storage),length(inds),typeof(storage),typeof(inds)}(
12+
as, storage, inds
13+
)
14+
end
15+
16+
array(tensor::MatrixOrArrayStorageTensor) = storage(tensor)
17+
18+
# Linear algebra (matrix algebra)
19+
# TODO: Remove `Base.`? Is it imported?
20+
function Base.adjoint(tens::MatrixStorageTensor)
21+
return tensor(adjoint(storage(tens)), reverse(inds(tens)))
22+
end
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# TODO: Just call `contraction_output(storage(tensor1), storage(tensor2), indsR)`
2+
function contraction_output(
3+
tensor1::MatrixOrArrayStorageTensor, tensor2::MatrixOrArrayStorageTensor, indsR
4+
)
5+
tensortypeR = contraction_output_type(typeof(tensor1), typeof(tensor2), indsR)
6+
return NDTensors.similar(tensortypeR, indsR)
7+
end
8+
9+
# TODO: Define `default_α` and `default_β`.
10+
function contract!(
11+
tensor_dest::MatrixOrArrayStorageTensor,
12+
labels_dest,
13+
tensor1::MatrixOrArrayStorageTensor,
14+
labels1,
15+
tensor2::MatrixOrArrayStorageTensor,
16+
labels2,
17+
α=one(eltype(tensor_dest)),
18+
β=zero(eltype(tensor_dest));
19+
)
20+
contract!(
21+
storage(tensor_dest),
22+
labels_dest,
23+
storage(tensor1),
24+
labels1,
25+
storage(tensor2),
26+
labels2,
27+
α,
28+
β,
29+
)
30+
return tensor_dest
31+
end
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# TODO: Rewrite this function to be more modern:
2+
# 1. List keyword arguments in function signature.
3+
# 2. Output `Spectrum` as a keyword argument that gets overwritten.
4+
# 3. Make this into two layers, one that handles indices and one that works with `AbstractMatrix`.
5+
function eigen(
6+
T::Hermitian{<:Any,<:ArrayStorageTensor};
7+
maxdim=nothing,
8+
mindim=1,
9+
cutoff=nothing,
10+
use_absolute_cutoff=false,
11+
use_relative_cutoff=true,
12+
# These are getting passed erroneously.
13+
# TODO: Make sure they don't get passed down
14+
# to here.
15+
which_decomp=nothing,
16+
tags=nothing,
17+
eigen_perturbation=nothing,
18+
normalize=nothing,
19+
ishermitian=nothing,
20+
ortho=nothing,
21+
svd_alg=nothing,
22+
)
23+
truncate = !isnothing(maxdim) || !isnothing(cutoff)
24+
# TODO: Define `default_maxdim(T)`.
25+
maxdim = isnothing(maxdim) ? minimum(dims(T)) : maxdim
26+
# TODO: Define `default_cutoff(T)`.
27+
cutoff = isnothing(cutoff) ? zero(eltype(T)) : cutoff
28+
29+
matrixT = matrix(T)
30+
## TODO Here I am calling parent to ensure that the correct `any` function
31+
## is envoked for non-cpu matrices
32+
if any(!isfinite, parent(matrixT))
33+
throw(
34+
ArgumentError(
35+
"Trying to perform the eigendecomposition of a matrix containing NaNs or Infs"
36+
),
37+
)
38+
end
39+
40+
DM, VM = eigen(matrixT)
41+
42+
# Sort by largest to smallest eigenvalues
43+
# TODO: Replace `cpu` with `leaf_parenttype` dispatch.
44+
p = sortperm(cpu(DM); rev=true, by=abs)
45+
DM = DM[p]
46+
VM = VM[:, p]
47+
48+
if truncate
49+
DM, truncerr, _ = truncate!!(
50+
DM; mindim, maxdim, cutoff, use_absolute_cutoff, use_relative_cutoff
51+
)
52+
dD = length(DM)
53+
if dD < size(VM, 2)
54+
VM = VM[:, 1:dD]
55+
end
56+
else
57+
dD = length(DM)
58+
truncerr = 0.0
59+
end
60+
spec = Spectrum(DM, truncerr)
61+
62+
# Make the new indices to go onto V
63+
# TODO: Put in a separate function, such as
64+
# `rewrap_inds` or something like that.
65+
indstype = typeof(inds(T))
66+
l = eltype(indstype)(dD)
67+
r = eltype(indstype)(dD)
68+
Vinds = indstype((dag(ind(T, 2)), dag(r)))
69+
Dinds = indstype((l, dag(r)))
70+
V = tensor(VM, Vinds)
71+
# TODO: Replace with `DiagonalArray`.
72+
D = tensor(Diag(DM), Dinds)
73+
return D, V, spec
74+
end
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
function getindex(tensor::MatrixOrArrayStorageTensor, I::Integer...)
2+
return storage(tensor)[I...]
3+
end
4+
5+
function setindex!(tensor::MatrixOrArrayStorageTensor, v, I::Integer...)
6+
storage(tensor)[I...] = v
7+
return tensor
8+
end
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
function LinearAlgebra.mul!(
2+
C::MatrixStorageTensor, A::MatrixStorageTensor, B::MatrixStorageTensor
3+
)
4+
mul!(storage(C), storage(A), storage(B))
5+
return C
6+
end
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
function permutedims!(
2+
output_tensor::MatrixOrArrayStorageTensor,
3+
tensor::MatrixOrArrayStorageTensor,
4+
perm,
5+
f::Function,
6+
)
7+
permutedims!(storage(output_tensor), storage(tensor), perm, f)
8+
return output_tensor
9+
end
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
function qr(A::ArrayStorageTensor)
2+
Q, R = qr(storage(A))
3+
Q = convert(typeof(R), Q)
4+
i, j = inds(A)
5+
q = size(A, 1) < size(A, 2) ? i : j
6+
q = sim(q)
7+
Qₜ = tensor(Q, (i, q))
8+
Rₜ = tensor(R, (dag(q), j))
9+
return Qₜ, Rₜ
10+
end

0 commit comments

Comments
 (0)