1+ using KrylovKit: schursolve, Arnoldi
12# TODO : call as `orthogonalize(ψ, -∞)`
23# TODO : could use commontags(ψ) as a default for left_tags
34function right_orthogonalize (
4- ψ:: InfiniteMPS ; left_tags= ts " Left" , right_tags= ts " Right" , tol:: Real = 1e-12
5+ ψ:: InfiniteMPS ;
6+ left_tags= ts " Left" ,
7+ right_tags= ts " Right" ,
8+ tol:: Real = 1e-12 ,
9+ eager= true ,
10+ ishermitian_kwargs= (; rtol= tol * 100 ),
511)
612 # A transfer matrix made from the 1st unit cell of the infinite MPS
713 T = TransferMatrix (ψ)
@@ -12,9 +18,20 @@ function right_orthogonalize(
1218 # Start by getting the right eivenvector/eigenvalue of T
1319 # TODO : make a function `right_environments(::InfiniteMPS)` that computes
1420 # all of the right environments using `eigsolve` and shifting unit cells
15- λ⃗₁ᴿᴺ, v⃗₁ᴿᴺ, eigsolve_info = eigsolve (T, v₁ᴿᴺ, 1 , :LM ; tol= tol)
21+
22+ # original eigsolve function, switch to schur which enforces real
23+ # λ⃗₁ᴿᴺ, v⃗₁ᴿᴺ, eigsolve_info = eigsolve(T, v₁ᴿᴺ, 1, :LM; tol, eager)
24+ TT, v⃗₁ᴿᴺ, λ⃗₁ᴿᴺ, info = schursolve (T, v₁ᴿᴺ, 1 , :LM , Arnoldi (; tol, eager))
1625 λ₁ᴿᴺ, v₁ᴿᴺ = λ⃗₁ᴿᴺ[1 ], v⃗₁ᴿᴺ[1 ]
1726
27+ if info. converged == 0
28+ @warn " orthogonalize not converged after $(info. numiter) iterations"
29+ end
30+
31+ if size (TT, 2 ) > 1 && TT[2 , 1 ] != 0
32+ @warn (" Non-unique largest eigenvector of transfer matrix found" )
33+ end
34+
1835 if imag (λ₁ᴿᴺ) / norm (λ₁ᴿᴺ) > 1e-15
1936 @show λ₁ᴿᴺ
2037 error (
@@ -24,11 +41,9 @@ function right_orthogonalize(
2441
2542 # Fix the phase of the diagonal to make Hermitian
2643 v₁ᴿᴺ .*= conj (sign (v₁ᴿᴺ[1 , 1 ]))
27- if ! ishermitian (v₁ᴿᴺ; rtol= tol)
28- @show λ₁ᴿᴺ
29- @show v₁ᴿᴺ
44+ if ! ishermitian (v₁ᴿᴺ; ishermitian_kwargs... )
3045 @show norm (v₁ᴿᴺ - swapinds (dag (v₁ᴿᴺ), reverse (Pair (inds (v₁ᴿᴺ)... ))))
31- error (" v₁ᴿᴺ not hermitian" )
46+ @warn (" v₁ᴿᴺ is not hermitian, passed kwargs: $ishermitian_kwargs " )
3247 end
3348 if norm (imag (v₁ᴿᴺ)) / norm (v₁ᴿᴺ) > 1e-13
3449 println (
105120function mixed_canonical (
106121 ψ:: InfiniteMPS ; left_tags= ts " Left" , right_tags= ts " Right" , tol:: Real = 1e-12
107122)
108- _, ψᴿ, _ = right_orthogonalize (ψ; left_tags= ts "" , right_tags= ts " Right " )
109- ψᴸ, C, λ = left_orthogonalize (ψᴿ; left_tags= ts " Left " , right_tags= ts " Right " )
123+ _, ψᴿ, _ = right_orthogonalize (ψ; left_tags= ts "" , right_tags)
124+ ψᴸ, C, λ = left_orthogonalize (ψᴿ; left_tags, right_tags)
110125 if λ ≉ one (λ)
111126 error (" λ should be approximately 1 after orthogonalization, instead it is $λ " )
112127 end
0 commit comments