Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/itensor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export ITensor,
combinedindex,
delta,
δ,
exp,
replaceindex!,
inds,
isNull,
Expand Down Expand Up @@ -424,6 +425,28 @@ end

dot(A::ITensor,B::ITensor) = scalar(dag(A)*B)

import LinearAlgebra.exp

"""
exp(A::ITensor, Lis::IndexSet; hermitian = false)
Compute the exponential of the tensor `A` by treating it as a matrix ``A_{lr}`` with
the left index `l` running over all indices in `Lis` and `r` running over all
indices not in `Lis`. Must have `dim(Lis) == dim(inds(A))/dim(Lis)` for the exponentiation to
be defined.
When `hermitian=true` the exponential of `Hermitian(reshape(A, dim(Lis), :))` is
computed internally.
"""
function exp(A::ITensor, Lis::IndexSet; hermitian = false)
(dim(Lis) == dim(inds(A))/dim(Lis)) || throw(DimensionMismatch("dimension of the left index set `Lis` must be
equal to `dim(inds(A))/dim(Lis)`"))
A, Lis, Ris = _permute_for_factorize(A,Lis)
expAs = storage_exp(store(A), Lis,Ris, hermitian = hermitian)
return ITensor(inds(A),expAs)
end


expHermitian(A::ITensor,Lis::IndexSet) = exp(A,Lis, hermitian=true)

#######################################################################
#
# In-place operations
Expand Down
5 changes: 5 additions & 0 deletions src/storage/dense.jl
Original file line number Diff line number Diff line change
Expand Up @@ -357,3 +357,8 @@ function storage_polar(Astore::Dense{T},
return (Qis,Qstore,Pis,Pstore)
end

function storage_exp(As::Dense{T}, Lis,Ris; hermitian=false) where {T}
expAdata = ( hermitian ? Array(exp(Hermitian(reshape(data(As),dim(Lis),dim(Ris))))) :
exp(reshape(data(As),dim(Lis),dim(Ris))) )
return Dense{T}(vec(expAdata))
end
35 changes: 35 additions & 0 deletions test/test_itensor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,41 @@ end
@test dot(A, B) == 11.0
end

@testset "exponentiate" begin
s1 = Index(2,"s1")
s2 = Index(2,"s2")
i1 = Index(2,"i1")
i2 = Index(2,"i2")
Amat = rand(2,2,2,2)
A = ITensor(Amat, i1,i2,s1,s2)

Aexp = exp(A,IndexSet(i1,i2))
Amatexp = reshape( exp(reshape(Amat,4,4)), 2,2,2,2)
Aexp_from_mat = ITensor(Amatexp, i1,i2,s1,s2)
@test Aexp ≈ Aexp_from_mat

#test that exponentiation works when indices need to be permuted
Aexp = exp(A,IndexSet(s1,s2))
Amatexp = Array( exp( reshape(Amat,4,4))' )
Aexp_from_mat = ITensor(reshape(Amatexp,2,2,2,2), s1,s2,i1,i2)
@test Aexp ≈ Aexp_from_mat

#test exponentiation when hermitian=true is used
Amat = reshape(Amat, 4,4)
Amat = reshape( Amat + Amat' + randn(4,4)*1e-10 , 2,2,2,2)
A = ITensor(Amat, i1,i2,s1,s2)
Aexp = exp(A,IndexSet(i1,i2), hermitian=true)
Amatexp = Array(reshape( exp(Hermitian(reshape(Amat,4,4))), 2,2,2,2))
Aexp_from_mat = ITensor(Amatexp, i1,i2,s1,s2)
@test Aexp ≈ Aexp_from_mat



@test_throws DimensionMismatch exp(A,IndexSet(s1))

end


@testset "add and axpy" begin
i = Index(2,"i")
a = [1.0; 2.0]
Expand Down