Skip to content

Refactor expectation_value implementations - #423

Merged
leburgel merged 35 commits into
mainfrom
lb/expval
Sep 21, 2026
Merged

leburgel merged 35 commits into
mainfrom
lb/expval

Conversation

@leburgel

@leburgel leburgel commented Aug 31, 2026 •

Copy link
Copy Markdown
Member

Some refactoring and reorganization related to the evaluation of expectation values. The main motivation for this refactor is making it easier to add support for computing expectation values of different kinds of operators, and evaluate these using different kinds of environments. Some examples of this are given in #425 and #426, which are built on top of this refactor.

Short summary:

  • Moved around some existing code to different/new files, hopefully improving the organization a bit.
  • Remove as many type annotations as possible from the methods used along the evaluation of expectation values, allowing to reuse the main entry points for different types of operators and environments.
  • Insert a dedicated local_expectation_value method to catch local expectation values for different kinds of operators. This goes through the reduced_densitymatrix approach for AbstractTensorMap local terms, but can follow a different path for different kinds of local terms (see for example [WIP] Add support for local expectation values of tensor product and MPO terms #425).
  • Implement BPEnv expectation values via reduced density matrix contraction along the generic AbstractTensorMap path, by specializing the appropriate methods.
  • Write the main local patch contraction as generic methods in terms of a fixed set of contraction expression generators . These generators then dispatch on the appropriate type to generate an appropriate expression. The idea would be that to add support support for a different type of state, operator or environment, we now only need to overload one of the main expression generators boundary_contraction_expr, bulk_contraction_expr or operator_contraction_expr.

@codecov

codecov Bot commented Aug 31, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.56448% with 47 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/algorithms/contractions/ctmrg/network_value.jl 73.58% 14 Missing ⚠️
.../algorithms/contractions/local_patch/expr_utils.jl 58.82% 7 Missing ⚠️
src/algorithms/expectation_value/network_value.jl 53.33% 7 Missing ⚠️
src/algorithms/contractions/absorb.jl 68.75% 5 Missing ⚠️
src/algorithms/contractions/bp_messages.jl 80.00% 4 Missing ⚠️
...ithms/contractions/local_patch/densitymatrix/bp.jl 91.42% 3 Missing ⚠️
...lgorithms/contractions/local_patch/network_expr.jl 96.38% 3 Missing ⚠️
.../algorithms/expectation_value/expectation_value.jl 90.47% 2 Missing ⚠️
src/algorithms/optimization/peps_optimization.jl 83.33% 1 Missing ⚠️
src/utility/contraction_labels.jl 80.00% 1 Missing ⚠️
Files with missing lines Coverage Δ
...hms/contractions/ctmrg/characteristic_equations.jl 93.33% <ø> (+0.81%) ⬆️
...ms/contractions/local_patch/densitymatrix/ctmrg.jl 100.00% <100.00%> (ø)
.../contractions/local_patch/densitymatrix/generic.jl 100.00% <100.00%> (ø)
...hms/contractions/local_patch/patch_contractions.jl 100.00% <100.00%> (ø)
...lgorithms/expectation_value/correlator_adapters.jl 84.61% <ø> (ø)
src/algorithms/expectation_value/correlators.jl 100.00% <ø> (ø)
...algorithms/expectation_value/patch_contractions.jl 100.00% <100.00%> (ø)
...orithms/expectation_value/reduced_densitymatrix.jl 100.00% <100.00%> (ø)
src/algorithms/toolbox.jl 84.00% <ø> (-2.16%) ⬇️
src/utility/tensor_traces.jl 100.00% <100.00%> (ø)
... and 11 more

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@leburgel
leburgel marked this pull request as draft August 31, 2026 14:18
@leburgel leburgel changed the title Slight reorganization of expectation_value implementation Refactor expectation_value implementations Sep 2, 2026
@leburgel
leburgel marked this pull request as ready for review September 3, 2026 06:55
@Yue-Zhengyuan

Copy link
Copy Markdown
Member

I'll try coming up with a source tree of expectation-value-related functions to better discuss where each function should be placed.

@Yue-Zhengyuan Yue-Zhengyuan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First-round comments focusing on docstring inconsistencies.

Comment thread src/utility/util.jl Outdated
Comment thread src/utility/util.jl Outdated
Comment thread src/algorithms/contractions/localoperator.jl Outdated
Comment thread src/algorithms/expectation_value.jl Outdated
Comment thread src/algorithms/expectation_value.jl Outdated
Comment thread src/algorithms/expectation_value.jl Outdated
Comment thread src/algorithms/expectation_value.jl Outdated
Comment thread src/algorithms/expectation_value.jl Outdated
Comment thread src/algorithms/expectation_value.jl Outdated
Comment thread src/algorithms/expectation_value.jl Outdated
Comment thread src/algorithms/contractions/localoperator.jl Outdated
@Yue-Zhengyuan

Yue-Zhengyuan commented Sep 4, 2026 •

Copy link
Copy Markdown
Member

Some files put too many things together in my opinion. I would like to suggest the following source tree:

Details
src/
└── algorithms/
    ├── expectation_value.jl
    │   ├── local_expectation_value(inds, bra, operator::AbstractTensorMap, ket, env)
    │   │   local_expectation_value(inds, state, operator::AbstractTensorMap, env)
    │   │   Select the evaluation strategy by operator type; evaluate the current dense-operator implementation through a reduced density matrix.
    │   │
    │   └── MPSKit.expectation_value(bra::S, O::LocalOperator, ket::S, env) where {S<:InfiniteState}
    │       MPSKit.expectation_value(peps::InfinitePEPS, O::LocalOperator, env)
    │       MPSKit.expectation_value(state::InfinitePEPO, O::LocalOperator, env)
    │       MPSKit.expectation_value(pf::InfinitePartitionFunction, op::Pair{CartesianIndex{2},<:AbstractTensorMap{T,S,2,2}}, env) where {T,S}
    │       MPSKit.expectation_value(pf::InfinitePartitionFunction, op::Pair{Tuple{Int,Int}}, env)
    │       Delegate each LocalOperator term to local_expectation_value and sum the results, or evaluate a local tensor insertion in a partition function.
    │
    ├── reduced_densitymatrix.jl
    │   └── reduced_densitymatrix(inds::Vector{CartesianIndex{2}}, ket::InfinitePEPS, bra::InfinitePEPS, env)
    │       reduced_densitymatrix(inds, ket::InfinitePEPS, env)
    │       reduced_densitymatrix(inds::Vector{CartesianIndex{2}}, state::InfinitePEPO, env)
    │       reduced_densitymatrix(inds::Vector{CartesianIndex{2}}, ket::InfinitePEPO, bra::InfinitePEPO, env)
    │       reduced_densitymatrix(inds::NTuple{N,CartesianIndex{2}}, args...) where {N} [deprecated]
    │       reduced_densitymatrix(inds::NTuple{N,Tuple{Int,Int}}, args...) where {N} [deprecated]
    │       Select an optimized density-matrix contraction when available, otherwise construct a normalized density matrix with _contract_densitymatrix.
    │
    ├── contractions/
    │   ├── tensor_traces.jl
    │   │   ├── _str(::Bosonic, t::AbstractTensorMap)
    │   │   │   _str(::Fermionic, t::AbstractTensorMap{<:Any,<:Any,N,N}) where {N}
    │   │   │   Dispatch the trace calculation on bosonic or fermionic braiding style.
    │   │   │
    │   │   ├── str(t::AbstractTensorMap)
    │   │   │   Compute the ordinary trace for bosonic tensors and the supertrace for fermionic tensors.
    │   │   │
    │   │   └── trmul(H::AbstractTensorMap{<:Any,S,N,N}, ρ::AbstractTensorMap{<:Any,S,N,N}) where {S,N}
    │   │       Contract an operator with a density matrix without materializing their product.
    │   │
    │   ├── absorb.jl
    │   │   ├── absorb_left(A::AbstractTensorMap{<:Any,S}, C::AbstractTensorMap{<:Any,S,1,1}) where {S}
    │   │   │   absorb_left(P::AbstractTensorMap{<:Any,S,1,N}, C::AbstractTensorMap{<:Any,S,1,1}) where {S,N}
    │   │   │   Contract a matrix into the leftmost leg of a tensor.
    │   │   │
    │   │   ├── absorb_right(A::AbstractTensorMap{<:Any,S}, C::AbstractTensorMap{<:Any,S,1,1}) where {S}
    │   │   │   absorb_right(E::AbstractTensorMap{<:Any,S,N,1}, C::AbstractTensorMap{<:Any,S,1,1}) where {S,N}
    │   │   │   Contract a matrix into the rightmost leg of a tensor.
    │   │   │
    │   │   └── absorb_left_right(T::AbstractTensorMap{<:Any,S}, CL::AbstractTensorMap{<:Any,S,1,1}, CR::AbstractTensorMap{<:Any,S,1,1}) where {S}
    │   │       Contract matrices into both outer legs of a tensor.
    │   │
    │   ├── bp_messages.jl
    │   │   ├── absorb_north_message(A::PEPSTensor, M::PEPSMessage)
    │   │   │   Absorb a north BP message into a PEPS tensor.
    │   │   │
    │   │   ├── absorb_east_message(A::PEPSTensor, M::PEPSMessage)
    │   │   │   Absorb an east BP message into a PEPS tensor.
    │   │   │
    │   │   ├── absorb_south_message(A::PEPSTensor, M::PEPSMessage)
    │   │   │   Absorb a south BP message into a PEPS tensor.
    │   │   │
    │   │   ├── absorb_west_message(A::PEPSTensor, M::PEPSMessage)
    │   │   │   Absorb a west BP message into a PEPS tensor.
    │   │   │
    │   │   ├── contract_north_message(A::PEPSSandwich, M_west::PEPSMessage, M_north::PEPSMessage, M_east::PEPSMessage)
    │   │   │   Update the BP message leaving a site toward the north.
    │   │   │
    │   │   ├── contract_east_message(A::PEPSSandwich, M_north::PEPSMessage, M_east::PEPSMessage, M_south::PEPSMessage)
    │   │   │   Update the BP message leaving a site toward the east.
    │   │   │
    │   │   ├── contract_south_message(A::PEPSSandwich, M_east::PEPSMessage, M_south::PEPSMessage, M_west::PEPSMessage)
    │   │   │   Update the BP message leaving a site toward the south.
    │   │   │
    │   │   └── contract_west_message(A::PEPSSandwich, M_south::PEPSMessage, M_west::PEPSMessage, M_north::PEPSMessage)
    │   │       Update the BP message leaving a site toward the west.
    │   │
    │   ├── local_patch/
    │   │   ├── expr_utils.jl
    │   │   │   ├── tensorlabel(args...)
    │   │   │   │   Join label components into a tensor-contraction symbol.
    │   │   │   │
    │   │   │   ├── envlabel(args...)
    │   │   │   │   Construct an environment-leg label.
    │   │   │   │
    │   │   │   ├── virtuallabel(args...)
    │   │   │   │   Construct a state virtual-leg label.
    │   │   │   │
    │   │   │   ├── physicallabel(args...)
    │   │   │   │   Construct a physical-leg label.
    │   │   │   │
    │   │   │   ├── _open_slot(open, r, c)
    │   │   │   │   Return the operator slot assigned to a patch site.
    │   │   │   │
    │   │   │   ├── _bulk_virtuallabels(i, j, layer, gridsize)
    │   │   │   │   Return the north, east, south, and west labels of one bulk tensor.
    │   │   │   │
    │   │   │   ├── _patch_inds(inds::Type)
    │   │   │   │   _patch_inds(inds::Tuple{Vararg{Val}})
    │   │   │   │   Recover and validate patch coordinates encoded in Val parameters.
    │   │   │   │
    │   │   │   ├── _patch_ranges(sites)
    │   │   │   │   Return the row and column ranges spanned by patch sites.
    │   │   │   │
    │   │   │   ├── _patch_gridsize(sites)
    │   │   │   │   Return the rectangular dimensions spanned by patch sites.
    │   │   │   │
    │   │   │   └── _patch_shape_string(sites)
    │   │   │       Format the rectangular patch dimensions for diagnostics.
    │   │   │
    │   │   ├── network_expr.jl
    │   │   │   ├── contractcheck(state::Type)
    │   │   │   │   contractcheck(::Type{<:InfinitePEPO})
    │   │   │   │   contractcheck(::Type{<:Tuple{Vararg{InfinitePEPO}}})
    │   │   │   │   Select whether tensor-space compatibility is checked for a state representation.
    │   │   │   │
    │   │   │   ├── _tensor_expr(prod, lhs, check::Bool)
    │   │   │   │   Assemble indexed tensor expressions into an optimized `@tensor` contraction.
    │   │   │   │
    │   │   │   ├── boundary_contraction_expr(env::Type, rowrange, colrange)
    │   │   │   │   boundary_contraction_expr(::Type{<:CTMRGEnv{C,T}}, rowrange, colrange) where {C,T}
    │   │   │   │   Generate indexed CTMRG boundary tensor expressions for an `@tensor` contraction, or report that an environment implementation is unavailable.
    │   │   │   │
    │   │   │   ├── bulk_contraction_expr(state::Type, rowrange, colrange, open)
    │   │   │   │   bulk_contraction_expr(::Type{<:Tuple{InfinitePEPS,InfinitePEPS}}, rowrange, colrange, open)
    │   │   │   │   bulk_contraction_expr(::Type{<:InfinitePEPO}, rowrange, colrange, open)
    │   │   │   │   bulk_contraction_expr(::Type{<:Tuple{InfinitePEPO,InfinitePEPO}}, rowrange, colrange, open)
    │   │   │   │   bulk_contraction_expr(state::Type{<:Tuple{Vararg{InfinitePEPO}}}, rowrange, colrange, open)
    │   │   │   │   Generate indexed PEPS or PEPO tensor expressions for the patch interior, or report that a state implementation is unavailable.
    │   │   │   │
    │   │   │   └── operator_contraction_expr(operator::Type, nsites)
    │   │   │       operator_contraction_expr(::Type{<:AbstractTensorMap}, nsites)
    │   │   │       Generate an indexed dense-operator expression for an `@tensor` contraction, or report that an operator implementation is unavailable.
    │   │   │
    │   │   ├── patch_contractions.jl
    │   │   │   ├── _contract_local_operator(inds::NTuple{N,Val}, operator, state, env) where {N}
    │   │   │   │   Assemble and execute the unnormalized operator-inserted patch contraction for direct evaluation.
    │   │   │   │
    │   │   │   ├── contract_local_operator(inds::Vector{CartesianIndex{2}}, O, ket::InfinitePEPS, bra::InfinitePEPS, env)
    │   │   │   │   contract_local_operator(inds::Vector{CartesianIndex{2}}, O, state::InfinitePEPO, env)
    │   │   │   │   contract_local_operator(inds::Vector{CartesianIndex{2}}, O, ket::InfinitePEPO, bra::InfinitePEPO, env)
    │   │   │   │   contract_local_operator(inds::Vector{Tuple{Int,Int}}, O, args...)
    │   │   │   │   contract_local_operator(inds::NTuple, args...) [deprecated]
    │   │   │   │   Validate the inputs and invoke the generated direct contraction for an operator insertion.
    │   │   │   │
    │   │   │   ├── _contract_local_norm(inds::NTuple{N,Val}, state, env) where {N}
    │   │   │   │   Assemble and execute the corresponding patch-normalization contraction with closed physical legs.
    │   │   │   │
    │   │   │   └── contract_local_norm(inds::Vector{CartesianIndex{2}}, ket::InfinitePEPS, bra::InfinitePEPS, env)
    │   │   │       contract_local_norm(inds::Vector{CartesianIndex{2}}, state::InfinitePEPO, env)
    │   │   │       contract_local_norm(inds::Vector{CartesianIndex{2}}, ket::InfinitePEPO, bra::InfinitePEPO, env)
    │   │   │       contract_local_norm(inds::Vector{Tuple{Int,Int}}, args...)
    │   │   │       contract_local_norm(inds::NTuple, ket::InfinitePEPS, bra::InfinitePEPS, env) [deprecated]
    │   │   │       Validate the inputs and invoke the generated direct contraction used to normalize an operator insertion.
    │   │   │
    │   │   └── densitymatrix/
    │   │       ├── generic.jl
    │   │       │   └── _contract_densitymatrix(inds::NTuple{N,Val}, state, env) where {N}
    │   │       │       Assemble and execute a generated patch contraction with open physical legs.
    │   │       │
    │   │       ├── ctmrg.jl
    │   │       │   ├── reduced_densitymatrix1x1(ind::CartesianIndex{2}, ket::InfinitePEPS, bra::InfinitePEPS, env::CTMRGEnv)
    │   │       │   │   Contract an optimized one-site PEPS density matrix using a CTMRG environment.
    │   │       │   │
    │   │       │   ├── reduced_densitymatrix2x1(ind::CartesianIndex, ket::InfinitePEPS, bra::InfinitePEPS, env::CTMRGEnv)
    │   │       │   │   Contract an optimized vertical two-site PEPS density matrix using a CTMRG environment.
    │   │       │   │
    │   │       │   └── reduced_densitymatrix1x2(ind::CartesianIndex, ket::InfinitePEPS, bra::InfinitePEPS, env::CTMRGEnv)
    │   │       │       Contract an optimized horizontal two-site PEPS density matrix using a CTMRG environment.
    │   │       │
    │   │       └── bp.jl
    │   │           ├── _contract_densitymatrix(inds::NTuple{N,Val}, state, env::BPEnv) where {N}
    │   │           │   Reject patch geometries that cannot be represented by local BP messages.
    │   │           │
    │   │           ├── reduced_densitymatrix1x1(ind::CartesianIndex{2}, ket::InfinitePEPS, bra::InfinitePEPS, env::BPEnv)
    │   │           │   Contract a one-site PEPS density matrix using BP messages.
    │   │           │
    │   │           ├── reduced_densitymatrix2x1(coord::CartesianIndex{2}, ket::InfinitePEPS, bra::InfinitePEPS, env::BPEnv)
    │   │           │   Contract a vertical two-site PEPS density matrix using BP messages.
    │   │           │
    │   │           └── reduced_densitymatrix1x2(coord::CartesianIndex{2}, ket::InfinitePEPS, bra::InfinitePEPS, env::BPEnv)
    │   │               Contract a horizontal two-site PEPS density matrix using BP messages.
    │   │
    │   └── ctmrg/
    │       └── network_value.jl
    │           ├── _contract_site(ind::Tuple{Int,Int}, network, env::CTMRGEnv)
    │           │   _contract_site(C_northwest, C_northeast, C_southeast, C_southwest, E_north::CTMRG_PEPS_EdgeTensor, E_east::CTMRG_PEPS_EdgeTensor, E_south::CTMRG_PEPS_EdgeTensor, E_west::CTMRG_PEPS_EdgeTensor, O::PEPSSandwich)
    │           │   _contract_site(C_northwest, C_northeast, C_southeast, C_southwest, E_north::CTMRG_PF_EdgeTensor, E_east::CTMRG_PF_EdgeTensor, E_south::CTMRG_PF_EdgeTensor, E_west::CTMRG_PF_EdgeTensor, O::PFTensor)
    │           │   _contract_site(C_northwest, C_northeast, C_southeast, C_southwest, E_north::TE, E_east::TE, E_south::TE, E_west::TE, O::PEPOSandwich{H}) where {TE<:CTMRGEdgeTensor,H}
    │           │   Contract one network site with its surrounding CTMRG corners and edges.
    │           │
    │           ├── _contract_corners(ind::Tuple{Int,Int}, env::CTMRGEnv)
    │           │   _contract_corners(C_northwest::CTMRGCornerTensor, C_northeast::CTMRGCornerTensor, C_southeast::CTMRGCornerTensor, C_southwest::CTMRGCornerTensor)
    │           │   Contract four CTMRG corners for network-value normalization.
    │           │
    │           ├── _contract_vertical_edges(ind::Tuple{Int,Int}, env::CTMRGEnv)
    │           │   _contract_vertical_edges(C_northwest::CTMRGCornerTensor, C_northeast::CTMRGCornerTensor, C_southeast::CTMRGCornerTensor, C_southwest::CTMRGCornerTensor, E_east::CTMRGEdgeTensor{T,S,N}, E_west::CTMRGEdgeTensor{T,S,N}) where {T,S,N}
    │           │   Contract two vertical edges and four corners for network-value normalization.
    │           │
    │           ├── _contract_horizontal_edges(ind::Tuple{Int,Int}, env::CTMRGEnv)
    │           │   _contract_horizontal_edges(C_northwest::CTMRGCornerTensor, C_northeast::CTMRGCornerTensor, C_southeast::CTMRGCornerTensor, C_southwest::CTMRGCornerTensor, E_north::CTMRGEdgeTensor{T,S,N}, E_south::CTMRGEdgeTensor{T,S,N}) where {T,S,N}
    │           │   Contract two horizontal edges and four corners for network-value normalization.
    │           │
    │           ├── network_value(network::InfiniteSquareNetwork, env::CTMRGEnv)
    │           │   network_value(state, env::CTMRGEnv)
    │           │   Evaluate the normalized value per unit cell of an infinite square network.
    │           │
    │           └── LinearAlgebra.norm(peps::InfinitePEPS, env::CTMRGEnv)
    │               Evaluate the CTMRG norm of an infinite PEPS.
    │
    └── optimization/
        └── peps_optimization.jl
            └── cost_function(peps::InfinitePEPS, env, O::LocalOperator)
                Return the real part of an expectation value as the PEPS optimization cost.

Comment thread src/algorithms/contractions/bp_contractions.jl Outdated
Comment thread src/algorithms/contractions/localoperator.jl Outdated
@leburgel

Copy link
Copy Markdown
Member Author

Some files put too many things together in my opinion. I would like to suggest the following source tree:
...

I did the reorganization mostly as suggested:

Updated file tree
src/
├── algorithms/
│   ├── expectation_value/
│   │   ├── expectation_value.jl
│   │   │   ├── local_expectation_value(inds, bra, operator::AbstractTensorMap, ket, env)
│   │   │   │   local_expectation_value(inds, state, operator::AbstractTensorMap, env)
│   │   │   │   Select the evaluation strategy by operator type; evaluate the current dense-operator implementation through a reduced density matrix.
│   │   │   │
│   │   │   └── MPSKit.expectation_value(bra::S, O::LocalOperator, ket::S, env) where {S<:InfiniteState}
│   │   │       MPSKit.expectation_value(peps::InfinitePEPS, O::LocalOperator, env)
│   │   │       MPSKit.expectation_value(state::InfinitePEPO, O::LocalOperator, env)
│   │   │       MPSKit.expectation_value(pf::InfinitePartitionFunction, op::Pair{CartesianIndex{2},<:AbstractTensorMap{T,S,2,2}}, env) where {T,S}
│   │   │       MPSKit.expectation_value(pf::InfinitePartitionFunction, op::Pair{Tuple{Int,Int}}, env)
│   │   │       Delegate each LocalOperator term to local_expectation_value and sum the results, or evaluate a local tensor insertion in a partition function.
│   │   │
│   │   ├── reduced_densitymatrix.jl
│   │   │   ├── reduced_densitymatrix(inds::Vector{CartesianIndex{2}}, ket::InfinitePEPS, bra::InfinitePEPS, env)
│   │   │   │   reduced_densitymatrix(inds, ket::InfinitePEPS, env)
│   │   │   │   reduced_densitymatrix(inds::Vector{CartesianIndex{2}}, state::InfinitePEPO, env)
│   │   │   │   reduced_densitymatrix(inds::Vector{CartesianIndex{2}}, ket::InfinitePEPO, bra::InfinitePEPO, env)
│   │   │   │   reduced_densitymatrix(inds::NTuple{N,CartesianIndex{2}}, args...) where {N} [deprecated]
│   │   │   │   reduced_densitymatrix(inds::NTuple{N,Tuple{Int,Int}}, args...) where {N} [deprecated]
│   │   │   │   Select an optimized density-matrix contraction when available, otherwise construct a normalized density matrix with _contract_densitymatrix.
│   │   │   │
│   │   │   ├── reduced_densitymatrix1x1(ind, ket, bra, env)
│   │   │   │   Construct the reduced density matrix of `|ket⟩⟨bra|` on the single site `ind` using an optimized contraction for the environment `env`; the CTMRG and BP implementations live in contractions/local_patch/densitymatrix/.
│   │   │   │
│   │   │   ├── reduced_densitymatrix2x1(ind, ket, bra, env)
│   │   │   │   Construct the reduced density matrix of `|ket⟩⟨bra|` on the vertical pair of sites starting at `ind` using an optimized contraction for the environment `env`; the CTMRG and BP implementations live in contractions/local_patch/densitymatrix/.
│   │   │   │
│   │   │   └── reduced_densitymatrix1x2(ind, ket, bra, env)
│   │   │       Construct the reduced density matrix of `|ket⟩⟨bra|` on the horizontal pair of sites starting at `ind` using an optimized contraction for the environment `env`; the CTMRG and BP implementations live in contractions/local_patch/densitymatrix/.
│   │   │
│   │   ├── patch_contractions.jl
│   │   │   ├── contract_local_operator(inds::Vector{CartesianIndex{2}}, O, ket::InfinitePEPS, bra::InfinitePEPS, env)
│   │   │   │   contract_local_operator(inds::Vector{CartesianIndex{2}}, O, state::InfinitePEPO, env)
│   │   │   │   contract_local_operator(inds::Vector{CartesianIndex{2}}, O, ket::InfinitePEPO, bra::InfinitePEPO, env)
│   │   │   │   contract_local_operator(inds::Vector{Tuple{Int,Int}}, O, args...)
│   │   │   │   contract_local_operator(inds::NTuple, args...) [deprecated]
│   │   │   │   Validate the inputs and invoke the generated direct contraction for an operator insertion.
│   │   │   │
│   │   │   └── contract_local_norm(inds::Vector{CartesianIndex{2}}, ket::InfinitePEPS, bra::InfinitePEPS, env)
│   │   │       contract_local_norm(inds::Vector{CartesianIndex{2}}, state::InfinitePEPO, env)
│   │   │       contract_local_norm(inds::Vector{CartesianIndex{2}}, ket::InfinitePEPO, bra::InfinitePEPO, env)
│   │   │       contract_local_norm(inds::Vector{Tuple{Int,Int}}, args...)
│   │   │       contract_local_norm(inds::NTuple, ket::InfinitePEPS, bra::InfinitePEPS, env) [deprecated]
│   │   │       Validate the inputs and invoke the generated direct contraction used to normalize an operator insertion.
│   │   │
│   │   ├── network_value.jl
│   │   │   ├── network_value(network::InfiniteSquareNetwork, env::CTMRGEnv)
│   │   │   │   network_value(state, env::CTMRGEnv)
│   │   │   │   Evaluate the normalized value per unit cell of an infinite square network.
│   │   │   │
│   │   │   ├── LinearAlgebra.norm(peps::InfinitePEPS, env::CTMRGEnv)
│   │   │   │   Evaluate the CTMRG norm of an infinite PEPS.
│   │   │   │
│   │   │   └── contract_local_tensor(inds::Tuple{Int,Int}, O::PFTensor, env::CTMRGEnv{C,<:CTMRG_PF_EdgeTensor}) where {C}
│   │   │       contract_local_tensor(ind::Tuple{Int,Int,Int}, O::PEPOTensor, network::InfiniteSquareNetwork{<:PEPOSandwich}, env::CTMRGEnv)
│   │   │       contract_local_tensor(inds::CartesianIndex, O::AbstractTensorMap, env::CTMRGEnv)
│   │   │       Contract a local tensor inserted into a partition function or into the PEPO of a network, using the surrounding CTMRG environment.
│   │   │
│   │   ├── correlators.jl
│   │   │   ├── const CoordCollection{N} = Union{AbstractVector{CartesianIndex{N}}, CartesianIndices{N}}
│   │   │   │   Accept either a vector of coordinates or a CartesianIndices range as correlator targets.
│   │   │   │
│   │   │   ├── MPSKit.correlator(bra::S, O, i::CartesianIndex{2}, js::CoordCollection{2}, ket::S, env::CTMRGEnv) where {S<:InfiniteState}
│   │   │   │   MPSKit.correlator(bra::S, O, i::CartesianIndex{2}, j::CartesianIndex{2}, ket::S, env::CTMRGEnv) where {S<:InfiniteState}
│   │   │   │   MPSKit.correlator(state::InfinitePEPS, O, i::CartesianIndex{2}, j, env::CTMRGEnv)
│   │   │   │   Build a braket correlator context and delegate to the generic correlator driver.
│   │   │   │
│   │   │   └── MPSKit.correlator(ρ::InfinitePEPO, O, i::CartesianIndex{2}, js::CoordCollection{2}, env::CTMRGEnv)
│   │   │       MPSKit.correlator(ρ::InfinitePEPO, O, i::CartesianIndex{2}, j::CartesianIndex{2}, env::CTMRGEnv)
│   │   │       Build a trace correlator context for a single-layer PEPO and delegate to the same driver.
│   │   │
│   │   └── correlator_adapters.jl
│   │       ├── struct PEPSCorrelator / PEPOPurifiedCorrelator / PEPOTraceCorrelator
│   │       │   const BraketCorrelator = Union{PEPSCorrelator, PEPOPurifiedCorrelator}
│   │       │   _braket_correlator(bra, ket, env::CTMRGEnv)
│   │       │   Bundle the bra, ket and environment into the context the driver dispatches on.
│   │       │
│   │       ├── edge_transfermatrix(row::Int, col::Int, context)
│   │       │   _correlator_scalartype(context, O::FiniteMPO)
│   │       │   _correlator_unitcell(context)
│   │       │   Base.rotl90(context)
│   │       │   Expose the per-context quantities the generic driver needs, including the rotation used for vertical correlators.
│   │       │
│   │       ├── _correlator(context, O, i::CartesianIndex{2}, js::AbstractVector{CartesianIndex{2}})
│   │       │   _correlator_horizontal(context, operator, i, js)
│   │       │   _correlator_vertical(context, operator, i, js)
│   │       │   _check_horizontal_correlator_sites(i, js)
│   │       │   Route a target set to the horizontal or vertical sweep and validate that it forms a single row or column.
│   │       │
│   │       └── _correlator_horizontal_right!(G, targets, context, O::FiniteMPO, i::CartesianIndex{2})
│   │           _correlator_horizontal_left!(G, targets, context, O::FiniteMPO, i::CartesianIndex{2})
│   │           Walk outward from the reference site to each target, reusing the partial contraction as the separation grows.
│   │
│   ├── contractions/
│   │   ├── absorb.jl
│   │   │   ├── absorb_left(A::AbstractTensorMap{<:Any,S}, C::AbstractTensorMap{<:Any,S,1,1}) where {S}
│   │   │   │   absorb_left(P::AbstractTensorMap{<:Any,S,1,N}, C::AbstractTensorMap{<:Any,S,1,1}) where {S,N}
│   │   │   │   Contract a matrix into the leftmost leg of a tensor.
│   │   │   │
│   │   │   ├── absorb_right(A::AbstractTensorMap{<:Any,S}, C::AbstractTensorMap{<:Any,S,1,1}) where {S}
│   │   │   │   absorb_right(E::AbstractTensorMap{<:Any,S,N,1}, C::AbstractTensorMap{<:Any,S,1,1}) where {S,N}
│   │   │   │   Contract a matrix into the rightmost leg of a tensor.
│   │   │   │
│   │   │   └── absorb_left_right(T::AbstractTensorMap{<:Any,S}, CL::AbstractTensorMap{<:Any,S,1,1}, CR::AbstractTensorMap{<:Any,S,1,1}) where {S}
│   │   │       Contract matrices into both outer legs of a tensor.
│   │   │
│   │   ├── bp_messages.jl
│   │   │   ├── const PEPSMessage = AbstractTensorMap{<:Any,<:Any,1,1}
│   │   │   │   Name the one-in one-out tensor carrying a BP message along a bond.
│   │   │   │
│   │   │   ├── absorb_north_message(A::PEPSTensor, M::PEPSMessage)
│   │   │   │   Absorb a north BP message into a PEPS tensor.
│   │   │   │
│   │   │   ├── absorb_east_message(A::PEPSTensor, M::PEPSMessage)
│   │   │   │   Absorb an east BP message into a PEPS tensor.
│   │   │   │
│   │   │   ├── absorb_south_message(A::PEPSTensor, M::PEPSMessage)
│   │   │   │   Absorb a south BP message into a PEPS tensor.
│   │   │   │
│   │   │   ├── absorb_west_message(A::PEPSTensor, M::PEPSMessage)
│   │   │   │   Absorb a west BP message into a PEPS tensor.
│   │   │   │
│   │   │   ├── contract_north_message(A::PEPSSandwich, M_west::PEPSMessage, M_north::PEPSMessage, M_east::PEPSMessage)
│   │   │   │   Update the BP message leaving a site toward the north.
│   │   │   │
│   │   │   ├── contract_east_message(A::PEPSSandwich, M_north::PEPSMessage, M_east::PEPSMessage, M_south::PEPSMessage)
│   │   │   │   Update the BP message leaving a site toward the east.
│   │   │   │
│   │   │   ├── contract_south_message(A::PEPSSandwich, M_east::PEPSMessage, M_south::PEPSMessage, M_west::PEPSMessage)
│   │   │   │   Update the BP message leaving a site toward the south.
│   │   │   │
│   │   │   └── contract_west_message(A::PEPSSandwich, M_south::PEPSMessage, M_west::PEPSMessage, M_north::PEPSMessage)
│   │   │       Update the BP message leaving a site toward the west.
│   │   │
│   │   ├── local_patch/
│   │   │   ├── expr_utils.jl
│   │   │   │   ├── tensorlabel(args...)
│   │   │   │   │   Join label components into a tensor-contraction symbol.
│   │   │   │   │
│   │   │   │   ├── envlabel(args...)
│   │   │   │   │   Construct an environment-leg label.
│   │   │   │   │
│   │   │   │   ├── virtuallabel(args...)
│   │   │   │   │   Construct a state virtual-leg label.
│   │   │   │   │
│   │   │   │   ├── physicallabel(args...)
│   │   │   │   │   Construct a physical-leg label.
│   │   │   │   │
│   │   │   │   ├── _open_slot(open, r, c)
│   │   │   │   │   Return the operator slot assigned to a patch site.
│   │   │   │   │
│   │   │   │   ├── _bulk_virtuallabels(i, j, layer, gridsize)
│   │   │   │   │   Return the north, east, south, and west labels of one bulk tensor.
│   │   │   │   │
│   │   │   │   ├── _patch_inds(inds::Type)
│   │   │   │   │   _patch_inds(inds::Tuple{Vararg{Val}})
│   │   │   │   │   Recover and validate patch coordinates encoded in Val parameters.
│   │   │   │   │
│   │   │   │   ├── _patch_ranges(sites)
│   │   │   │   │   Return the row and column ranges spanned by patch sites.
│   │   │   │   │
│   │   │   │   ├── _patch_gridsize(sites)
│   │   │   │   │   Return the rectangular dimensions spanned by patch sites.
│   │   │   │   │
│   │   │   │   └── _patch_shape_string(sites)
│   │   │   │       Format the rectangular patch dimensions for diagnostics.
│   │   │   │
│   │   │   ├── network_expr.jl
│   │   │   │   ├── _tensor_expr(prod, lhs = nothing)
│   │   │   │   │   Assemble indexed tensor expressions into an optimized `@tensor` contraction.
│   │   │   │   │
│   │   │   │   ├── boundary_contraction_expr(env::Type, rowrange, colrange)
│   │   │   │   │   boundary_contraction_expr(::Type{<:CTMRGEnv{C,T}}, rowrange, colrange) where {C,T}
│   │   │   │   │   Generate indexed CTMRG boundary tensor expressions for an `@tensor` contraction, or report that an environment implementation is unavailable.
│   │   │   │   │
│   │   │   │   ├── bulk_contraction_expr(state::Type, rowrange, colrange, open)
│   │   │   │   │   bulk_contraction_expr(::Type{<:Tuple{InfinitePEPS,InfinitePEPS}}, rowrange, colrange, open)
│   │   │   │   │   bulk_contraction_expr(::Type{<:InfinitePEPO}, rowrange, colrange, open)
│   │   │   │   │   bulk_contraction_expr(::Type{<:Tuple{InfinitePEPO,InfinitePEPO}}, rowrange, colrange, open)
│   │   │   │   │   bulk_contraction_expr(state::Type{<:Tuple{Vararg{InfinitePEPO}}}, rowrange, colrange, open)
│   │   │   │   │   Generate indexed PEPS or PEPO tensor expressions for the patch interior, or report that a state implementation is unavailable.
│   │   │   │   │
│   │   │   │   └── operator_contraction_expr(operator::Type, nsites)
│   │   │   │       operator_contraction_expr(::Type{<:AbstractTensorMap}, nsites)
│   │   │   │       Generate an indexed dense-operator expression for an `@tensor` contraction, or report that an operator implementation is unavailable.
│   │   │   │
│   │   │   ├── patch_contractions.jl
│   │   │   │   ├── _contract_local_operator(inds::NTuple{N,Val}, operator, state, env) where {N}
│   │   │   │   │   Assemble and execute the unnormalized operator-inserted patch contraction for direct evaluation.
│   │   │   │   │
│   │   │   │   └── _contract_local_norm(inds::NTuple{N,Val}, state, env) where {N}
│   │   │   │       Assemble and execute the corresponding patch-normalization contraction with closed physical legs.
│   │   │   │
│   │   │   └── densitymatrix/
│   │   │       ├── generic.jl
│   │   │       │   └── _contract_densitymatrix(inds::NTuple{N,Val}, state, env) where {N}
│   │   │       │       Assemble and execute a generated patch contraction with open physical legs.
│   │   │       │
│   │   │       ├── ctmrg.jl
│   │   │       │   ├── reduced_densitymatrix1x1(ind::CartesianIndex{2}, ket::InfinitePEPS, bra::InfinitePEPS, env::CTMRGEnv)
│   │   │       │   │   Contract an optimized one-site PEPS density matrix using a CTMRG environment.
│   │   │       │   │
│   │   │       │   ├── reduced_densitymatrix2x1(ind::CartesianIndex, ket::InfinitePEPS, bra::InfinitePEPS, env::CTMRGEnv)
│   │   │       │   │   Contract an optimized vertical two-site PEPS density matrix using a CTMRG environment.
│   │   │       │   │
│   │   │       │   └── reduced_densitymatrix1x2(ind::CartesianIndex, ket::InfinitePEPS, bra::InfinitePEPS, env::CTMRGEnv)
│   │   │       │       Contract an optimized horizontal two-site PEPS density matrix using a CTMRG environment.
│   │   │       │
│   │   │       └── bp.jl
│   │   │           ├── _contract_densitymatrix(inds::NTuple{N,Val}, state, env::BPEnv) where {N}
│   │   │           │   Reject patch geometries that cannot be represented by local BP messages.
│   │   │           │
│   │   │           ├── reduced_densitymatrix1x1(ind::CartesianIndex{2}, ket::InfinitePEPS, bra::InfinitePEPS, env::BPEnv)
│   │   │           │   Contract a one-site PEPS density matrix using BP messages.
│   │   │           │
│   │   │           ├── reduced_densitymatrix2x1(coord::CartesianIndex{2}, ket::InfinitePEPS, bra::InfinitePEPS, env::BPEnv)
│   │   │           │   Contract a vertical two-site PEPS density matrix using BP messages.
│   │   │           │
│   │   │           └── reduced_densitymatrix1x2(coord::CartesianIndex{2}, ket::InfinitePEPS, bra::InfinitePEPS, env::BPEnv)
│   │   │               Contract a horizontal two-site PEPS density matrix using BP messages.
│   │   │
│   │   └── ctmrg/
│   │       └── network_value.jl
│   │           ├── _contract_site(ind::Tuple{Int,Int}, network, env::CTMRGEnv)
│   │           │   _contract_site(C_northwest, C_northeast, C_southeast, C_southwest, E_north::CTMRG_PEPS_EdgeTensor, E_east::CTMRG_PEPS_EdgeTensor, E_south::CTMRG_PEPS_EdgeTensor, E_west::CTMRG_PEPS_EdgeTensor, O::PEPSSandwich)
│   │           │   _contract_site(C_northwest, C_northeast, C_southeast, C_southwest, E_north::CTMRG_PF_EdgeTensor, E_east::CTMRG_PF_EdgeTensor, E_south::CTMRG_PF_EdgeTensor, E_west::CTMRG_PF_EdgeTensor, O::PFTensor)
│   │           │   _contract_site(C_northwest, C_northeast, C_southeast, C_southwest, E_north::TE, E_east::TE, E_south::TE, E_west::TE, O::PEPOSandwich{H}) where {TE<:CTMRGEdgeTensor,H}
│   │           │   Contract one network site with its surrounding CTMRG corners and edges.
│   │           │
│   │           ├── _contract_corners(ind::Tuple{Int,Int}, env::CTMRGEnv)
│   │           │   _contract_corners(C_northwest::CTMRGCornerTensor, C_northeast::CTMRGCornerTensor, C_southeast::CTMRGCornerTensor, C_southwest::CTMRGCornerTensor)
│   │           │   Contract four CTMRG corners for network-value normalization.
│   │           │
│   │           ├── _contract_vertical_edges(ind::Tuple{Int,Int}, env::CTMRGEnv)
│   │           │   _contract_vertical_edges(C_northwest::CTMRGCornerTensor, C_northeast::CTMRGCornerTensor, C_southeast::CTMRGCornerTensor, C_southwest::CTMRGCornerTensor, E_east::CTMRGEdgeTensor{T,S,N}, E_west::CTMRGEdgeTensor{T,S,N}) where {T,S,N}
│   │           │   Contract two vertical edges and four corners for network-value normalization.
│   │           │
│   │           └── _contract_horizontal_edges(ind::Tuple{Int,Int}, env::CTMRGEnv)
│   │               _contract_horizontal_edges(C_northwest::CTMRGCornerTensor, C_northeast::CTMRGCornerTensor, C_southeast::CTMRGCornerTensor, C_southwest::CTMRGCornerTensor, E_north::CTMRGEdgeTensor{T,S,N}, E_south::CTMRGEdgeTensor{T,S,N}) where {T,S,N}
│   │               Contract two horizontal edges and four corners for network-value normalization.
│   │
│   └── optimization/
│       └── peps_optimization.jl
│           └── cost_function(peps::InfinitePEPS, env, O::LocalOperator)
│               Return the real part of an expectation value as the PEPS optimization cost.
│
└── utility/
    └── tensor_traces.jl
        ├── _str(::Bosonic, t::AbstractTensorMap)
        │   _str(::Fermionic, t::AbstractTensorMap{<:Any,<:Any,N,N}) where {N}
        │   Dispatch the trace calculation on bosonic or fermionic braiding style.
        │
        ├── str(t::AbstractTensorMap)
        │   Compute the ordinary trace for bosonic tensors and the supertrace for fermionic tensors.
        │
        └── trmul(H::AbstractTensorMap{<:Any,S,N,N}, ρ::AbstractTensorMap{<:Any,S,N,N}) where {S,N}
            Contract an operator with a density matrix without materializing their product.

The only notable differences are that:

  • I added an extra expectation_value folder directly under src/algorithms to collect everything related to expectation values. I also move the correlator code here, since it seemed related enough to put there. I can always revert if we don't want that.
  • I split some more "public" methods from their implementations under src/algorithms/contractions (e.g. contract_local_norm and contract_local_operator, network_value, ...). This felt more appropriate, since src/contractions was originally intended to contain the lowest level contraction methods.

Happy to reorganize further, or more thoroughly if we no longer like the use of the src/algorithms/contractions approach.

@Yue-Zhengyuan Yue-Zhengyuan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some code extensibility issues involving custom environment types discovered by Codex. Again, we need to explain why supertrace instead of trace occurs in expectation values.

I'm in favor of putting the low-level contractions beside the algorithm that uses it, instead of collecting them all together. But this can be deferred to a follow up.

Comment thread src/utility/tensor_traces.jl
Comment thread src/PEPSKit.jl
Comment thread src/algorithms/contractions/local_patch/patch_contractions.jl
Comment thread src/algorithms/contractions/absorb.jl Outdated
Comment thread src/algorithms/expectation_value/reduced_densitymatrix.jl
Comment thread src/algorithms/expectation_value/patch_contractions.jl Outdated
Contract a local norm corresponding to the overlap `ket` and `bra` states, computing a patch
of `⟨bra|ket⟩`, where `ket` and `bra` correspond to either a PEPS or a PEPO representing a
PEPS with ancillary legs.
Alternatively, contract a local norm patch of a density matrix PEPO `state`, computing a patch of `tr(state)`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this back to ordinary trace. The RDM is using str only because we manually added twist on the 2nd codomain index of each iPEPO tensor.

@Yue-Zhengyuan Yue-Zhengyuan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ready for merge after #429 and updating to the new test format.

@leburgel
leburgel merged commit 00ea2d0 into main Sep 21, 2026
73 of 78 checks passed
@leburgel
leburgel deleted the lb/expval branch September 21, 2026 18:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants