Skip to content
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: 21 additions & 7 deletions src/infinitecanonicalmps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -249,21 +249,35 @@ 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::String="right")
@assert isone(step(range))
N = length(range)
ψ_finite = ψ.AL[range]
ψ_finite[N] *= ψ.C[last(range)]
l0 = linkind(ψ.AL, first(range) - 1 => first(range))
if ortho == "right"
ψ_finite = ψ.AL[range]
ψ_finite[N] *= ψ.C[last(range)]
l0 = linkind(ψ.AL, first(range) - 1 => first(range))
lN = linkind(ψ.AR, last(range) => last(range) + 1)
center = N + 1
elseif ortho == "left"
ψ_finite = (ψ.AR[range])
# C gets applied to the left here
ψ_finite[1] *= (ψ.C[first(range) - 1])
l0 = linkind(ψ.AL, first(range) - 1 => first(range))
lN = linkind(ψ.AR, last(range) => last(range) + 1)
center = 2
else
error("Unknown ortho option $ortho. Please use left or right")
end

l̃0 = sim(l0)
lN = linkind(ψ.AR, last(range) => last(range) + 1)
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ᵢ for ψ_finiteᵢ in ψ_finite]; δlN]; ortho_lims=center:center
)
return ψ_finite
end
function ITensorMPS.expect(ψ::InfiniteCanonicalMPS, o::String, n::Int)
Expand Down
9 changes: 8 additions & 1 deletion src/orthogonalize.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using KrylovKit: schursolve, Arnoldi
# TODO: call as `orthogonalize(ψ, -∞)`
# TODO: could use commontags(ψ) as a default for left_tags
function right_orthogonalize(
Expand All @@ -12,9 +13,15 @@ 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=true)
TT, v⃗₁ᴿᴺ, λ⃗₁ᴿᴺ, eigsolve_info = schursolve(T, v₁ᴿᴺ, 1, :LM, Arnoldi(; tol))
λ₁ᴿᴺ, v₁ᴿᴺ = λ⃗₁ᴿᴺ[1], v⃗₁ᴿᴺ[1]

if size(TT, 2) > 1 && TT[2, 1] != 0
@warn("Largest transfer matrix eigenvector is not real?")
Copy link
Member

Choose a reason for hiding this comment

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

Seems a bit funny to make this a question. Can't you check if it is real?

Copy link
Member

Choose a reason for hiding this comment

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

If it isn't a definitive check, it would be better to phrase it as "Largest transfer matrix eigenvector might not be real.".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess it should be "Non-unique largest eigenvector" (or the eigenvector shouldn't be real)

Copy link

Choose a reason for hiding this comment

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

I think what it really means is that it is not unique, this results in complex conjugate eigenvalue pairs (hence checking the TT[2, 1], TT[1:2,1:2] = [real(lambda) imag(lambda); -imag(lambda) real(lambda)] or something like that).

end
if imag(λ₁ᴿᴺ) / norm(λ₁ᴿᴺ) > 1e-15
@show λ₁ᴿᴺ
error(
Expand Down
Loading