@@ -23,9 +23,13 @@ function _ntu_iter(
2323
2424 # truncate each bond sequentially along the path
2525 info = (; fid = 1.0 )
26- for (bondsites, trunc) in zip (zip (sites, Iterators. drop (sites, 1 )), truncs)
26+ nbond = length (sites) - 1
27+ for (i, bondsites) in enumerate (zip (sites, Iterators. drop (sites, 1 )))
28+ trunc = truncs[i]
2729 alg′ = (@set alg. opt_alg. trunc = trunc)
28- state, wts, info′ = _bond_truncate (state, wts, bondsites, alg′)
30+ stype1 = (i == 1 ) ? :first : :middle
31+ stype2 = (i == nbond) ? :last : :middle
32+ state, wts, info′ = _bond_truncate (state, wts, bondsites, (stype1, stype2), alg′)
2933 # record the worst fidelity
3034 (info′. fid < info. fid) && (info = info′)
3135 end
3539"""
3640Truncate a nearest neighbor bond between `site1` and `site2`
3741after rotating the bond to standard x direction `A ← B`.
42+
43+ `bondtype` takes values in (1, 2, 3), meaning that the current bond is
44+ (the first, a middle, the last) bond in the updated cluster.
3845"""
3946function _bond_truncate (
4047 state:: InfiniteState , wts:: SUWeight ,
4148 (site1, site2):: NTuple{2, CartesianIndex{2}} ,
49+ (stype1, stype2):: NTuple{2, Symbol} ,
4250 alg:: NeighbourUpdate ; gate:: Union{NNGate, Nothing} = nothing
4351 )
4452 # rotate bond to standard x direction `A ← B`
@@ -54,14 +62,26 @@ function _bond_truncate(
5462 A, B = state2[row, col], state2[row, cp1]
5563
5664 # create bond environment
57- a, X = bond_tensor_first (A; trunc = trunctol (; rtol = 1.0e-12 ))
58- b, Y = bond_tensor_last (B; trunc = trunctol (; rtol = 1.0e-12 ))
65+ qrtrunc = trunctol (; rtol = 1.0e-12 )
66+ a, X = if stype1 == :first
67+ bond_tensor_first (A; trunc = qrtrunc)
68+ else
69+ @assert stype1 == :middle
70+ bond_tensor_midnext (A; trunc = qrtrunc)
71+ end
72+ b, Y = if stype2 == :last
73+ bond_tensor_last (B; trunc = qrtrunc)
74+ else
75+ @assert stype2 == :middle
76+ bond_tensor_midprev (B; trunc = qrtrunc)
77+ end
5978 benv = bondenv_ntu (row, col, X, Y, state2, alg. bondenv_alg)
6079 @debug " cond(benv) before gauge fix: $(LinearAlgebra. cond (benv)) "
6180 if alg. fixgauge
6281 Z = positive_approx (benv)
6382 Z, a, b, (Linv, Rinv) = fixgauge_benv (Z, a, b)
64- X, Y = _fixgauge_benvXY (X, Y, Linv, Rinv)
83+ X = _fixgauge_benvX (X, Rinv)
84+ Y = _fixgauge_benvY (Y, Linv)
6585 benv = Z' * Z
6686 @debug " cond(L) = $(LinearAlgebra. cond (Linv)) ; cond(R): $(LinearAlgebra. cond (Rinv)) "
6787 @debug " cond(benv) after gauge fix: $(LinearAlgebra. cond (benv)) "
@@ -70,14 +90,20 @@ function _bond_truncate(
7090 # (optional) apply the NN gate without truncation
7191 if ! (gate === nothing )
7292 a, s, b, = _apply_gate (a, b, gate, truncerror (; atol = 1.0e-15 ))
93+ end
94+ a, s, b, info = bond_truncate (a, b, benv, alg. opt_alg)
95+
96+ A = if stype1 == :first
97+ undo_bond_tensor_first (a, X)
7398 else
74- a = permute (a, ((1 , 2 ), (3 ,)))
75- b = permute (b, ((1 ,), (2 , 3 )))
99+ undo_bond_tensor_midnext (a, X)
100+ end
101+ B = if stype2 == :last
102+ undo_bond_tensor_last (b, Y)
103+ else
104+ undo_bond_tensor_midprev (b, Y)
76105 end
77106
78- a, s, b, info = bond_truncate (a, b, benv, alg. opt_alg)
79- A = undo_bond_tensor_first (a, X)
80- B = undo_bond_tensor_last (b, Y)
81107 normalize! (A, Inf )
82108 normalize! (B, Inf )
83109 normalize! (s, Inf )
0 commit comments