diff --git a/src/IntrTree/addIntr.jl b/src/IntrTree/addIntr.jl index e04f369..e164c83 100644 --- a/src/IntrTree/addIntr.jl +++ b/src/IntrTree/addIntr.jl @@ -98,6 +98,37 @@ function _addZ!(OR::LocalOperator{2, 2}, Z::AbstractTensorMap) return OR end +# swap two operators to deal with horizontal bond +_swap(A::LocalOperator{1, 1}, B::LocalOperator{1, 1}) = B, A +_swap(A::LocalOperator{1, 1}, B::LocalOperator{1, 2}) = B, A +_swap(A::LocalOperator{2, 1}, B::LocalOperator{1, 1}) = B, A +function _swap(A::LocalOperator{1, 2}, B::LocalOperator{2, 1}) + return _swapOp(B), _swapOp(A) +end +function _swap(A::LocalOperator{1, 2}, B::LocalOperator{2, 2}) + # | | | | + # A-- --B--va --> B-- --A--va + # | | | | + + @tensor AB[d e; a b f] := A.A[a b c] * B.A[c d e f] + # QR + TA, TB = leftorth(AB) + + return LocalOperator(permute(TA, (1,), (2, 3)), B.name, B.si, B.strength), LocalOperator(permute(TB, (1, 2), (3, 4)), A.name, A.si, A.strength) +end +function _swap(A::LocalOperator{2, 2}, B::LocalOperator{2,1}) + # | | | | + # va--A-- --B --> va--B-- --A + # | | | | + + @tensor AB[a e f; b c] := A.A[a b c d] * B.A[d e f] + # QR + TA, TB = rightorth(AB) + + return LocalOperator(permute(TA, (1, 2), (3, 4)), B.name, B.si, B.strength), LocalOperator(permute(TB, (1, 2), (3,)), A.name, A.si, A.strength) +end + + diff --git a/src/IntrTree/addIntr4.jl b/src/IntrTree/addIntr4.jl index 5a02837..5195733 100644 --- a/src/IntrTree/addIntr4.jl +++ b/src/IntrTree/addIntr4.jl @@ -38,20 +38,25 @@ function addIntr4!(Root::InteractionTreeNode, O::NTuple{4,AbstractTensorMap}, si (A, B, C, D) = map(1:4) do i LocalOperator(O[i], name[i], si[i]) end - _addtag!(A, B, C, D) # deal with the permutation 1<->2 and 3<->4 if si[1] > si[2] - A, B = _leftOp(B), _rightOp(A) + A, B = _swap(A, B) si = (si[2], si[1], si[3], si[4]) !isnothing(Z) && (strength *= -1) end if si[3] > si[4] - C, D = _leftOp(D), _rightOp(C) + C, D = _swap(C, D) si = (si[1], si[2], si[4], si[3]) !isnothing(Z) && (strength *= -1) end + _addtag!(A, B, C, D) + + # ============ reduce to 2-site term =========== + if A.si == B.si && C.si == D.si + return addIntr2!(Root, A * B, C * D, strength, nothing; value = value) + end if A.si == C.si && B.si == D.si # D # C Z Z Z Z -BD