Repository navigation
Conversation
Bring the t-J module in line with every other operator module: define the dense reference operators first and obtain the symmetric ones by a basis transformation + projection, generated by `@operator`. Previously all 31 operators were generated by an `@eval` loop that projected the corresponding `HubbardOperators` operator, and their docstrings were scraped from Hubbard and patched by string substitution. - `tj_space` is dispatched on the symmetries, and rejects `SU2Irrep` particle symmetry with a dedicated error (there is no η-pairing doublet without the doubly occupied state). - New `basis_transform(P, S; slave_fermion)`, built generically from the sector order of the target space, which makes `test_operator_dense` available. - The basis choice is a parameter of the reference space, like `spin` in `SpinOperators`: `slave_fermion` is forwarded to both the reference operator and `_symmetrize_operator`, so it also selects the reference dense ordering (the parity flip moves the holon to the back). - The staggered sign of the slave-fermion representation stays inside `transform_slave_fermion`, applied once to the assembled N-site reference; derived operators are built in the plain basis and transformed at the end. - Real docstrings per operator, without the unreachable |↑↓⟩ matrix elements the transplanted Hubbard ones advertised. - Fixes three misaligned aliases of the old positional `zip`: `u⁺u⁺` and `d⁻d⁻` were swapped with `d_min_d_min`/`u_plus_u_plus`, and `S⁺S⁻`/`S⁻S⁺` with each other. - `tj_projector` remains public and now documents the projection relation to `HubbardOperators`, which the tests check. Tests mirror `test/hubbardoperators.jl`: availability predicates, basis transform unitarity and scalar-type preservation, element-wise dense comparison instead of the spectral one, regression values against transposes, the Hubbard projection relation, and the slave-fermion consistency invariant `O(…; slave_fermion = true) ≈ transform_slave_fermion(O(…))`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The chain-spectrum comparisons are largely subsumed by `test_operator_dense`, which compares every operator element-wise per bond and additionally catches transposes and gauge rotations. The analytic exact-diagonalisation testsets are kept as the many-body sanity check. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
@Yue-Zhengyuan, I was planning to tag after this PR, so we can release the new "trivial-to-symmetric" path |
- `tj_projector` referred to the `HubbardOperators` module with `@ref`, which Documenter cannot resolve (modules have no docstring here). - Hoist the `Iterators.product` symmetry loops into named iterators, so the `for ... in` headers fit on one line: the line-range formatting `git runic` applies to a diff disagrees with whole-file formatting on that continuation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
🚀 New features to boost your workflow:
|
Yue-Zhengyuan
left a comment
There was a problem hiding this comment.
I'm strongly against defining the t-J operators from hard-coded dense tensors all over again. I would still use projection from the corresponding Hubbard operators as the definition.
But the dense-conversion can be a good test: we de-symmetrize the symmetric t-J operators, and check that they are the same as the dense non-symmetric one.
|
Oh, no worries, I somehow must have misinterpreted a previous conversation we had and I had it in my head that you wanted something similar to simplify the tests. |
|
I prefer not to change current TJOperator, only adding the basis transformations to enable the dense-symmetric comparison that was not supported before. |
|
Ok in the current version then? This keeps everything defined in terms of Hubbard, but fixes the issues that are listed in the PR description above. I agree the docstrings are a bit annoying, but I also didn't really like that the doubly-occupied state was there in the first place, so this seems like a reasonable inbetween solution |
Yue-Zhengyuan
left a comment
There was a problem hiding this comment.
This is more or less what I want. But I still have some opinions on docstring handling.
The t-J operators are projections of the Hubbard operators of the same name, but their docstrings restated the Hubbard prose in the `_OPERATORS` registry, and the two copies had drifted. Make `HubbardOperators` the single source of truth and inherit the descriptions from its docstrings at load time. The listings of nonzero matrix elements are dropped from both modules: they were the reason the two texts could not be shared, since the projection kills most of the elements. Hubbard absorbs everything else the t-J docstrings had: the "electrons" wording, the symmetry-compatibility remarks and the leg-ordering diagram of the 3-site term. Descriptions are read with `@doc`, which returns the raw docstring on recent Julia versions and a rendered `Markdown.MD` object on 1.10; stringifying the latter reflows the text and writes inline math as `$x$`, which parses the same way. An admonition in a Hubbard operator docstring is Hubbard-specific and is not inherited -- currently only the staggered-gauge note of `e_hopping`, which must stay out of the t-J docs because t-J has no `SU2Irrep` particle symmetry. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
I agree that this duplication is a bit annoying, but there are definitely drawbacks to copying things from the hubbard counterparts. I made an attempt here to do something like you described, let me know what you think. |
Yue-Zhengyuan
left a comment
There was a problem hiding this comment.
_inherit_description is clean enough and much better than repeating the docstrings.
Closes the main part of #45. Both stub pages now follow the structure of the spin operator page: conventions with basis ordering and symmetry sectors, an operator overview table, and the autodocs API section. Since both modules take two independent symmetry arguments, the overview tables carry separate particle and spin columns. This is exact rather than an approximation: every availability predicate in the test suite factorizes into an independent condition per symmetry axis. The basis-ordering sections document the parity-sorted reference order (|0>, |updn>, |up>, |dn> for Hubbard) rather than the enumeration order used in the prose so far, and give a recipe for reading off the dense order of the symmetric spaces instead of tabulating it, since it follows TensorKit's sector sorting and is not part of the interface. The t-J page additionally documents the slave-fermion keyword, including the warning that the transformation does not distribute over tensor products, and the projection relation to the Hubbard model. Upgrade the docstrings of both modules to match: math definitions where they were missing, and an explicit `Compatible symmetries:` line replacing the ad-hoc prose notes. Since #57 made the t-J operator docstrings inherit their description from the Hubbard docstring of the same name, that prose now lives in `HubbardOperators` and reaches `TJOperators` through the inheritance, which imposes two rules on it: - Anything true only of the Hubbard space goes into an admonition, the mechanism #57 already uses to keep the staggered-gauge note out of the t-J docs. That now also covers the listings of nonzero matrix elements, which are basis-specific, and the remarks about `SU2Irrep` particle symmetry, which t-J does not have. The shared prose is worded to hold in both spaces, which is why the eigenvalue listings characterize the states they act on instead of enumerating a fixed basis. - The symmetry line is derived rather than restated. t-J supports exactly the Hubbard combinations minus `SU2Irrep` particle symmetry, because the eta-pairing doublet (|updn>, |0>) loses its doubly occupied state to the projection, so `_project_symmetries` strips that one entry from the inherited line. The spin symmetries carry over verbatim, for all 31 operators of the registry. Along the way: - `HubbardOperators.h_num` is `1 - n`, so it takes the value -1 on the doubly occupied state rather than counting holes as its docstring claimed. Document what it actually does, and point to the t-J module, where it is a genuine projector. - Fix a few typos and an inconsistent float literal. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
) Closes #45. `spinoperators.md` and `quantumgates.md` were full documentation pages; the other four were 9-line bare `@autodocs` stubs. This brings all six to the same structure — Conventions (basis ordering, symmetry sectors), an operator overview table, then the `@autodocs` API section. Since `@autodocs` only renders what the docstrings contain, the docstrings were upgraded in step: math definitions, matrix elements, and an explicit `Supported symmetries:` line where Boson/Fermion had none and Hubbard had only ad-hoc prose. ### Rendered preview Mostly prose, tables and math, so much easier to review rendered than as a diff: | Page | Preview | |---|---| | Boson operators | https://quantumkithub.github.io/TensorKitTensors.jl/previews/PR58/bosonoperators/ | | Fermion operators | https://quantumkithub.github.io/TensorKitTensors.jl/previews/PR58/fermionoperators/ | | Hubbard operators | https://quantumkithub.github.io/TensorKitTensors.jl/previews/PR58/hubbardoperators/ | | t-J operators | https://quantumkithub.github.io/TensorKitTensors.jl/previews/PR58/tjoperators/ | Full preview: https://quantumkithub.github.io/TensorKitTensors.jl/previews/PR58/ ### Notable decisions - **The Hubbard/t-J overview tables use separate particle and spin columns.** Exact, not an approximation: every `has_*(P, S)` predicate in the test suite factorizes into an independent condition per axis. - **The basis-ordering sections document the parity-sorted reference order** — for Hubbard `|0⟩, |↑↓⟩, |↑⟩, |↓⟩`, not the enumeration used so far, which is not an index order anywhere and read as a competing convention against `basis_transform`. - **The dense order of the *symmetric* spaces is a recipe, not a table**, since it follows TensorKit's sector sorting and is not part of the interface; tabulating it could silently desync. - **The t-J page documents `slave_fermion`**, including the warning that `transform_slave_fermion` does not distribute over `⊗`. ### Fitting the t-J docstrings to #57 #57 made each t-J operator docstring inherit its description from the `HubbardOperators` docstring of the same name, so this prose lives in `HubbardOperators` and reaches `TJOperators` through the inheritance. Two rules follow: - **Hubbard-only statements go into admonitions**, the mechanism #57 already uses for the staggered-gauge note. That now also covers the nonzero-matrix-element listings (basis-specific) and the `SU2Irrep`-particle remarks (t-J has no such symmetry). Shared prose is worded to hold in both spaces, so eigenvalue listings characterize the states they act on rather than enumerate a fixed basis. - **The symmetry line is derived, not restated.** t-J supports exactly the Hubbard combinations minus `SU2Irrep` particle symmetry — the η-pairing doublet `(|↑↓⟩, |0⟩)` loses its doubly occupied state to the projection — so `_project_symmetries` strips that entry from the inherited line. Spin symmetries carry over verbatim for all 31 operators. Trade-off worth flagging: per-operator prose true *only* of t-J has no home under this design (that `n` never exceeds one, that `nʰ + n = 1`). Both are stated on the t-J page instead. ### Bugs found along the way - **`HubbardOperators.h_num` did not count holes.** It was `1 - n`, returning `-1` on the doubly occupied state; now `(1 - nꜛ)(1 - nꜜ)`, the projector onto the empty state. Invisible through the t-J projection — the discrepancy lives entirely on `|↑↓⟩`, which the projector removes — so `TJOperators.h_num` agreed either way. Tests now pin down idempotency and `nʰ + n = 1 + nꜛnꜜ`. - **`boson_space(; cutoff)` was a `MethodError`**, unlike every other module's space constructor, while its docstring already advertised the symmetry argument as optional. - **An inherited `@ref` cannot name a Hubbard-only binding.** `h_num`'s `See also ud_num` broke cross-references on the t-J page; it moves into the admonition with the rest of the double-occupancy caveat. ### Also `Documenter` compat bumped to `1.9`, which introduced `checkdocs = :public` (on 1.8.x the symbol is unvalidated and silently disables the check). `operatorpages` puts Hubbard before t-J, since the t-J page refers to it several times. Harmonized on `Supported symmetries` package-wide. Assorted typos, and `T` → `elt` in `FermionOperators` for consistency. ### Verification - Full test suite passes: 2387 tests. Runic clean, docs build clean. - **855 symmetry combinations checked against the overview tables, 0 mismatches** — tables parsed out of the markdown, every listed combination asserted to construct and every unlisted one to throw, across both t-J bases. - All 31 generated t-J docstrings audited: no Hubbard-only text inherited, every symmetry line correct. - 440 math expressions validated against KaTeX — Documenter renders math client-side, so a glyph with no font metrics gives a clean build and a blank on the page. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: Yue Zhengyuan <yuezy1997@icloud.com>
Brings
TJOperatorsin line with every other operator module: dense reference operators defined first, symmetric ones obtained by basis transformation + projection through@operator. Previously all 31 operators were generated by an@evalloop projecting theHubbardOperatorscounterparts, with docstrings scraped from Hubbard and patched by string substitution.The two bases
slave_fermionis a parameter of the reference space, likespininSpinOperators:@operatorforwards keywords to the reference method as well as to the hook, and(Trivial, Trivial)never reaches_symmetrize_operator, so the reference has to return the operator in the requested basis. Flipping the parity also reorders the reference dense basis (|0⟩, |↑⟩, |↓⟩→|↑⟩, |↓⟩, |0⟩), sobasis_transformtakesslave_fermiontoo. It comes out a pure integer permutation in both bases; the staggered sign of the slave-fermion representation stays insidetransform_slave_fermion, applied once to the assembled N-site reference.Other changes
tj_spaceis dispatched on the symmetries and rejectsSU2Irrepparticle symmetry with a dedicated error (no η-pairing doublet without|↑↓⟩).|↑↓⟩matrix elements the transplanted ones advertised.zip:u⁺u⁺/d⁻d⁻were swapped withd_min_d_min/u_plus_u_plus, andS⁺S⁻/S⁻S⁺with each other.tj_projectorstays public and documents the projection relation toHubbardOperators, which the tests now check.test/hubbardoperators.jl: availability predicates, basis-transform unitarity and scalar-type preservation,test_operator_denseinstead of the spectral comparison, transpose-regression values, the Hubbard projection relation, and the invariantO(…; slave_fermion = true) ≈ transform_slave_fermion(O(…)).spectrumtestsets (t-J and Hubbard), subsumed by the element-wise comparison; the analytic ED testsets are kept.Verified against the pre-refactor implementation: all 31 operators match element-wise for the 6 symmetry combinations × both bases. Full suite green.
🤖 Generated with Claude Code