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
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "ITensorInfiniteMPS"
uuid = "1dc1fb26-a137-4954-ae60-1bd4106e95ad"
authors = ["Matthew Fishman <[email protected]> and contributors"]
version = "0.2.0"
version = "0.2.1"

[deps]
Compat = "34da2185-b29b-5c13-b0c7-acf172513d20"
Expand Down
1 change: 1 addition & 0 deletions examples/vumps/vumps_hubbard_extended.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ subspace_expansion_kwargs = (cutoff=cutoff, maxdim=maxdim)

println("\nRun VUMPS on initial product state, unit cell size $N")
ψ = vumps_subspace_expansion(H, ψ; outer_iters, subspace_expansion_kwargs, vumps_kwargs)
ψ = orthogonalize(ψ.AL, :; tol=1e-14) # ensure translation invariance

# Check translational invariance
println("\nCheck translational invariance of optimized infinite MPS")
Expand Down
28 changes: 22 additions & 6 deletions src/infinitecanonicalmps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -249,21 +249,37 @@ function InfMPS(s::CelledVector, f::Function)
return ψ = InfiniteCanonicalMPS(ψL, ψC, ψR)
end

function finite_mps(ψ::InfiniteCanonicalMPS, range::AbstractRange)
function finite_mps(
ψ::InfiniteCanonicalMPS,
range::AbstractRange;
ortho_lims::AbstractUnitRange=last(range):last(range),
)
@assert isone(step(range))
@assert first(ortho_lims) == last(ortho_lims) # TODO: variable ortho_lims
@assert first(ortho_lims) ∈ range

N = length(range)
ψ_finite = ψ.AL[range]
ψ_finite[N] *= ψ.C[last(range)]
ψ_finite = Vector{ITensor}(undef, N)
for i in first(range):first(ortho_lims)
ψ_finite[i] = ψ.AL[i]
end
ψ_finite[first(ortho_lims)] *= ψ.C[first(ortho_lims)]

for i in (last(ortho_lims) + 1):last(range)
ψ_finite[i] = ψ.AR[i]
end

l0 = linkind(ψ.AL, first(range) - 1 => first(range))
l̃0 = sim(l0)
lN = linkind(ψ.AR, last(range) => last(range) + 1)
l̃0 = sim(l0)
l̃N = sim(lN)
δl0 = δ(dag(l̃0), l0)
δlN = δ(dag(l̃N), lN)
ψ_finite[1] *= δl0
ψ_finite[N] *= dag(δlN)
ψ_finite = MPS([dag(δl0); [ψ_finiteᵢ for ψ_finiteᵢ in ψ_finite]; δlN])
set_ortho_lims!(ψ_finite, (N + 1):(N + 1))
ψ_finite = MPS(
[dag(δl0); ψ_finite; δlN]; ortho_lims=(first(ortho_lims) + 1):(last(ortho_lims) + 1)
)
return ψ_finite
end
function ITensorMPS.expect(ψ::InfiniteCanonicalMPS, o::String, n::Int)
Expand Down
31 changes: 23 additions & 8 deletions src/orthogonalize.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
using KrylovKit: schursolve, Arnoldi
# TODO: call as `orthogonalize(ψ, -∞)`
# TODO: could use commontags(ψ) as a default for left_tags
function right_orthogonalize(
ψ::InfiniteMPS; left_tags=ts"Left", right_tags=ts"Right", tol::Real=1e-12
ψ::InfiniteMPS;
left_tags=ts"Left",
right_tags=ts"Right",
tol::Real=1e-12,
eager=true,
ishermitian_kwargs=(; rtol=tol * 100),
)
# A transfer matrix made from the 1st unit cell of the infinite MPS
T = TransferMatrix(ψ)
Expand All @@ -12,9 +18,20 @@ function right_orthogonalize(
# Start by getting the right eivenvector/eigenvalue of T
# TODO: make a function `right_environments(::InfiniteMPS)` that computes
# all of the right environments using `eigsolve` and shifting unit cells
λ⃗₁ᴿᴺ, v⃗₁ᴿᴺ, eigsolve_info = eigsolve(T, v₁ᴿᴺ, 1, :LM; tol=tol)

# original eigsolve function, switch to schur which enforces real
#λ⃗₁ᴿᴺ, v⃗₁ᴿᴺ, eigsolve_info = eigsolve(T, v₁ᴿᴺ, 1, :LM; tol, eager)
TT, v⃗₁ᴿᴺ, λ⃗₁ᴿᴺ, info = schursolve(T, v₁ᴿᴺ, 1, :LM, Arnoldi(; tol, eager))
λ₁ᴿᴺ, v₁ᴿᴺ = λ⃗₁ᴿᴺ[1], v⃗₁ᴿᴺ[1]

if info.converged == 0
@warn "orthogonalize not converged after $(info.numiter) iterations"
end

if size(TT, 2) > 1 && TT[2, 1] != 0
@warn("Non-unique largest eigenvector of transfer matrix found")
end

if imag(λ₁ᴿᴺ) / norm(λ₁ᴿᴺ) > 1e-15
@show λ₁ᴿᴺ
error(
Expand All @@ -24,11 +41,9 @@ function right_orthogonalize(

# Fix the phase of the diagonal to make Hermitian
v₁ᴿᴺ .*= conj(sign(v₁ᴿᴺ[1, 1]))
if !ishermitian(v₁ᴿᴺ; rtol=tol)
@show λ₁ᴿᴺ
@show v₁ᴿᴺ
if !ishermitian(v₁ᴿᴺ; ishermitian_kwargs...)
@show norm(v₁ᴿᴺ - swapinds(dag(v₁ᴿᴺ), reverse(Pair(inds(v₁ᴿᴺ)...))))
error("v₁ᴿᴺ not hermitian")
@warn("v₁ᴿᴺ is not hermitian, passed kwargs: $ishermitian_kwargs")
end
if norm(imag(v₁ᴿᴺ)) / norm(v₁ᴿᴺ) > 1e-13
println(
Expand Down Expand Up @@ -105,8 +120,8 @@ end
function mixed_canonical(
ψ::InfiniteMPS; left_tags=ts"Left", right_tags=ts"Right", tol::Real=1e-12
)
_, ψᴿ, _ = right_orthogonalize(ψ; left_tags=ts"", right_tags=ts"Right")
ψᴸ, C, λ = left_orthogonalize(ψᴿ; left_tags=ts"Left", right_tags=ts"Right")
_, ψᴿ, _ = right_orthogonalize(ψ; left_tags=ts"", right_tags)
ψᴸ, C, λ = left_orthogonalize(ψᴿ; left_tags, right_tags)
if λ ≉ one(λ)
error("λ should be approximately 1 after orthogonalization, instead it is $λ")
end
Expand Down
Loading