# Non-Abelian DMRG Design Notes
This note records the implementation direction for the SU(2)-adapted DMRG
prototype in `pyqed.mps.nonabelian` and `pyqed.qchem.dmrg`. The immediate goal
is a reduced spatial-orbital quantum-chemistry DMRG path that keeps SU(2)
Wigner-Eckart structure in the tensors and MPO virtual channels instead of
expanding every spin component.
## Reference Implementations
### TensorKit.jl and MPSKit.jl
TensorKit.jl is the closest architectural reference for the tensor core. It
represents non-Abelian vector spaces, fusion trees, reduced tensor blocks, and
symmetry-aware tensor factorizations as first-class objects. MPSKit.jl builds
MPS algorithms on top of those tensors.
Implementation lessons for pyqed:
- Keep reduced tensor data separate from Clebsch-Gordan/fusion metadata.
- Track fusion trees explicitly instead of relying on implicit dense axes.
- Make SVD/canonicalization operate on reduced block sectors and preserve
multiplet degeneracies.
- Treat recoupling as a tensor-layout operation, not as ad-hoc reshaping.
Key references:
- J. Haegeman, J.utho et al., TensorKit.jl documentation,
https://quantumkithub.github.io/TensorKit.jl/stable/
- MPSKit.jl documentation,
https://quantumkithub.github.io/MPSKit.jl/stable/
### block2
block2 is the closest reference for the quantum-chemistry Hamiltonian MPO. It
does not build the SU(2) quantum-chemistry MPO by enumerating all spin-orbital
strings. It uses spin-adapted irreducible operators and complementary
operators on the MPO virtual bonds.
The relevant operator families are:
- one-index doublet channels such as `S_i` and `R_i`
- pair channels such as `A_ij` and `P_ij` in rank-0 and rank-1 sectors
- particle-hole channels such as `B_ij`, `Q_ij`, and related rank-0/rank-1
channels
- scalar channels for `H` and `I`
Implementation lessons for pyqed:
- The current `AutoMPO.add_reduced_string(...)` primitive is useful for testing
Wigner-Eckart recoupling, but a production QC MPO should group ERI
contractions into complementary operators.
- MPO virtual channels should carry operator families and SU(2) ranks, not one
independent channel per four-fermion integral.
- Spin-summed one-body terms should be represented as scalar-coupled
`a^\dagger x a` with the correct `sqrt(2)` normalization.
- Two-body terms should use rank-0/rank-1 pair and particle-hole intermediates
with the same normalization conventions as the documented block2 formulas.
Key references:
- block2 SU(2) Hamiltonian theory,
https://block2.readthedocs.io/en/latest/theory/su2.html
- block2 quantum-chemistry Hamiltonian tutorial,
https://block2.readthedocs.io/en/latest/tutorial/qc-hamiltonians.html
### CheMPS2
CheMPS2 is an older spin-adapted quantum-chemistry DMRG code. Its structure is
less general than TensorKit/MPSKit, but it is useful as a second reference for
spin-adapted complementary-operator Hamiltonian construction, CAS integration,
and reduced density matrix interfaces.
Implementation lessons for pyqed:
- Keep a clear quantum-chemistry layer above the tensor algebra layer.
- Reuse complementary operators across sweeps instead of rebuilding full local
Hamiltonians from raw ERIs.
- Design RDM and CASCI/CASSCF integration around spatial orbitals and target
total spin.
Key references:
- S. Wouters et al., CheMPS2: a free open-source spin-adapted implementation of
the density matrix renormalization group for ab initio quantum chemistry,
Computer Physics Communications 185, 1501-1514 (2014).
- CheMPS2 repository, https://github.com/SebWouters/CheMPS2
### TeNPy
TeNPy is a useful reference for symbolic MPO graph construction and automatic
Jordan-Wigner string handling, but not for SU(2)-reduced Wigner-Eckart tensors.
Its public tensor machinery is based on Abelian charge sectors rather than full
non-Abelian SU(2) fusion trees.
Implementation lessons for pyqed:
- A graph-based MPO builder is useful for compressing symbolic product terms.
- Automatic Jordan-Wigner handling should live in the model/builder layer.
- TeNPy is not the model to follow for non-Abelian reduced tensor storage.
Key references:
- TeNPy model documentation,
https://tenpy.readthedocs.io/en/stable/reference/tenpy.models.model.CouplingModel.html
- TeNPy MPO model documentation,
https://tenpy.readthedocs.io/en/v1.0.3/reference/tenpy.models.model.CouplingMPOModel.html
## Current pyqed Status
Implemented pieces:
- `ReducedTensorOperator` for local irreducible spatial-orbital fermion tensors.
- `RankCoupledMPO` virtual channels with optional Clebsch-Gordan recoupling.
- `AutoMPO.add_reduced_string(...)` for explicit Wigner-Eckart coupled strings.
- A general spin-free qchem two-body reduced-MPO builder that lowers ERI terms
to scalar-coupled reduced operators without the old dense symbolic fallback
for the covered spatial-orbital paths.
- Canonical SU(2) qchem sweeps that keep mixed-canonical MPS gauges, use
matrix-free reduced packed/rank-coupled matvecs, and use reduced local block
preconditioners for both ground-state and state-averaged local Davidson
solves.
- State-averaged SU(2) qchem sweeps that enforce the target spin sector inside
the local block Davidson/projector path instead of relying on final
`<S^2>` filtering or dense target-sector fallback.
Known limitations:
- The reduced qchem MPO is still a scalar-coupled term builder, not a full
block2-style complementary-operator MPO with persistent `S/R/A/P/B/Q`
virtual families.
- The transformed coupled local preconditioner is matrix-free and lazy, but its
self-blocks are still built by probing packed matvecs. A compiled reduced
block kernel would be faster.
- The reduced SVD/canonicalization layer has explicit `TwoSiteBasis` metadata,
but it is not yet a TensorKit-style fusion-tree object model throughout all
tensor factorizations.
## Recommended Next Steps
1. Promote all qchem one-body and two-body scalar-coupled terms to a single
documented Wigner-Eckart normalization table shared by the builder and tests.
2. Add persistent rank-0/rank-1 local pair and particle-hole operator families.
3. Build block2-style complementary operator families `S/R/A/P/B/Q` from `h1e`
and `eri`, then use those families as MPO virtual channels.
4. Replace remaining per-integral four-operator string lowering with those
complementary operators.
5. Move fully reduced SVD/canonicalization toward TensorKit-style explicit
fusion-tree metadata across all decomposition/canonicalization code paths.
6. Move hot packed matvec, projected preconditioner, and reduced SVD kernels
out of Python loops into vectorized or compiled block kernels.