6666@non_differentiable _condition_number (S:: AbstractTensorMap )
6767
6868"""
69- compute_projector(enlarged_corners, coordinate, alg::ProjectorAlgorithm)
70-
71- Determine left and right projectors at the bond given determined by the enlarged corners
72- and the given coordinate using the specified `alg`.
73- """
74- function compute_projector (enlarged_corners, coordinate, alg:: HalfInfiniteProjector )
75- # SVD half-infinite environment
76- halfinf = half_infinite_environment (enlarged_corners... )
77- svd_alg = svd_algorithm (alg, coordinate)
78- U, S, V, truncation_error = PEPSKit. tsvd! (halfinf, svd_alg; trunc= alg. trscheme)
69+ compute_projector(L::AbstractTensorMap, R::AbstractTensorMap, svd_alg, alg)
70+
71+ Given the bond connecting the left and right tensors, e.g. L and R, we compute the projectors on the bond.
72+ This is a general algorithm that can be used for any bond. The only thing you need worry about
73+ is the left and right tensors. After the projection, the arrow of the bond is now (L⊙P_L)←(P_R⊙R).
74+
75+ ```
76+ L⊙R=(L⊙R)*(L⊙R)^-1*(L⊙R)=(L⊙R)*(U*S*V)^-1*(L⊙R)=(L⊙R)*V'S^{-1}U'*(L⊙R)=L⊙(R*V'*S^{-1/2})*(S^{-1/2}*U'*L)⊙R=L⊙P_L*P_R⊙R
77+ ```
78+ """
79+ # help function for the projection, particularly for the sign of fermions
80+ ⊙ (t1:: AbstractTensorMap , t2:: AbstractTensorMap )= twist (t1, filter (i -> ! isdual (space (t1, i)), domainind (t1)))* t2
81+
82+ function compute_projector (L:: AbstractTensorMap , R:: AbstractTensorMap , svd_alg, alg)
83+ if dim (codomain (L)) > dim (domain (L))
84+ _,L= leftorth! (L)
85+ R,_= rightorth! (R)
86+ end
87+ LR= L⊙ R
88+ n_factor= norm (LR)
89+ LR= LR/ n_factor
90+
91+ U, S, V, truncation_error = PEPSKit. tsvd! (LR, svd_alg; trunc= alg. trscheme)
7992
8093 # Check for degenerate singular values
8194 Zygote. isderiving () && ignore_derivatives () do
@@ -85,29 +98,14 @@ function compute_projector(enlarged_corners, coordinate, alg::HalfInfiniteProjec
8598 end
8699 end
87100
88- P_left, P_right = contract_projectors (U, S, V, enlarged_corners... )
101+ norm_factor = sqrt (n_factor)
102+ isqS = sdiag_pow (S, - 0.5 )
103+ PL = R * V' * isqS / norm_factor
104+ PR = isqS * U' * L / norm_factor
105+
89106 truncation_error /= norm (S)
90- condition_number = @ignore_derivatives (_condition_number (S))
91- return (P_left, P_right), (; truncation_error, condition_number, U, S, V)
92- end
93- function compute_projector (enlarged_corners, coordinate, alg:: FullInfiniteProjector )
94- halfinf_left = half_infinite_environment (enlarged_corners[1 ], enlarged_corners[2 ])
95- halfinf_right = half_infinite_environment (enlarged_corners[3 ], enlarged_corners[4 ])
96-
97- # SVD full-infinite environment
98- fullinf = full_infinite_environment (halfinf_left, halfinf_right)
99- svd_alg = svd_algorithm (alg, coordinate)
100- U, S, V, truncation_error = PEPSKit. tsvd! (fullinf, svd_alg; trunc= alg. trscheme)
101-
102- # Check for degenerate singular values
103- Zygote. isderiving () && ignore_derivatives () do
104- if alg. verbosity > 0 && is_degenerate_spectrum (S)
105- svals = TensorKit. SectorDict (c => diag (b) for (c, b) in blocks (S))
106- @warn (" degenerate singular values detected: " , svals)
107- end
107+ condition_number = ignore_derivatives () do
108+ _condition_number (S)
108109 end
109-
110- P_left, P_right = contract_projectors (U, S, V, halfinf_left, halfinf_right)
111- condition_number = @ignore_derivatives (_condition_number (S))
112- return (P_left, P_right), (; truncation_error, condition_number, U, S, V)
110+ return (PL, PR), (; truncation_error, condition_number, U, S, V)
113111end
0 commit comments