Skip to content

Commit 6753076

Browse files
authored
Avoid computing the norm on normalization of a Canonical MPS (#338)
* Avoid computing the `norm` on normalization of a `Canonical` MPS * Fix normalization for Gamma tensors * Fix `normalize!(::Canonical, ::AbstractMPO)` when `bond` kwarg is set * remove wrong comment * fix typo * add note * last fixes * Fix normalization of boundary gamma tensors
1 parent 0c2ad3e commit 6753076

File tree

1 file changed

+58
-8
lines changed

1 file changed

+58
-8
lines changed

src/MPS.jl

+58-8
Original file line numberDiff line numberDiff line change
@@ -728,16 +728,66 @@ function LinearAlgebra.normalize!(config::MixedCanonical, ψ::AbstractMPO; at=co
728728
end
729729

730730
function LinearAlgebra.normalize!(::Canonical, ψ::AbstractMPO; bond=nothing)
731-
old_norm = norm(ψ)
732-
if isnothing(bond) # Normalize all λ tensors
733-
for i in 1:(nlanes(ψ) - 1)
734-
λ = tensors(ψ; bond=(Lane(i), Lane(i + 1)))
735-
replace!(ψ, λ => λ ./ old_norm^(1 / (nlanes(ψ) - 1)))
731+
if !isnothing(bond)
732+
# when setting `bond`, we are just normalizing one Λ tensor and its neighbor Γ tensors
733+
Λab = tensors(ψ; bond)
734+
normalize!(Λab)
735+
736+
a, b = bond
737+
Γa, Γb = tensors(ψ; at=a), tensors(ψ; at=b)
738+
739+
# ρ are Γ tensors with neighbor Λ tensors contracted => ρ = Λ Γ Λ
740+
# i.e. it's half reduced density matrix for the site, so it's norm is the total norm too
741+
# NOTE this works only if the state is correctly canonized!
742+
ρa, ρb = contract(Γa, Λab; dims=Symbol[]), contract(Γb, Λab; dims=Symbol[])
743+
744+
# open boundary conditions
745+
if a != lane"1"
746+
Λa = tensors(ψ; bond=(Lane(id(a) - 1), a))
747+
ρa = contract(ρa, Λa; dims=Symbol[])
736748
end
737-
else
738-
λ = tensors(ψ; bond)
739-
replace!(ψ, λ => λ ./ old_norm)
749+
750+
if b != Lane(nlanes(ψ))
751+
Λb = tensors(ψ; bond=(b, Lane(id(b) + 1)))
752+
ρb = contract(ρb, Λb; dims=Symbol[])
753+
end
754+
755+
Za, Zb = norm(ρa), norm(ρb)
756+
757+
Γa ./= Za
758+
Γb ./= Zb
740759
end
741760

761+
# normalize the Λ tensors
762+
for i in 1:(nlanes(ψ) - 1)
763+
Λ = tensors(ψ; bond=(Lane(i), Lane(i + 1)))
764+
normalize!(Λ)
765+
end
766+
767+
# normalize the Γ tensors
768+
for i in 2:(nlanes(ψ) - 1)
769+
Γ = tensors(ψ; at=Lane(i))
770+
Λᵢ₋₁ = tensors(ψ; bond=(Lane(i - 1), Lane(i)))
771+
Λᵢ₊₁ = tensors(ψ; bond=(Lane(i), Lane(i + 1)))
772+
773+
# NOTE manual binary contraction due to bugs in `contract(args...)`
774+
ρ = contract(contract(Γ, Λᵢ₋₁; dims=Symbol[]), Λᵢ₊₁; dims=Symbol[])
775+
Z = norm(ρ)
776+
Γ ./= Z
777+
end
778+
779+
# normalize the first and last Γ tensors
780+
Γ = tensors(ψ; at=lane"1")
781+
Λ = tensors(ψ; bond=(lane"1", lane"2"))
782+
ρ = contract(Γ, Λ; dims=Symbol[])
783+
Z = norm(ρ)
784+
Γ ./= Z
785+
786+
Γ = tensors(ψ; at=Lane(nlanes(ψ)))
787+
Λ = tensors(ψ; bond=(Lane(nlanes(ψ) - 1), Lane(nlanes(ψ))))
788+
ρ = contract(Γ, Λ; dims=Symbol[])
789+
Z = norm(ρ)
790+
Γ ./= Z
791+
742792
return ψ
743793
end

0 commit comments

Comments
 (0)