diff --git a/src/states/abstractmps.jl b/src/states/abstractmps.jl index 5c1e82c1d..b27763a7d 100644 --- a/src/states/abstractmps.jl +++ b/src/states/abstractmps.jl @@ -15,7 +15,7 @@ const MPSTensor{S} = GenericMPSTensor{S, 2} # the usual mps tensors on which we """ MPSTensor([f, eltype], d::Int, left_D::Int, [right_D]::Int]) - MPSTensor([f, eltype], physicalspace::Union{S,CompositeSpace{S}}, + MPSTensor([f, eltype], physicalspace::Union{S,CompositeSpace{S}}, left_virtualspace::S, [right_virtualspace]::S) where {S<:ElementarySpace} Construct an `MPSTensor` with given physical and virtual spaces. @@ -164,6 +164,8 @@ If this hasn't been computed before, this can be computed as: - `kind=:ALAC` : AL[i] * AC[i+1] """ AC2 +AC2(psi::AbstractMPS, site::Int; kwargs...) = AC2(GeometryStyle(psi), psi, site; kwargs...) + #=========================================================================================== MPS types ===========================================================================================# @@ -202,7 +204,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 @@ -245,4 +247,79 @@ 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(ψ) + +# TensorKit utility +# ----------------- + +function TensorKit.dot(ψ₁::AbstractMPS, ψ₂::AbstractMPS; kwargs...) + geometry_style = GeometryStyle(ψ₁) & GeometryStyle(ψ₂) + return TensorKit.dot(geometry_style, ψ₁, ψ₂; 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) diff --git a/src/utility/styles.jl b/src/utility/styles.jl index 104b4e562..962859019 100644 --- a/src/utility/styles.jl +++ b/src/utility/styles.jl @@ -10,6 +10,12 @@ Trait to describe the operator behavior of the input `x` or type `T`, which can abstract type OperatorStyle end OperatorStyle(x) = OperatorStyle(typeof(x)) OperatorStyle(T::Type) = throw(MethodError(OperatorStyle, T)) # avoid stackoverflow if not defined +OperatorStyle(x::OperatorStyle) = x + +OperatorStyle(x, y) = OperatorStyle(OperatorStyle(x)::OperatorStyle, OperatorStyle(y)::OperatorStyle) +OperatorStyle(::T, ::T) where {T <: OperatorStyle} = T() +OperatorStyle(x::OperatorStyle, y::OperatorStyle) = error("Unknown combination of operator styles $x and $y") +@inline OperatorStyle(x, y, zs...) = OperatorStyle(OperatorStyle(x, y), zs...) struct MPOStyle <: OperatorStyle end struct HamiltonianStyle <: OperatorStyle end @@ -29,6 +35,12 @@ Trait to describe the geometry of the input `x` or type `T`, which can be either abstract type GeometryStyle end GeometryStyle(x) = GeometryStyle(typeof(x)) GeometryStyle(T::Type) = throw(MethodError(GeometryStyle, T)) # avoid stackoverflow if not defined +GeometryStyle(x::GeometryStyle) = x + +GeometryStyle(x, y) = GeometryStyle(GeometryStyle(x)::GeometryStyle, GeometryStyle(y)::GeometryStyle) +GeometryStyle(::T, ::T) where {T <: GeometryStyle} = T() +GeometryStyle(x::GeometryStyle, y::GeometryStyle) = error("Unknown combination of geometry styles $x and $y") +@inline GeometryStyle(x, y, zs...) = GeometryStyle(GeometryStyle(x, y), zs...) struct FiniteChainStyle <: GeometryStyle end struct InfiniteChainStyle <: GeometryStyle end diff --git a/test/operators.jl b/test/operators.jl index b2390437d..f5dce96b5 100644 --- a/test/operators.jl +++ b/test/operators.jl @@ -71,6 +71,8 @@ module TestOperators mps₁ = FiniteMPS(ψ₁) mps₂ = FiniteMPS(ψ₂) + @test @constinferred GeometryStyle(mps₁, mpo₁, mps₁) == GeometryStyle(mps₁) + @test convert(TensorMap, mpo₁ * mps₁) ≈ O₁ * ψ₁ @test mpo₁ * ψ₁ ≈ O₁ * ψ₁ @test convert(TensorMap, mpo₃ * mps₁) ≈ O₃ * ψ₁ @@ -140,6 +142,7 @@ module TestOperators @test GeometryStyle(H) == FiniteChainStyle() @test OperatorStyle(typeof(H)) == HamiltonianStyle() @test OperatorStyle(H) == HamiltonianStyle() + @test OperatorStyle(H, H′) == OperatorStyle(H) # Infinite Ws = [Wmid] @@ -410,6 +413,8 @@ module TestOperators ψ = InfiniteMPS([pspace], [ou ⊕ pspace]) W = MPSKit.DenseMPO(make_time_mpo(ham, 1im * 0.5, WII())) + + @test GeometryStyle(ψ, W) == GeometryStyle(ψ) @test W * (W * ψ) ≈ (W * W) * ψ atol = 1.0e-2 # TODO: there is a normalization issue here end diff --git a/test/other.jl b/test/other.jl index 17b3138fe..2eb3443ca 100644 --- a/test/other.jl +++ b/test/other.jl @@ -112,6 +112,9 @@ module TestMiscellaneous @test OperatorStyle(MPO) == MPOStyle() @test OperatorStyle(InfiniteMPO) == MPOStyle() + @test OperatorStyle(HamiltonianStyle()) == HamiltonianStyle() + @test @constinferred OperatorStyle(MPO, InfiniteMPO, MPO) == MPOStyle() + @test_throws ErrorException OperatorStyle(MPO, HamiltonianStyle()) @test GeometryStyle(FiniteMPOHamiltonian) == FiniteChainStyle() @test GeometryStyle(InfiniteMPS) == InfiniteChainStyle() @@ -120,5 +123,11 @@ module TestMiscellaneous @test GeometryStyle(FiniteMPOHamiltonian) == FiniteChainStyle() @test GeometryStyle(InfiniteMPO) == InfiniteChainStyle() @test GeometryStyle(InfiniteMPOHamiltonian) == InfiniteChainStyle() + + @test GeometryStyle(GeometryStyle(FiniteMPS)) == GeometryStyle(FiniteMPS) + @test GeometryStyle(FiniteMPS, FiniteMPO) == FiniteChainStyle() + @test_throws ErrorException GeometryStyle(FiniteMPS, InfiniteMPO) + @test @constinferred GeometryStyle(InfiniteMPS, InfiniteMPO, InfiniteMPS) == InfiniteChainStyle() + @test_throws ErrorException GeometryStyle(FiniteMPS, FiniteMPO, InfiniteMPS) end end