From 5615270498aa73139726eae5a7eeefd3eab256d3 Mon Sep 17 00:00:00 2001 From: leburgel Date: Thu, 17 Sep 2026 15:49:48 +0200 Subject: [PATCH 1/4] Restrict to pure environment VJP in implicit differentiation linear problem --- .../ctmrg/characteristic_equations.jl | 81 ++++++++++++++----- .../optimization/implicit_differentiation.jl | 45 ++++++++--- 2 files changed, 93 insertions(+), 33 deletions(-) diff --git a/src/algorithms/contractions/ctmrg/characteristic_equations.jl b/src/algorithms/contractions/ctmrg/characteristic_equations.jl index fa852187f..a53d4cb4e 100644 --- a/src/algorithms/contractions/ctmrg/characteristic_equations.jl +++ b/src/algorithms/contractions/ctmrg/characteristic_equations.jl @@ -52,17 +52,21 @@ end Cfp::CornerTensor, Efp::EdgeTensor, # unused Ufp::LeftProjector, - ULfp::LeftProjector, + ULfp::LeftProjector; + site = getindex, ) Takes the fixed-point values of the corner tensor `Cfp`, edge tensor `Efp`, left isometry `Ufp` and its left null space `ULfp` corresponding to a converged C4v CTMRG contraction, and -generates a function ``F(s, C, E, u)`` which characterizes the convergence of the C4v CTMRG -algorithm in terms of the characteristic equation ``F(s, C, E, u) = 0``. -Here, ``s`` corresponds to a state variable (e.g. an `InfinitePEPS` that is being optimized), -and ``(C, E, u)`` represents a C4v symmetric contraction environment. -``C`` and ``E`` directly represent the corner and edge tensors, while ``u`` parametrizes -a differentiable projector ``U`` as ``U = U_{fp} + U_{L,fp} * u``. +generates a function ``F(n, C, E, u)`` which characterizes the convergence of the C4v CTMRG +algorithm in terms of the characteristic equation ``F(n, C, E, u) = 0``. Here, ``n`` is the +`InfiniteSquareNetwork` containing the state variable being optimized, and ``(C, E, u)`` +represents a C4v symmetric contraction environment. ``C`` and ``E`` directly represent the +corner and edge tensors, while ``u`` parametrizes a differentiable projector ``U`` as ``U = +U_{fp} + U_{L,fp} * u``. + +The local sandwich is read through `site`, so a caller can choose whether it is +differentiated at all; see [`PEPSKit.constant_site`](@ref). ``F`` returns a tuple of three tensors, corresponding to an equation for ``C``, ``E`` and ``u`` respectively: @@ -95,15 +99,15 @@ function generate_symmetric_characteristic_equation( Cfp::CornerTensor, Efp::EdgeTensor, # unused Ufp::LeftProjector, - ULfp::LeftProjector, + ULfp::LeftProjector; + site = getindex, ) iC = sdiag_pow(real(DiagonalTensorMap(Cfp)), -1) ULd = ULfp' - function symmetric_characteristic_equation(state, C, E, u) - network = InfiniteSquareNetwork(state) - O = network[1, 1] + function symmetric_characteristic_equation(n, C, E, u) + O = site(n, 1, 1) # project input C = project_hermitian(C) @@ -313,6 +317,33 @@ end # Util # ---- +""" + constant_site(network, r, c) + +Read the local sandwich at `(r, c)` without making it a differentiable value. + +`TensorOperations` thunks the cotangents of a contraction's inputs, so an untracked sandwich +never forces the ket and bra cotangents - which the implicit gradient's linear solve discards +anyway. The marker has to sit on the outermost read: capturing the network and indexing it +normally leaves the sandwich tracked. +""" +constant_site(network, r, c) = ignore_derivatives() do + return network[r, c] +end + +""" + _enlarged_corner(network, env, coordinates; site = getindex) + +Build an enlarged corner whose local sandwich is read through `site`, without adding an +implicit-differentiation keyword to `EnlargedCorner` itself. The sandwich the constructor +reads is discarded, never contracted, and so never picks up a cotangent. +""" +function _enlarged_corner(network, env, coordinates; site = getindex) + _, r, c = coordinates + Q = EnlargedCorner(network, env, coordinates) + return EnlargedCorner(Q.C, Q.E_1, Q.E_2, site(network, r, c), Q.dir) +end + function eachcoordinate(tensor_unitcell::Array{<:AbstractTensorMap, 3}) return collect(Iterators.product(axes(tensor_unitcell)...)) end @@ -395,7 +426,8 @@ function contract_halfinfinite_characteristic_equation( Ud::RightProjectors, Vd::LeftProjectors, iCi::CornerTensors, ULd::RightProjectors, VRd::LeftProjectors, - iSfp::CornerTensors, + iSfp::CornerTensors; + site = getindex, ) coordinates = eachcoordinate(n, 1:4) nrows, ncols = size(n) @@ -403,10 +435,11 @@ function contract_halfinfinite_characteristic_equation( # precompute rotated local sandwiches, enlarged corners, and projectors Or = map(coordinates) do co dir, r, c = co - return _rotate_north_localsandwich(n[r, c], dir) + return _rotate_north_localsandwich(site(n, r, c), dir) end + envi = CTMRGEnv(iCi, E) EC = map(coordinates) do co - return TensorMap(EnlargedCorner(n, CTMRGEnv(iCi, E), co)) + return TensorMap(_enlarged_corner(n, envi, co; site)) end PR = map(coordinates) do co co′ = _proj_sinv_indices(co, nrows, ncols) @@ -482,17 +515,21 @@ end Ufp::LeftProjectors, Vfp::RightProjectors, ULfp::LeftProjectors, - VRfp::RightProjectors, + VRfp::RightProjectors; + site = getindex, ) Takes the fixed-point values of the inverse singular values `iSfp`, the left and right isometries `Ufp` and `Vfp`, and their null spaces `ULfp` and `VRfp` corresponding to a converged CTMRG contraction, -and generates a function ``F(s, C, E, u, S, v)`` which characterizes the convergence of the CTMRG algorithm in terms of the characteristic equation ``F(s, C, E, u, S, v) = 0``. Here, ``s`` corresponds to a -state variable (e.g. an `InfinitePEPS` that is being optimized), and ``(C, E, u, S, v)`` represents a CTMRG +and generates a function ``F(n, C, E, u, S, v)`` which characterizes the convergence of the CTMRG algorithm in terms of the characteristic equation ``F(n, C, E, u, S, v) = 0``. Here, ``n`` is the +`InfiniteSquareNetwork` containing the state variable being optimized, and ``(C, E, u, S, v)`` represents a CTMRG contraction environment on a generic unit cell meaning that all tensors have a directional and unit cell index. ``C`` and ``E`` directly represent the corner and edge tensors, while ``u`` and ``v`` parametrize differentiable projectors ``U = U_{fp} + U_{L,fp} u`` and ``V = V_{fp} + V_{L,fp} V``, and ``S`` denotes the singular values of the decomposed environment. +The local sandwiches are read out of ``n`` through `site`, so a caller can choose whether they +are differentiated at all; see [`PEPSKit.constant_site`](@ref). + ``F`` returns a tuple of five tensor arrays, corresponding to equations for ``C``, ``E``, ``u``, ``S`` and ``v``, respectively, as shown in Eqs. (76)-(80) in [arXiv:2607.15030](@cite burgelman_implicit_2026). """ @@ -501,7 +538,8 @@ function generate_halfinfinite_characteristic_equation( Ufp::LeftProjectors, Vfp::RightProjectors, ULfp::LeftProjectors, - VRfp::RightProjectors, + VRfp::RightProjectors; + site = getindex, ) iSfp = real.(DiagonalTensorMap.(iSfp)) # use as constant preconditioner? @@ -509,7 +547,7 @@ function generate_halfinfinite_characteristic_equation( nrows, ncols = size(iSfp)[2:3] # the main routine which uses both the singular values and their inverses - function asymmetric_characteristic_equation(state, C, E, u, s, v) + function asymmetric_characteristic_equation(n, C, E, u, s, v) ## Prepare all the objects we need in the right parametrization is = map(inv, s) @@ -553,11 +591,12 @@ function generate_halfinfinite_characteristic_equation( C, E, is, s, u, v, - InfiniteSquareNetwork(state), + n, Ud, Vd, iCi, ULd, VRd, - iSfp, + iSfp; + site, ) return F1, F2, F3, F4, F5 diff --git a/src/algorithms/optimization/implicit_differentiation.jl b/src/algorithms/optimization/implicit_differentiation.jl index f00632504..787cf3d20 100644 --- a/src/algorithms/optimization/implicit_differentiation.jl +++ b/src/algorithms/optimization/implicit_differentiation.jl @@ -501,13 +501,22 @@ function _rrule( # prepare pullback of C4v CTMRG environment constructor (artefact of reusing asymmetric environment type for C4v symmetric contraction) _, c4v_env_vjp = rrule_via_ad(config, CTMRGEnv, C, E) - # initialize the partial pullbacks of the characteristic equations - F = generate_symmetric_characteristic_equation(C, E, U, UL) + # Two tapes: the linear solve only uses the environment cotangents, so reading the + # sandwich through `constant_site` leaves the ket and bra cotangents unforced. The state + # pullback runs once, after the solve, and gets its own tape. + F_tracked = generate_symmetric_characteristic_equation(C, E, U, UL) + F_untracked = generate_symmetric_characteristic_equation( + C, E, U, UL; site = constant_site + ) + network = InfiniteSquareNetwork(state) + + F_environment(C′, E′, u′) = F_untracked(network, C′, E′, u′) + F_full(A, C′, E′, u′) = F_tracked(InfiniteSquareNetwork(A), C′, E′, u′) - # get the partial pullback of the characteristic equations - _, F_vjp = rrule_via_ad(config, F, state, C, E, u) - vjp_env(x) = F_vjp(x)[3:end] # environment and isometry pullback - vjp_state(x) = F_vjp(x)[2] # state pullback + _, F_vjp_environment = rrule_via_ad(config, F_environment, C, E, u) + _, F_vjp_full = rrule_via_ad(config, F_full, state, C, E, u) + vjp_env(x) = F_vjp_environment(x)[2:end] # environment and isometry pullback + vjp_state(x) = F_vjp_full(x)[2] # state pullback function leading_boundary_implicit_pullback((_Δenv, _Δinfo)) Δenv, Δinfo = unthunk(_Δenv), unthunk(_Δinfo) @@ -647,19 +656,31 @@ function PEPSKit._rrule( end is = sdiag_pow.(s, -1) # also treat them as general complex tensors - # generate the characteristic equations - F = generate_halfinfinite_characteristic_equation(is, U, V, UL, VR) + # Two tapes: the linear solve only uses the environment cotangents, so reading the + # sandwiches through `constant_site` leaves the ket and bra cotangents unforced. The + # state pullback runs once, after the solve, and gets its own tape. + F_tracked = generate_halfinfinite_characteristic_equation(is, U, V, UL, VR) + F_untracked = generate_halfinfinite_characteristic_equation( + is, U, V, UL, VR; site = constant_site + ) + network = InfiniteSquareNetwork(state) + + F_environment(C′, E′, u′, s′, v′) = F_untracked(network, C′, E′, u′, s′, v′) + function F_full(A, C′, E′, u′, s′, v′) + return F_tracked(InfiniteSquareNetwork(A), C′, E′, u′, s′, v′) + end # check if characteristic equations are actually satisfied - FS = F(state, C̃, Ẽ, u, s, v) + FS = F_environment(C̃, Ẽ, u, s, v) F_nrms = norm.(FS) any(F_nrms .> 1.0e2 * alg.tol) && @warn "Characteristic equations not satisfied, still using the gradient: $F_nrms" # get the partial gradients of the characteristic equations - _, F_vjp = rrule_via_ad(config, F, state, C̃, Ẽ, u, s, v) # full automatic pullback - vjp_env(x) = F_vjp(x)[3:end] # environment and SVD pullback - vjp_state(x) = F_vjp(x)[2] # state pullback + _, F_vjp_environment = rrule_via_ad(config, F_environment, C̃, Ẽ, u, s, v) + _, F_vjp_full = rrule_via_ad(config, F_full, state, C̃, Ẽ, u, s, v) + vjp_env(x) = F_vjp_environment(x)[2:end] # environment and SVD pullback + vjp_state(x) = F_vjp_full(x)[2] # state pullback function leading_boundary_characteristic_pullback((_Δenv, _Δinfo)) # unpack incoming cotangents From e19ea61624d5088754dec4e54abf0466490a569b Mon Sep 17 00:00:00 2001 From: leburgel Date: Fri, 18 Sep 2026 15:16:55 +0200 Subject: [PATCH 2/4] Switch to implicit null-space projection in half-infinite characteristic equations --- .../ctmrg/characteristic_equations.jl | 73 ++++++++++++------- .../optimization/implicit_differentiation.jl | 20 ++--- 2 files changed, 53 insertions(+), 40 deletions(-) diff --git a/src/algorithms/contractions/ctmrg/characteristic_equations.jl b/src/algorithms/contractions/ctmrg/characteristic_equations.jl index a53d4cb4e..4ffe013e7 100644 --- a/src/algorithms/contractions/ctmrg/characteristic_equations.jl +++ b/src/algorithms/contractions/ctmrg/characteristic_equations.jl @@ -421,11 +421,11 @@ end function contract_halfinfinite_characteristic_equation( C::CornerTensors, E::EdgeTensors, is::CornerTensors, s::CornerTensors, - u::CornerTensors, v::CornerTensors, + u::LeftProjectors, v::RightProjectors, n::InfiniteSquareNetwork, Ud::RightProjectors, Vd::LeftProjectors, iCi::CornerTensors, - ULd::RightProjectors, VRd::LeftProjectors, + proj_u, proj_v, iSfp::CornerTensors; site = getindex, ) @@ -492,8 +492,8 @@ function contract_halfinfinite_characteristic_equation( fp4 = s´ / λs - s[co...] co´ = _next_coordinate(co, nrows, ncols) - fp3 = ((ULd[co...] * EiCiEPL[co...]) * iSfp[co...]) / λs - u[co...] - fp5 = (iSfp[co...] * (_contract_PR_M(PR[co...], EC[co´...]) * VRd[co...])) / λs - v[co...] + fp3 = (proj_u(co, EiCiEPL[co...]) * iSfp[co...]) / λs - u[co...] + fp5 = (iSfp[co...] * proj_v(co, _contract_PR_M(PR[co...], EC[co´...]))) / λs - v[co...] return fp3, fp4, fp5 end @@ -513,19 +513,34 @@ end ::CTMRGAlgorithm{<:HalfInfiniteProjector}, iSfp::CornerTensors, Ufp::LeftProjectors, - Vfp::RightProjectors, - ULfp::LeftProjectors, - VRfp::RightProjectors; + Vfp::RightProjectors; site = getindex, ) -Takes the fixed-point values of the inverse singular values `iSfp`, the left and right isometries `Ufp` -and `Vfp`, and their null spaces `ULfp` and `VRfp` corresponding to a converged CTMRG contraction, -and generates a function ``F(n, C, E, u, S, v)`` which characterizes the convergence of the CTMRG algorithm in terms of the characteristic equation ``F(n, C, E, u, S, v) = 0``. Here, ``n`` is the -`InfiniteSquareNetwork` containing the state variable being optimized, and ``(C, E, u, S, v)`` represents a CTMRG -contraction environment on a generic unit cell meaning that all tensors have a directional and -unit cell index. ``C`` and ``E`` directly represent the corner and edge tensors, while ``u`` and ``v`` -parametrize differentiable projectors ``U = U_{fp} + U_{L,fp} u`` and ``V = V_{fp} + V_{L,fp} V``, and ``S`` denotes the singular values of the decomposed environment. +Takes the fixed-point values of the inverse singular values `iSfp` and the left and right +isometries `Ufp` and `Vfp` corresponding to a converged CTMRG contraction, and generates a +function ``F(n, C, E, u, S, v)`` which characterizes the convergence of the CTMRG algorithm +in terms of the characteristic equation ``F(n, C, E, u, S, v) = 0``. Here, ``n`` is the +`InfiniteSquareNetwork` containing the state variable being optimized, and ``(C, E, u, S, +v)`` represents a CTMRG contraction environment on a generic unit cell meaning that all +tensors have a directional and unit cell index. ``C`` and ``E`` directly represent the +corner and edge tensors, while ``u`` and ``v`` parametrize differentiable projectors ``U = +U_{fp} + P_\\perp^U u`` and ``V = V_{fp} + v P_\\perp^V``, and ``S`` denotes the singular +values of the decomposed environment. Here ``P_\\perp^U = 1 - U_{fp} U_{fp}^\\dagger`` and +``P_\\perp^V = 1 - V_{fp}^\\dagger V_{fp}`` are projectors onto the null spaces of the +fixed-point isometries. Thefore, while ``u`` and ``v`` formally live in the full projector +spaces, they only contain contributions along the null spaces as they are subject to +``U_{fp}^\\dagger u = 0`` and ``v V_{fp}^\\dagger = 0``. + +One could equivalently parametrize the differentiable projectors as ``U = U_{fp} + U_{L,fp} +u`` and ``V = V_{fp} + v V_{R,fp}``, where ``U_{L,fp}`` and ``V_{R,fp}`` are the left and +right null spaces of the fixed-point isometries. In this parametrization, ``u`` and ``v`` +are smaller matrix variables whose variations directly encode the variations of ``U`` and +``V`` along the respective null spaces. While this alternative approach leads to smaller vectors, +and therefore a smaller linear system to solve in the context of implicit differentiation, +the approach using implicit null space projectors without materializing `U_{L,fp}`` and +``V_{R,fp}``allows for a more efficient evaluation of the characteristic equations themselves. + The local sandwiches are read out of ``n`` through `site`, so a caller can choose whether they are differentiated at all; see [`PEPSKit.constant_site`](@ref). @@ -536,9 +551,7 @@ are differentiated at all; see [`PEPSKit.constant_site`](@ref). function generate_halfinfinite_characteristic_equation( iSfp::CornerTensors, Ufp::LeftProjectors, - Vfp::RightProjectors, - ULfp::LeftProjectors, - VRfp::RightProjectors; + Vfp::RightProjectors; site = getindex, ) @@ -546,17 +559,24 @@ function generate_halfinfinite_characteristic_equation( coordinates = eachcoordinate(iSfp) nrows, ncols = size(iSfp)[2:3] + # Orthogonal complements without forming a null space: `U_L U_L^† = 1 - U_{fp} U_{fp}^†`. + # Avoids materializing `ULd`/`VRd` on every evaluation, each as large as an enlarged + # corner. + perp_u(co, x) = x - Ufp[co...] * (Ufp[co...]' * x) + perp_v(co, x) = x - (x * Vfp[co...]') * Vfp[co...] + # the main routine which uses both the singular values and their inverses function asymmetric_characteristic_equation(n, C, E, u, s, v) ## Prepare all the objects we need in the right parametrization is = map(inv, s) - # outspace variation parametrization of isometries + # Outspace variation parametrization. Projecting on input keeps the component along + # the isometry a decoupled identity block, so the adjoint preserves the constraint. U = map(coordinates) do co - return Ufp[co...] + ULfp[co...] * u[co...] + return Ufp[co...] + perp_u(co, u[co...]) end V = map(coordinates) do co - return Vfp[co...] + v[co...] * VRfp[co...] + return Vfp[co...] + perp_v(co, v[co...]) end isqsR = map(fourthroot, adjoint.(is) .* is) # root that goes into the left projector @@ -571,13 +591,14 @@ function generate_halfinfinite_characteristic_equation( co′ = _rightvec_invfroot_indices(co, nrows, ncols) absorb_left(V[co...]', isqsL[co′...]) end - ULd = map(coordinates) do co + # the fourth roots now ride on the objects `ULd`/`VRd` were contracted with + function proj_u(co, x) co′ = _leftvec_invfroot_indices(co, nrows, ncols) - absorb_right(ULfp[co...]', isqsR[co′...]) + return perp_u(co, absorb_left(x, isqsR[co′...])) end - VRd = map(coordinates) do co + function proj_v(co, x) co′ = _rightvec_invfroot_indices(co, nrows, ncols) - absorb_left(VRfp[co...]', isqsL[co′...]) + return perp_v(co, absorb_right(x, isqsL[co′...])) end # pre-contract full inverses into corners from both sides @@ -594,7 +615,7 @@ function generate_halfinfinite_characteristic_equation( n, Ud, Vd, iCi, - ULd, VRd, + proj_u, proj_v, iSfp; site, ) @@ -609,8 +630,6 @@ function generate_fullinfinite_characteristic_equation( iSfp::CornerTensors, Ufp::LeftProjectors, Vfp::RightProjectors, - ULfp::LeftProjectors, - VRfp::RightProjectors, ) throw(ArgumentError("Characteristic equations for CTMRGAlgorithm{<:FullInfiniteProjector} are not yet implemented.")) diff --git a/src/algorithms/optimization/implicit_differentiation.jl b/src/algorithms/optimization/implicit_differentiation.jl index 787cf3d20..aee57f111 100644 --- a/src/algorithms/optimization/implicit_differentiation.jl +++ b/src/algorithms/optimization/implicit_differentiation.jl @@ -643,25 +643,19 @@ function PEPSKit._rrule( # forward pass, and then explicitly backpropagate through that in the pullback here _, absorb_inverse_roots_vjp = rrule_via_ad(config, absorb_inverse_roots, C̃, Ẽ, s) - # get the projector nullspaces - UL = left_null.(U) - VR = right_null.(V) - - # instantiate the variables used in the characteristic equations - u = map(zip(U, UL)) do (Uc, ULc) - return zeros(scalartype(Uc), space(ULc, numind(ULc))' ← space(Uc, numind(Uc))') - end - v = map(zip(V, VR)) do (Vc, VRc) - return zeros(scalartype(Vc), space(Vc, 1) ← space(VRc, 1)) - end + # variables of the characteristic equations, living in the full projector spaces and + # constrained to the orthogonal complements of the isometries inside the characteristic + # equations + u = zerovector.(U) + v = zerovector.(V) is = sdiag_pow.(s, -1) # also treat them as general complex tensors # Two tapes: the linear solve only uses the environment cotangents, so reading the # sandwiches through `constant_site` leaves the ket and bra cotangents unforced. The # state pullback runs once, after the solve, and gets its own tape. - F_tracked = generate_halfinfinite_characteristic_equation(is, U, V, UL, VR) + F_tracked = generate_halfinfinite_characteristic_equation(is, U, V) F_untracked = generate_halfinfinite_characteristic_equation( - is, U, V, UL, VR; site = constant_site + is, U, V; site = constant_site ) network = InfiniteSquareNetwork(state) From 56801fd090bf087c157c56a21b1ebb39a2d1e3ac Mon Sep 17 00:00:00 2001 From: Lander Burgelman <39218680+leburgel@users.noreply.github.com> Date: Mon, 21 Sep 2026 16:09:31 +0200 Subject: [PATCH 3/4] Update src/algorithms/contractions/ctmrg/characteristic_equations.jl Co-authored-by: Paul Brehmer --- src/algorithms/contractions/ctmrg/characteristic_equations.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/algorithms/contractions/ctmrg/characteristic_equations.jl b/src/algorithms/contractions/ctmrg/characteristic_equations.jl index 4ffe013e7..76d5f8b69 100644 --- a/src/algorithms/contractions/ctmrg/characteristic_equations.jl +++ b/src/algorithms/contractions/ctmrg/characteristic_equations.jl @@ -528,7 +528,7 @@ corner and edge tensors, while ``u`` and ``v`` parametrize differentiable projec U_{fp} + P_\\perp^U u`` and ``V = V_{fp} + v P_\\perp^V``, and ``S`` denotes the singular values of the decomposed environment. Here ``P_\\perp^U = 1 - U_{fp} U_{fp}^\\dagger`` and ``P_\\perp^V = 1 - V_{fp}^\\dagger V_{fp}`` are projectors onto the null spaces of the -fixed-point isometries. Thefore, while ``u`` and ``v`` formally live in the full projector +fixed-point isometries. Therefore, while ``u`` and ``v`` formally live in the full projector spaces, they only contain contributions along the null spaces as they are subject to ``U_{fp}^\\dagger u = 0`` and ``v V_{fp}^\\dagger = 0``. From 1fa8e64458e6cfa3aab89ae466dc52f77f6d57bc Mon Sep 17 00:00:00 2001 From: leburgel Date: Mon, 21 Sep 2026 16:17:16 +0200 Subject: [PATCH 4/4] Rename `site` -> `getsite` --- .../ctmrg/characteristic_equations.jl | 30 +++++++++---------- .../optimization/implicit_differentiation.jl | 4 +-- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/algorithms/contractions/ctmrg/characteristic_equations.jl b/src/algorithms/contractions/ctmrg/characteristic_equations.jl index 76d5f8b69..8f56670cc 100644 --- a/src/algorithms/contractions/ctmrg/characteristic_equations.jl +++ b/src/algorithms/contractions/ctmrg/characteristic_equations.jl @@ -53,7 +53,7 @@ end Efp::EdgeTensor, # unused Ufp::LeftProjector, ULfp::LeftProjector; - site = getindex, + getsite = getindex, ) Takes the fixed-point values of the corner tensor `Cfp`, edge tensor `Efp`, left isometry @@ -65,7 +65,7 @@ represents a C4v symmetric contraction environment. ``C`` and ``E`` directly rep corner and edge tensors, while ``u`` parametrizes a differentiable projector ``U`` as ``U = U_{fp} + U_{L,fp} * u``. -The local sandwich is read through `site`, so a caller can choose whether it is +The local sandwich is read through `getsite`, so a caller can choose whether it is differentiated at all; see [`PEPSKit.constant_site`](@ref). ``F`` returns a tuple of three tensors, corresponding to an equation for ``C``, ``E`` and @@ -100,14 +100,14 @@ function generate_symmetric_characteristic_equation( Efp::EdgeTensor, # unused Ufp::LeftProjector, ULfp::LeftProjector; - site = getindex, + getsite = getindex, ) iC = sdiag_pow(real(DiagonalTensorMap(Cfp)), -1) ULd = ULfp' function symmetric_characteristic_equation(n, C, E, u) - O = site(n, 1, 1) + O = getsite(n, 1, 1) # project input C = project_hermitian(C) @@ -332,16 +332,16 @@ constant_site(network, r, c) = ignore_derivatives() do end """ - _enlarged_corner(network, env, coordinates; site = getindex) + _enlarged_corner(network, env, coordinates; getsite = getindex) -Build an enlarged corner whose local sandwich is read through `site`, without adding an +Build an enlarged corner whose local sandwich is read through `getsite`, without adding an implicit-differentiation keyword to `EnlargedCorner` itself. The sandwich the constructor reads is discarded, never contracted, and so never picks up a cotangent. """ -function _enlarged_corner(network, env, coordinates; site = getindex) +function _enlarged_corner(network, env, coordinates; getsite = getindex) _, r, c = coordinates Q = EnlargedCorner(network, env, coordinates) - return EnlargedCorner(Q.C, Q.E_1, Q.E_2, site(network, r, c), Q.dir) + return EnlargedCorner(Q.C, Q.E_1, Q.E_2, getsite(network, r, c), Q.dir) end function eachcoordinate(tensor_unitcell::Array{<:AbstractTensorMap, 3}) @@ -427,7 +427,7 @@ function contract_halfinfinite_characteristic_equation( iCi::CornerTensors, proj_u, proj_v, iSfp::CornerTensors; - site = getindex, + getsite = getindex, ) coordinates = eachcoordinate(n, 1:4) nrows, ncols = size(n) @@ -435,11 +435,11 @@ function contract_halfinfinite_characteristic_equation( # precompute rotated local sandwiches, enlarged corners, and projectors Or = map(coordinates) do co dir, r, c = co - return _rotate_north_localsandwich(site(n, r, c), dir) + return _rotate_north_localsandwich(getsite(n, r, c), dir) end envi = CTMRGEnv(iCi, E) EC = map(coordinates) do co - return TensorMap(_enlarged_corner(n, envi, co; site)) + return TensorMap(_enlarged_corner(n, envi, co; getsite)) end PR = map(coordinates) do co co′ = _proj_sinv_indices(co, nrows, ncols) @@ -514,7 +514,7 @@ end iSfp::CornerTensors, Ufp::LeftProjectors, Vfp::RightProjectors; - site = getindex, + getsite = getindex, ) Takes the fixed-point values of the inverse singular values `iSfp` and the left and right @@ -542,7 +542,7 @@ the approach using implicit null space projectors without materializing `U_{L,fp ``V_{R,fp}``allows for a more efficient evaluation of the characteristic equations themselves. -The local sandwiches are read out of ``n`` through `site`, so a caller can choose whether they +The local sandwiches are read out of ``n`` through `getsite`, so a caller can choose whether they are differentiated at all; see [`PEPSKit.constant_site`](@ref). ``F`` returns a tuple of five tensor arrays, corresponding to equations for ``C``, ``E``, ``u``, ``S`` and @@ -552,7 +552,7 @@ function generate_halfinfinite_characteristic_equation( iSfp::CornerTensors, Ufp::LeftProjectors, Vfp::RightProjectors; - site = getindex, + getsite = getindex, ) iSfp = real.(DiagonalTensorMap.(iSfp)) # use as constant preconditioner? @@ -617,7 +617,7 @@ function generate_halfinfinite_characteristic_equation( iCi, proj_u, proj_v, iSfp; - site, + getsite, ) return F1, F2, F3, F4, F5 diff --git a/src/algorithms/optimization/implicit_differentiation.jl b/src/algorithms/optimization/implicit_differentiation.jl index aee57f111..ac8e87990 100644 --- a/src/algorithms/optimization/implicit_differentiation.jl +++ b/src/algorithms/optimization/implicit_differentiation.jl @@ -506,7 +506,7 @@ function _rrule( # pullback runs once, after the solve, and gets its own tape. F_tracked = generate_symmetric_characteristic_equation(C, E, U, UL) F_untracked = generate_symmetric_characteristic_equation( - C, E, U, UL; site = constant_site + C, E, U, UL; getsite = constant_site ) network = InfiniteSquareNetwork(state) @@ -655,7 +655,7 @@ function PEPSKit._rrule( # state pullback runs once, after the solve, and gets its own tape. F_tracked = generate_halfinfinite_characteristic_equation(is, U, V) F_untracked = generate_halfinfinite_characteristic_equation( - is, U, V; site = constant_site + is, U, V; getsite = constant_site ) network = InfiniteSquareNetwork(state)