Skip to content
Closed
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
104 changes: 91 additions & 13 deletions src/states/abstractmps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -153,17 +153,6 @@ function makefullrank!(virtualspaces::PeriodicVector{S}, physicalspaces::Periodi
return virtualspaces
end

# Tensor accessors
# ----------------
@doc """
AC2(ψ::AbstractMPS, i; kind=:ACAR)

Obtain the two-site (center) gauge tensor at site `i` of the MPS `ψ`.
If this hasn't been computed before, this can be computed as:
- `kind=:ACAR` : AC[i] * AR[i+1]
- `kind=:ALAC` : AL[i] * AC[i+1]
""" AC2

#===========================================================================================
MPS types
===========================================================================================#
Expand Down Expand Up @@ -202,7 +191,7 @@ TensorKit.sectortype(ψtype::Type{<:AbstractMPS}) = sectortype(site_type(ψtype)

"""
left_virtualspace(ψ::AbstractMPS, [pos=1:length(ψ)])

Return the virtual space of the bond to the left of sites `pos`.

!!! warning
Expand Down Expand Up @@ -245,4 +234,93 @@ physicalspace(ψ::AbstractMPS) = map(Base.Fix1(physicalspace, ψ), eachsite(ψ))

Return an iterator over the sites of the MPS `state`.
"""
eachsite(ψ::AbstractMPS) = eachindex(ψ)
eachsite(ψ::AbstractMPS) = eachsite(GeometryStyle(ψ), ψ)

eachsite(::GeometryStyle, ψ::AbstractMPS) = eachindex(ψ)
Comment on lines +237 to +239
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a benefit to having this go through the geometrystyle? It looks like we end up with the same fallback anyways, so I don't really see the point here


# Tensor accessors
# ----------------
@doc """
AC2(ψ::AbstractMPS, i; kind=:ACAR)

Obtain the two-site (center) gauge tensor at site `i` of the MPS `ψ`.
If this hasn't been computed before, this can be computed as:
- `kind=:ACAR` : AC[i] * AR[i+1]
- `kind=:ALAC` : AL[i] * AC[i+1]
""" AC2

AC2(psi::AbstractMPS, site::Integer; kwargs...) = AC2(GeometryStyle(psi), psi, site; kwargs...)

#===========================================================================================
TensorKit utility
===========================================================================================#

function TensorKit.dot(ψ₁::AbstractMPS, ψ₂::AbstractMPS; kwargs...)
return TensorKit.dot(GeometryStyle(ψ₁, ψ₂), ψ₁, ψ₂; kwargs...)
end
function Base.isapprox(ψ₁::AbstractMPS, ψ₂::AbstractMPS; kwargs...)
return isapprox(dot(ψ₁, ψ₂), 1; kwargs...)
end
TensorKit.norm(ψ::AbstractMPS) = TensorKit.norm(GeometryStyle(ψ), ψ)
TensorKit.normalize!(ψ::AbstractMPS) = TensorKit.normalize!(GeometryStyle(ψ), ψ)
TensorKit.normalize(ψ::AbstractMPS) = normalize!(copy(ψ))

#===========================================================================================
Fixedpoints
===========================================================================================#

"""
l_RR(ψ, location)

Left dominant eigenvector of the `AR`-`AR` transfermatrix.
"""
l_RR(ψ::AbstractMPS, loc::Int = 1) = l_RR(GeometryStyle(ψ), ψ, loc)

"""
l_RL(ψ, location)

Left dominant eigenvector of the `AR`-`AL` transfermatrix.
"""
l_RL(ψ::AbstractMPS, loc::Int = 1) = l_RL(GeometryStyle(ψ), ψ, loc)

"""
l_LR(ψ, location)

Left dominant eigenvector of the `AL`-`AR` transfermatrix.
"""
l_LR(ψ::AbstractMPS, loc::Int = 1) = l_LR(GeometryStyle(ψ), ψ, loc)

"""
l_LL(ψ, location)

Left dominant eigenvector of the `AL`-`AL` transfermatrix.
"""
l_LL(ψ::AbstractMPS, loc::Int = 1) = l_LL(GeometryStyle(ψ), ψ, loc)

"""
r_RR(ψ, location)

Right dominant eigenvector of the `AR`-`AR` transfermatrix.
"""
r_RR(ψ::AbstractMPS, loc::Int = length(ψ)) = r_RR(GeometryStyle(ψ), ψ, loc)

"""
r_RL(ψ, location)

Right dominant eigenvector of the `AR`-`AL` transfermatrix.
"""
r_RL(ψ::AbstractMPS, loc::Int = length(ψ)) = r_RL(GeometryStyle(ψ), ψ, loc)

"""
r_LR(ψ, location)

Right dominant eigenvector of the `AL`-`AR` transfermatrix.
"""
r_LR(ψ::AbstractMPS, loc::Int = length(ψ)) = r_LR(GeometryStyle(ψ), ψ, loc)

"""
r_LL(ψ, location)

Right dominant eigenvector of the `AL`-`AL` transfermatrix.
"""
r_LL(ψ::AbstractMPS, loc::Int = length(ψ)) = r_LL(GeometryStyle(ψ), ψ, loc)
13 changes: 6 additions & 7 deletions src/states/finitemps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ Base.@propagate_inbounds function Base.getindex(ψ::FiniteMPS, i::Int)
end

# TODO: check where gauge center is to determine efficient kind
AC2(psi::FiniteMPS, site::Int) = psi.AC[site] * _transpose_tail(psi.AR[site + 1])
AC2(::FiniteChainStyle, psi::AbstractMPS, site::Integer) = psi.AC[site] * _transpose_tail(psi.AR[site + 1])

_complex_if_not_missing(x) = ismissing(x) ? x : complex(x)
function Base.complex(mps::FiniteMPS)
Expand Down Expand Up @@ -541,33 +541,32 @@ function TensorKit.rmul!(ψ::FiniteMPS, a::Number)
return ψ
end

function TensorKit.dot(ψ₁::FiniteMPS, ψ₂::FiniteMPS)
function TensorKit.dot(::FiniteChainStyle, ψ₁::AbstractMPS, ψ₂::AbstractMPS)
#todo : rewrite this without having to gauge
length(ψ₁) == length(ψ₂) || throw(ArgumentError("MPS with different length"))
ρr = TransferMatrix(ψ₂.AR[2:end], ψ₁.AR[2:end]) * r_RR(ψ₂)
return tr(_transpose_front(ψ₁.AC[1])' * _transpose_front(ψ₂.AC[1]) * ρr)
end

function TensorKit.norm(ψ::FiniteMPS)
function TensorKit.norm(::FiniteChainStyle, ψ::AbstractMPS)
c = ψ.center
if isinteger(c) # center is an AC
return norm(ψ.AC[Int(c)])
else # center is a bond-tensor
return norm(ψ.C[Int(c - 1 / 2)])
end
end
TensorKit.normalize!(ψ::FiniteMPS) = rmul!(ψ, 1 / norm(ψ))
TensorKit.normalize(ψ::FiniteMPS) = normalize!(copy(ψ))
TensorKit.normalize!(::FiniteChainStyle, ψ::AbstractMPS) = rmul!(ψ, 1 / norm(ψ))

#===========================================================================================
Fixedpoints
===========================================================================================#

function r_RR(ψ::FiniteMPS, site::Int = length(ψ))
function r_RR(::FiniteChainStyle, ψ::AbstractMPS, site::Int = length(ψ))
Vr = right_virtualspace(ψ.AR[site])
return isomorphism(storagetype(site_type(ψ)), Vr ← Vr)
end
function l_LL(ψ::FiniteMPS, site::Int = 1)
function l_LL(::FiniteChainStyle, ψ::AbstractMPS, site::Int = 1)
Vl = left_virtualspace(ψ.AL[site])
return isomorphism(storagetype(site_type(ψ)), Vl ← Vl)
end
79 changes: 15 additions & 64 deletions src/states/infinitemps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ end
Utility
===========================================================================================#

function AC2(ψ::InfiniteMPS, i::Integer; kind = :ACAR)
function AC2(::InfiniteChainStyle, ψ::AbstractMPS, i::Integer; kind = :ACAR)
if kind == :ACAR
return ψ.AC[i] * _transpose_tail(ψ.AR[i + 1])
elseif kind == :ALAC
Expand Down Expand Up @@ -276,7 +276,7 @@ end

Base.eachindex(ψ::InfiniteMPS) = eachindex(ψ.AL)
Base.eachindex(l::IndexStyle, ψ::InfiniteMPS) = eachindex(l, ψ.AL)
eachsite(ψ::InfiniteMPS) = PeriodicArray(eachindex(ψ))
eachsite(::InfiniteChainStyle, ψ::AbstractMPS) = PeriodicArray(eachindex(ψ))

Base.checkbounds(::Type{Bool}, ψ::InfiniteMPS, i::Integer) = true

Expand All @@ -294,87 +294,38 @@ physicalspace(ψ::InfiniteMPS, n::Integer) = physicalspace(ψ.AL[n])
# return ProductSpace{S}(space.(Ref(t), Base.front(Base.tail(TensorKit.allind(t)))))
# end

TensorKit.norm(ψ::InfiniteMPS) = norm(ψ.AC[1])
function TensorKit.normalize!(ψ::InfiniteMPS)
TensorKit.norm(::InfiniteChainStyle, ψ::AbstractMPS) = norm(ψ.AC[1])
function TensorKit.normalize!(::InfiniteChainStyle, ψ::AbstractMPS)
normalize!.(ψ.C)
normalize!.(ψ.AC)
return ψ
end

function TensorKit.dot(ψ₁::InfiniteMPS, ψ₂::InfiniteMPS; krylovdim = 30)
function TensorKit.dot(::InfiniteChainStyle, ψ₁::AbstractMPS, ψ₂::AbstractMPS; krylovdim = 30)
init = similar(ψ₁.AL[1], _firstspace(ψ₂.AL[1]) ← _firstspace(ψ₁.AL[1]))
randomize!(init)
val, = fixedpoint(
TransferMatrix(ψ₂.AL, ψ₁.AL), init, :LM, Arnoldi(; krylovdim = krylovdim)
)
return val
end
function Base.isapprox(ψ₁::InfiniteMPS, ψ₂::InfiniteMPS; kwargs...)
return isapprox(dot(ψ₁, ψ₂), 1; kwargs...)
end

#===========================================================================================
Fixedpoints
===========================================================================================#

"""
l_RR(ψ, location)

Left dominant eigenvector of the `AR`-`AR` transfermatrix.
"""
l_RR(ψ::InfiniteMPS, loc::Int = 1) = adjoint(ψ.C[loc - 1]) * ψ.C[loc - 1]

"""
l_RL(ψ, location)

Left dominant eigenvector of the `AR`-`AL` transfermatrix.
"""
l_RL(ψ::InfiniteMPS, loc::Int = 1) = ψ.C[loc - 1]

"""
l_LR(ψ, location)

Left dominant eigenvector of the `AL`-`AR` transfermatrix.
"""
l_LR(ψ::InfiniteMPS, loc::Int = 1) = ψ.C[loc - 1]'

"""
l_LL(ψ, location)

Left dominant eigenvector of the `AL`-`AL` transfermatrix.
"""
function l_LL(ψ::InfiniteMPS{A}, loc::Int = 1) where {A}
return isomorphism(storagetype(A), left_virtualspace(ψ, loc), left_virtualspace(ψ, loc))
l_RR(::InfiniteChainStyle, ψ::AbstractMPS, loc::Int = 1) = adjoint(ψ.C[loc - 1]) * ψ.C[loc - 1]
l_RL(::InfiniteChainStyle, ψ::AbstractMPS, loc::Int = 1) = ψ.C[loc - 1]
l_LR(::InfiniteChainStyle, ψ::AbstractMPS, loc::Int = 1) = ψ.C[loc - 1]'
function l_LL(::InfiniteChainStyle, ψ::AbstractMPS, loc::Int = 1)
return isomorphism(storagetype(eltype(ψ)), left_virtualspace(ψ, loc), left_virtualspace(ψ, loc))
end

"""
r_RR(ψ, location)

Right dominant eigenvector of the `AR`-`AR` transfermatrix.
"""
function r_RR(ψ::InfiniteMPS{A}, loc::Int = length(ψ)) where {A}
function r_RR(::InfiniteChainStyle, ψ::AbstractMPS, loc::Int = length(ψ))
return isomorphism(
storagetype(A), right_virtualspace(ψ, loc), right_virtualspace(ψ, loc)
storagetype(eltype(ψ)), right_virtualspace(ψ, loc), right_virtualspace(ψ, loc)
)
end

"""
r_RL(ψ, location)

Right dominant eigenvector of the `AR`-`AL` transfermatrix.
"""
r_RL(ψ::InfiniteMPS, loc::Int = length(ψ)) = ψ.C[loc]'

"""
r_LR(ψ, location)

Right dominant eigenvector of the `AL`-`AR` transfermatrix.
"""
r_LR(ψ::InfiniteMPS, loc::Int = length(ψ)) = ψ.C[loc]

"""
r_LL(ψ, location)

Right dominant eigenvector of the `AL`-`AL` transfermatrix.
"""
r_LL(ψ::InfiniteMPS, loc::Int = length(ψ)) = ψ.C[loc] * adjoint(ψ.C[loc])
r_RL(::InfiniteChainStyle, ψ::AbstractMPS, loc::Int = length(ψ)) = ψ.C[loc]'
r_LR(::InfiniteChainStyle, ψ::AbstractMPS, loc::Int = length(ψ)) = ψ.C[loc]
r_LL(::InfiniteChainStyle, ψ::AbstractMPS, loc::Int = length(ψ)) = ψ.C[loc] * adjoint(ψ.C[loc])
15 changes: 15 additions & 0 deletions test/states.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module TestStates
using MPSKit: _transpose_front, _transpose_tail
using MPSKit: GeometryStyle, FiniteChainStyle, InfiniteChainStyle
using MPSKit: TransferMatrix
using MPSKit: AC2
using TensorKit
using TensorKit: ℙ

Expand Down Expand Up @@ -120,6 +121,9 @@ module TestStates
@test all(x -> x ≾ D, left_virtualspace(ψ))
@test all(x -> x ≾ D, right_virtualspace(ψ))

normalize!(ψ)
@test norm(ψ) ≈ norm(InfiniteChainStyle(), ψ) ≈ 1.0

for i in 1:length(ψ)
@plansor difference[-1 -2; -3] := ψ.AL[i][-1 -2; 1] * ψ.C[i][1; -3] -
ψ.C[i - 1][-1; 1] * ψ.AR[i][1 -2; -3]
Expand All @@ -134,6 +138,17 @@ module TestStates
@test TransferMatrix(ψ.AL[i], ψ.AR[i]) * r_LR(ψ, i) ≈ r_LR(ψ, i + 1)
@test TransferMatrix(ψ.AR[i], ψ.AL[i]) * r_RL(ψ, i) ≈ r_RL(ψ, i + 1)
@test TransferMatrix(ψ.AR[i], ψ.AR[i]) * r_RR(ψ, i) ≈ r_RR(ψ, i + 1)

@test l_LL(ψ, i) ≈ l_LL(InfiniteChainStyle(), ψ, i)
@test l_LR(ψ, i) ≈ l_LR(InfiniteChainStyle(), ψ, i)
@test l_RL(ψ, i) ≈ l_RL(InfiniteChainStyle(), ψ, i)
@test l_RR(ψ, i) ≈ l_RR(InfiniteChainStyle(), ψ, i)
@test r_LL(ψ, i) ≈ r_LL(InfiniteChainStyle(), ψ, i)
@test r_LR(ψ, i) ≈ r_LR(InfiniteChainStyle(), ψ, i)
@test r_RL(ψ, i) ≈ r_RL(InfiniteChainStyle(), ψ, i)
@test r_RR(ψ, i) ≈ r_RR(InfiniteChainStyle(), ψ, i)

@test @constinferred AC2(ψ, i) ≈ AC2(InfiniteChainStyle(), ψ, i)
end
end

Expand Down