@@ -728,16 +728,66 @@ function LinearAlgebra.normalize!(config::MixedCanonical, ψ::AbstractMPO; at=co
728
728
end
729
729
730
730
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[])
736
748
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
740
759
end
741
760
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
+
742
792
return ψ
743
793
end
0 commit comments