Skip to content

Commit 4712074

Browse files
authored
Fix an issue with wrong leg fusers (#405)
* rework derivatives to avoid incompatible leg fusion * extra fix
1 parent d43b020 commit 4712074

File tree

1 file changed

+25
-15
lines changed

1 file changed

+25
-15
lines changed

src/algorithms/derivatives/mpo_derivatives.jl

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ function PrecomputedDerivative(L::AbstractTensorMap, R::AbstractTensorMap, backe
128128
end
129129

130130
const PrecomputedCDerivative{T, S, M, B, A} = PrecomputedDerivative{T, S, M, 1, 2, 2, 1, B, A}
131-
const PrecomputedACDerivative{T, S, M, B, A} = PrecomputedDerivative{T, S, M, 2, 3, 2, 1, B, A}
132-
const PrecomputedAC2Derivative{T, S, M, B, A} = PrecomputedDerivative{T, S, M, 2, 3, 3, 2, B, A}
131+
const PrecomputedACDerivative{T, S, M, B, A} = PrecomputedDerivative{T, S, M, 2, 2, 2, 1, B, A}
132+
const PrecomputedAC2Derivative{T, S, M, B, A} = PrecomputedDerivative{T, S, M, 2, 2, 2, 2, B, A}
133133

134134
VectorInterface.scalartype(::Type{<:PrecomputedDerivative{T}}) where {T} = T
135135
TensorKit.storagetype(::Type{<:PrecomputedDerivative{T, S, M}}) where {T, S, M} = M
@@ -174,9 +174,10 @@ function prepare_operator!!(
174174
backend::AbstractBackend, allocator
175175
)
176176
@plansor backend = backend allocator = allocator begin
177-
GL_O[-1 -2; -4 -5 -3] := H.leftenv[-1 1; -4] * H.operators[1][1 -2; -5 -3]
177+
GL_O[-1 -2 -3; -4 -5] := H.leftenv[-1 1; -4] * H.operators[1][1 -2; -5 -3]
178178
end
179179
leftenv = GL_O isa TensorMap ? GL_O : TensorMap(GL_O)
180+
leftenv = repartition(fuse_legs(leftenv, 1, 2), 2, 2)
180181
rightenv = H.rightenv isa TensorMap ? H.rightenv : TensorMap(H.rightenv)
181182

182183
return prepared_operator_type(typeof(H), typeof(backend), typeof(allocator))(
@@ -189,12 +190,14 @@ function prepare_operator!!(
189190
backend::AbstractBackend, allocator
190191
)
191192
@plansor backend = backend allocator = allocator begin
192-
GL_O[-1 -2; -4 -5 -3] := H.leftenv[-1 1; -4] * H.operators[1][1 -2; -5 -3]
193-
O_GR[-1 -2 -3; -4 -5] := H.operators[2][-3 -5; -2 1] * H.rightenv[-1 1; -4]
193+
GL_O[-1 -2 -3; -4 -5] := H.leftenv[-1 1; -4] * H.operators[1][1 -2; -5 -3]
194+
O_GR[-1 -2; -4 -5 -3] := H.operators[2][-3 -5; -2 1] * H.rightenv[-1 1; -4]
194195
end
195-
196196
leftenv = GL_O isa TensorMap ? GL_O : TensorMap(GL_O)
197+
leftenv = repartition(fuse_legs(leftenv, 1, 2), 2, 2)
198+
197199
rightenv = O_GR isa TensorMap ? O_GR : TensorMap(O_GR)
200+
rightenv = repartition(fuse_legs(rightenv, 2, 1), 2, 2)
198201
return prepared_operator_type(typeof(H), typeof(backend), typeof(allocator))(
199202
leftenv, rightenv, backend, allocator
200203
)
@@ -221,7 +224,7 @@ function (H::PrecomputedACDerivative)(x::MPSTensor)
221224
backend, allocator = H.backend, H.allocator
222225
L, R = H.leftenv, H.rightenv
223226

224-
L_fused = fuse_legs(L, 2, 2)
227+
L_fused = fuse_legs(L, 2, 1)
225228
x_fused = fuse_legs(x, 2, 1)
226229
LxR_fused = PrecomputedDerivative(L_fused, R, backend, allocator)(x_fused)
227230

@@ -231,9 +234,9 @@ function (H::PrecomputedAC2Derivative)(x::MPOTensor)
231234
backend, allocator = H.backend, H.allocator
232235
L, R = H.leftenv, H.rightenv
233236

234-
L_fused = fuse_legs(L, 2, 2)
237+
L_fused = fuse_legs(L, 2, 1)
235238
x_fused = fuse_legs(x, 2, 2)
236-
R_fused = fuse_legs(R, 2, 2)
239+
R_fused = fuse_legs(R, 1, 2)
237240
LxR_fused = PrecomputedDerivative(L_fused, R_fused, backend, allocator)(x_fused)
238241

239242
return TensorMap{scalartype(LxR_fused)}(LxR_fused.data, codomain(L) domain(R))
@@ -246,21 +249,28 @@ function (H::PrecomputedACDerivative)(x::AbstractTensorMap{<:Any, <:Any, 3, 1})
246249
L, R = H.leftenv, H.rightenv
247250

248251
@plansor backend = backend allocator = allocator begin
249-
y[-1 -2 -3; -4] ≔
250-
L[-1 -2; 4 5 2] * x[4 5 3; 1] * τ[2 -3; 3 6] * R[1 6; -4]
252+
xR[-1 -2; -4 -5 -3] := x[-1 -2 3; 1] * R[1 2; -4] * τ[2 3; -5 -3]
253+
end
254+
xR_fused = fuse_legs(xR, 2, 1)
255+
@plansor backend = backend allocator = allocator begin
256+
y[-1 -2 -3; -4] := L[-1 -2; 1 2] * xR_fused[1; -4 -3 2]
251257
end
252258
return y
253259
end
254260
function (H::PrecomputedAC2Derivative)(x::AbstractTensorMap{<:Any, <:Any, 3, 3})
255261
backend, allocator = H.backend, H.allocator
256262
L, R = H.leftenv, H.rightenv
257263

258-
x_braided = braid(x, ((5, 3, 1, 2), (4, 6)), (1, 2, 3, 4, 5, 6))
264+
x_braided = fuse_legs(braid(x, ((1, 2, 3, 5), (4, 6)), (1, 2, 3, 4, 5, 6)), 1, 2)
265+
266+
@plansor backend = backend allocator = allocator begin
267+
xR[-1 -2; -4 -6 -7 -5 -3] := x_braided[-1 -2 -3 -5; 1] * R[1 -7; -4 -6]
268+
end
269+
@notensor xR_braided = braid(fuse_legs(xR, 2, 1), ((1, 4), (2, 3, 5, 6)), (1, 4, 6, 7, 5, 3))
259270
@plansor backend = backend allocator = allocator begin
260-
y_braided[-5 -3 -1 -2; -4 -6] ≔
261-
L[-1 -2; 3 4 5] * x_braided[-5 -3 3 4; 1 2] * R[1 2 5; -4 -6]
271+
y_braided[-1 -2; -4 -6 -5 -3] := L[-1 -2; 1 2] * xR_braided[1 2; -4 -6 -5 -3]
262272
end
263-
return braid(y_braided, ((3, 4, 2), (5, 1, 6)), (5, 3, 1, 2, 4, 6))
273+
return braid(y_braided, ((1, 2, 6), (3, 5, 4)), (1, 2, 4, 5, 5, 3))
264274
end
265275

266276
const _ToPrepare = Union{

0 commit comments

Comments
 (0)