11"""
2- struct MPO{O<:MPOTensor ,V<:AbstractVector{O}} <: AbstractMPO{O}
2+ struct MPO{O,V<:AbstractVector{O}} <: AbstractMPO{O}
33
44Matrix Product Operator (MPO) acting on a tensor product space with a linear order.
55
66See also: [`FiniteMPO`](@ref), [`InfiniteMPO`](@ref)
77"""
8- struct MPO{TO<: MPOTensor ,V<: AbstractVector{TO} } <: AbstractMPO{TO}
8+ struct MPO{TO,V<: AbstractVector{TO} } <: AbstractMPO{TO}
99 O:: V
1010end
1111
1212"""
13- FiniteMPO(Os::Vector{<:MPOTensor }) -> FiniteMPO
14- FiniteMPO(O::AbstractTensorMap{S,N,N}) where {S,N} -> FiniteMPO
13+ FiniteMPO(Os::Vector{O }) -> FiniteMPO{O}
14+ FiniteMPO(O::AbstractTensorMap{S,N,N}) where {S,N} -> FiniteMPO{O<:MPOTensor}
1515
1616Matrix Product Operator (MPO) acting on a finite tensor product space with a linear order.
1717"""
18- const FiniteMPO{O<: MPOTensor } = MPO{O,Vector{O}}
18+ const FiniteMPO{O} = MPO{O,Vector{O}}
1919Base. isfinite (:: Type{<:FiniteMPO} ) = true
2020
21- function FiniteMPO (Os:: AbstractVector{O} ) where {O<: MPOTensor }
21+ function FiniteMPO (Os:: AbstractVector{O} ) where {O}
2222 for i in eachindex (Os)[1 : (end - 1 )]
2323 right_virtualspace (Os[i]) == left_virtualspace (Os[i + 1 ]) ||
2424 throw (SpaceMismatch (" unmatching virtual spaces at site $i " ))
@@ -31,14 +31,14 @@ function FiniteMPO(O::AbstractTensorMap{T,S,N,N}) where {T,S,N}
3131end
3232
3333"""
34- InfiniteMPO(Os::PeriodicVector{<:MPOTensor }) -> InfiniteMPO
34+ InfiniteMPO(Os::PeriodicVector{O }) -> InfiniteMPO{O}
3535
3636Matrix Product Operator (MPO) acting on an infinite tensor product space with a linear order.
3737"""
38- const InfiniteMPO{O<: MPOTensor } = MPO{O,PeriodicVector{O}}
38+ const InfiniteMPO{O} = MPO{O,PeriodicVector{O}}
3939Base. isfinite (:: Type{<:InfiniteMPO} ) = false
4040
41- function InfiniteMPO (Os:: AbstractVector{O} ) where {O<: MPOTensor }
41+ function InfiniteMPO (Os:: AbstractVector{O} ) where {O}
4242 for i in eachindex (Os)
4343 right_virtualspace (Os[i]) == left_virtualspace (Os[mod1 (i + 1 , end )]) ||
4444 throw (SpaceMismatch (" umatching virtual spaces at site $i " ))
@@ -55,7 +55,7 @@ DenseMPO(mpo::MPO) = mpo isa DenseMPO ? copy(mpo) : MPO(map(TensorMap, parent(mp
5555Base. parent (mpo:: MPO ) = mpo. O
5656Base. copy (mpo:: MPO ) = MPO (map (copy, mpo))
5757
58- function Base. similar (mpo:: MPO , :: Type{O} , L:: Int ) where {O<: MPOTensor }
58+ function Base. similar (mpo:: MPO , :: Type{O} , L:: Int ) where {O}
5959 return MPO (similar (parent (mpo), O, L))
6060end
6161
@@ -95,7 +95,7 @@ function _mps_to_mpo(A::GenericMPSTensor{S,3}) where {S}
9595 return O
9696end
9797
98- function Base. convert (:: Type{TensorMap} , mpo:: FiniteMPO )
98+ function Base. convert (:: Type{TensorMap} , mpo:: FiniteMPO{<:MPOTensor} )
9999 N = length (mpo)
100100 # add trivial tensors to remove left and right trivial leg.
101101 V_left = left_virtualspace (mpo, 1 )
120120# VectorInterface.scalartype(::Type{FiniteMPO{O}}) where {O} = scalartype(O)
121121
122122Base.:+ (mpo:: MPO ) = MPO (map (+ , parent (mpo)))
123- function Base.:+ (mpo1:: FiniteMPO{TO} , mpo2:: FiniteMPO{TO} ) where {TO}
123+ function Base.:+ (mpo1:: FiniteMPO{TO} , mpo2:: FiniteMPO{TO} ) where {TO<: MPOTensor }
124124 (N = length (mpo1)) == length (mpo2) || throw (ArgumentError (" dimension mismatch" ))
125125 @assert left_virtualspace (mpo1, 1 ) == left_virtualspace (mpo2, 1 ) &&
126126 right_virtualspace (mpo1, N) == right_virtualspace (mpo2, N)
@@ -207,7 +207,8 @@ function VectorInterface.scale!(mpo::MPO, α::Number)
207207 return mpo
208208end
209209
210- function Base.:* (mpo1:: FiniteMPO{TO} , mpo2:: FiniteMPO{TO} ) where {TO}
210+ # TODO : merge implementation with that of InfiniteMPO
211+ function Base.:* (mpo1:: FiniteMPO{TO} , mpo2:: FiniteMPO{TO} ) where {TO<: MPOTensor }
211212 (N = length (mpo1)) == length (mpo2) || throw (ArgumentError (" dimension mismatch" ))
212213 S = spacetype (TO)
213214 if (left_virtualspace (mpo1, 1 ) != oneunit (S) ||
@@ -273,29 +274,16 @@ function _fuse_mpo_mps(O::MPOTensor, A::MPSTensor, Fₗ, Fᵣ)
273274end
274275
275276function Base.:* (mpo1:: InfiniteMPO , mpo2:: InfiniteMPO )
276- L = check_length (mpo1, mpo2)
277-
278- T = promote_type (scalartype (mpo1), scalartype (mpo2))
279- make_fuser (i) = fuser (T, left_virtualspace (mpo2, i), left_virtualspace (mpo1, i))
280- fusers = PeriodicArray (map (make_fuser, 1 : L))
281-
282- Os = map (1 : L) do i
283- return _fuse_mpo_mpo (mpo1[i], mpo2[i], fusers[i], fusers[i + 1 ])
284- end
277+ check_length (mpo1, mpo2)
278+ Os = map (fuse_mul_mpo, parent (mpo1), parent (mpo2))
285279 return InfiniteMPO (Os)
286280end
287281
288- function _fuse_mpo_mpo (O1:: MPOTensor , O2:: MPOTensor , Fₗ, Fᵣ)
289- return @plansor O′[- 1 - 2 ; - 3 - 4 ] := Fₗ[- 1 ; 1 4 ] *
290- O2[1 2 ; - 3 3 ] *
291- O1[4 - 2 ; 2 5 ] *
292- conj (Fᵣ[- 4 ; 3 5 ])
293- end
294-
295282# TODO : I think the fastest order is to start from both ends, and take the overlap at the
296283# largest virtual space cut, but it might be better to just multithread both sides and meet
297284# in the middle
298- function TensorKit. dot (bra:: FiniteMPS{T} , mpo:: FiniteMPO , ket:: FiniteMPS{T} ) where {T}
285+ function TensorKit. dot (bra:: FiniteMPS{T} , mpo:: FiniteMPO{<:MPOTensor} ,
286+ ket:: FiniteMPS{T} ) where {T}
299287 (N = length (bra)) == length (mpo) == length (ket) ||
300288 throw (ArgumentError (" dimension mismatch" ))
301289 Nhalf = N ÷ 2
@@ -320,17 +308,15 @@ function TensorKit.dot(bra::FiniteMPS{T}, mpo::FiniteMPO, ket::FiniteMPS{T}) whe
320308end
321309function TensorKit. dot (bra:: InfiniteMPS , mpo:: InfiniteMPO , ket:: InfiniteMPS ;
322310 ishermitian= false , krylovdim= 30 , kwargs... )
323- ρ₀ = similar (bra. AL[1 ],
324- left_virtualspace (ket, 1 ) * left_virtualspace (mpo, 1 ) ←
325- left_virtualspace (bra, 1 ))
311+ ρ₀ = allocate_GL (bra, mpo, ket, 1 )
326312 randomize! (ρ₀)
327313
328314 val, = fixedpoint (TransferMatrix (ket. AL, parent (mpo), bra. AL), ρ₀, :LM ; ishermitian,
329315 krylovdim, kwargs... )
330316 return val
331317end
332318
333- function TensorKit. dot (mpo₁:: FiniteMPO , mpo₂:: FiniteMPO )
319+ function TensorKit. dot (mpo₁:: FiniteMPO{TO} , mpo₂:: FiniteMPO{TO} ) where {TO <: MPOTensor }
334320 length (mpo₁) == length (mpo₂) || throw (ArgumentError (" dimension mismatch" ))
335321 N = length (mpo₁)
336322 Nhalf = N ÷ 2
0 commit comments