Skip to content

docs: Diátaxis restructure — tutorials, how-to guides, concepts, library reference - #449

Draft
lkdvos wants to merge 8 commits into
docs/examples-regroupfrom
docs/content-wave1
Draft

docs: Diátaxis restructure — tutorials, how-to guides, concepts, library reference#449
lkdvos wants to merge 8 commits into
docs/examples-regroupfrom
docs/content-wave1

Conversation

@lkdvos

@lkdvos lkdvos commented Jul 3, 2026

Copy link
Copy Markdown
Member

Restructures the documentation along Diátaxis lines: a sequential tutorial track, task-recipe how-to guides, prose concept pages, and a topic-split library reference, replacing the man/ section that mixed all four on the same page. Also rewrites the landing page.

Stacked on #500 (base is docs/examples-regroup), so the diff above shows only this PR's own changes. The landing page and the symmetry tutorial link to the regrouped example paths and to the examples_index anchor that #500 introduces, so #500 merges first; GitHub retargets this to main automatically when it does.

Everything mechanical has been split out of this PR so what remains is the prose that actually needs reading: #497 (VitePress config), #499 (contributing guide), #500 (examples regroup), #501 (citing/migration), #502 (two new examples, stacked on this).

Adapted to API changes since the branch was cut

Review notes

  • Locally verified: the whole Documenter half passes with no errors — every @example runs against current main, all @ref/@extref/@cite resolve, checkdocs clean. The VitePress stage cannot run on my machine (rollup needs a newer glibc), so CI covers the HTML render.
  • The intended make_time_mpo + Zipup recipe had to be dropped: Zipup rejects propagator MPOs with a SpaceMismatch (Zipup fails with a SpaceMismatch on make_time_mpo propagator MPOs #496).
  • Concept and how-to pages are cross-linked densely (141 cross-group references), which is why they are one PR rather than four — splitting by page type would mean rewriting tens of links and restoring them later.
  • The previous 82-commit history is preserved at archive/content-wave1-pre-rebase if anything needs recovering.

🤖 Generated with Claude Code

@lkdvos lkdvos added the documentation Improvements or additions to documentation label Jul 3, 2026
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

After the build completes, the updated documentation will be available here

@codecov

codecov Bot commented Jul 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

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

@lkdvos

lkdvos commented Jul 28, 2026

Copy link
Copy Markdown
Member Author

@leburgel, any chance you can confirm this would resolve the two issues you brought up?

@leburgel

leburgel commented Jul 30, 2026

Copy link
Copy Markdown
Member

@leburgel, any chance you can confirm this would resolve the two issues you brought up?

The search issue seems to be resolved, which was definitely the most important one.

The docstring header issue improved a bit, but it's not quite solved. The custom jldocstring-heading specification is used correctly and shows the corresponding thin bottom border line. But the font weight is still not right for a <strong>...</strong> block, and the text still renders as plain instead of bold. When I inspect, I see the font weight of the strong block is 700, which should really be bold. So I have no idea what's going wrong, but I'm not sure if it's worth figuring out. The bottom border is enough to indicate the header, so I guess it's good enough.

@leburgel

Copy link
Copy Markdown
Member

Unrelated: it seems the warning and note blocks have lost quite a bit of their style compared to the way they look in standard documenter. This is quite unfortunate, the blocks here look quite a bit worse than they used to.

lkdvos added a commit that referenced this pull request Jul 30, 2026
Follow-up to the #477/#478 fixes, addressing review feedback on #449.

Bold still did not render bold. The remaining cause is VitePress' reset,
which sets `font-synthesis: style` on <body>: listing only `style` permits
synthetic oblique and *disables* synthetic bold, so wherever the resolved face
has no real bold, `font-weight: 700` computes correctly yet still paints at
regular weight. That is why the inspected weight looked right while the text
did not. Allowing weight synthesis fixes it for docstring headings and for
everything else subject to it — admonition titles, links inside callouts,
docstring binding names and inline <strong>.

Admonitions had lost their Documenter look for three compounding reasons:
VitePress custom blocks carry no icon, no title colour and a transparent
border; their title weight was subject to the same synthesis problem; and
DocumenterVitepress maps every `!!! note` onto the `tip` container, whose
dark-mode background its template overrides to a flat grey with dimmed text.
Restyled towards Documenter: accent-coloured bold title with the same
circle-exclamation icon, a 4px accent left rule, body text back at full
contrast, and tip backgrounds restated so notes keep their colour in the dark
theme. Everything is guarded by `:not(.jldocstring)`, since docstrings also
carry the `custom-block` class.

The note/tip distinction is deliberately not recovered. Both arrive as
`::: tip` and the only signal left is the title, which Documenter defaults to
"Note" — but 13 of this repo's 44 notes carry a custom title and are then
indistinguishable from a real `!!! tip`. Colouring only the recognisable ones
would be visibly inconsistent, so this waits on the upstream fix: VitePress
1.x has native `note`/`info` containers, making the remap obsolete.

UPSTREAM_DVP_NOTES.md records both findings alongside the existing two.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
lkdvos added a commit that referenced this pull request Jul 30, 2026
`first(js) > i || @error "..."` only logged the problem and then let the function
continue into a contraction that is not the requested correlator, so an unordered
(or equal) site pair returned a meaningless number instead of failing. Make it an
`ArgumentError`, and document the ordering requirement in the docstring.

All three `correlator` signatures funnel their arguments through the range method,
so the test covers each of them.

Carved out of #449 to keep that PR documentation-only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
lkdvos added a commit that referenced this pull request Jul 30, 2026
`excitations(H::InfiniteMPO, ::QuasiparticleAnsatz, ϕ₀::InfiniteQP, lenvs, renvs)`
constructed its effective Hamiltonian as
`EffectiveExcitationHamiltonian(H_eff, lenvs, renvs, E)`. `H_eff` is the local being
assigned on that very line, so the read hit an uninitialized slot and every call through
this method threw `UndefVarError: H_eff not defined in local scope` — the path was dead
rather than silently wrong. The momentum entry point is unaffected, since for an
`MPO` it converts to a `MultilineMPO` and dispatches to the `MultilineQP` method.

The regression test uses the classical Ising transfer matrix rather than the six-vertex
model of the neighbouring testset: with the latter the quasiparticle eigenproblem is only
loosely converged (the eigenpair residual is ~1e-2 on both entry points), while for the
former the two entry points agree to ~1e-11.

Carved out of #449 to keep that PR documentation-only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
lkdvos added a commit that referenced this pull request Jul 30, 2026
`Base.isfinite(O::AbstractMPO) = isfinite(typeof(O))` requires every concrete operator
type to define the trait, and `WindowMPOHamiltonian` did not, so both `isfinite(H)` and
`isfinite(typeof(H))` threw a `MethodError`. A window Hamiltonian acts on a finite
number of sites, so the trait is `true`, matching how it otherwise behaves as a finite
Hamiltonian; it is spelled and placed like the `FiniteMPO(Hamiltonian)` definitions.

Carved out of #449 to keep that PR documentation-only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
lkdvos added a commit that referenced this pull request Jul 31, 2026
`first(js) > i || @error "..."` only logged the problem and then let the function
continue into a contraction that is not the requested correlator, so an unordered
(or equal) site pair returned a meaningless number instead of failing. Make it an
`ArgumentError`, and document the ordering requirement in the docstring.

All three `correlator` signatures funnel their arguments through the range method,
so the test covers each of them.

Carved out of #449 to keep that PR documentation-only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
lkdvos added a commit that referenced this pull request Jul 31, 2026
`excitations(H::InfiniteMPO, ::QuasiparticleAnsatz, ϕ₀::InfiniteQP, lenvs, renvs)`
constructed its effective Hamiltonian as
`EffectiveExcitationHamiltonian(H_eff, lenvs, renvs, E)`. `H_eff` is the local being
assigned on that very line, so the read hit an uninitialized slot and every call through
this method threw `UndefVarError: H_eff not defined in local scope` — the path was dead
rather than silently wrong. The momentum entry point is unaffected, since for an
`MPO` it converts to a `MultilineMPO` and dispatches to the `MultilineQP` method.

The regression test uses the classical Ising transfer matrix rather than the six-vertex
model of the neighbouring testset: with the latter the quasiparticle eigenproblem is only
loosely converged (the eigenpair residual is ~1e-2 on both entry points), while for the
former the two entry points agree to ~1e-11.

Carved out of #449 to keep that PR documentation-only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
lkdvos added a commit that referenced this pull request Jul 31, 2026
`Base.isfinite(O::AbstractMPO) = isfinite(typeof(O))` requires every concrete operator
type to define the trait, and `WindowMPOHamiltonian` did not, so both `isfinite(H)` and
`isfinite(typeof(H))` threw a `MethodError`. A window Hamiltonian acts on a finite
number of sites, so the trait is `true`, matching how it otherwise behaves as a finite
Hamiltonian; it is spelled and placed like the `FiniteMPO(Hamiltonian)` definitions.

Carved out of #449 to keep that PR documentation-only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
lkdvos added a commit that referenced this pull request Jul 31, 2026
* fix: `correlator` throws on unordered sites

`first(js) > i || @error "..."` only logged the problem and then let the function
continue into a contraction that is not the requested correlator, so an unordered
(or equal) site pair returned a meaningless number instead of failing. Make it an
`ArgumentError`, and document the ordering requirement in the docstring.

All three `correlator` signatures funnel their arguments through the range method,
so the test covers each of them.

Carved out of #449 to keep that PR documentation-only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: `excitations` on an `InfiniteMPO` with a quasiparticle input

`excitations(H::InfiniteMPO, ::QuasiparticleAnsatz, ϕ₀::InfiniteQP, lenvs, renvs)`
constructed its effective Hamiltonian as
`EffectiveExcitationHamiltonian(H_eff, lenvs, renvs, E)`. `H_eff` is the local being
assigned on that very line, so the read hit an uninitialized slot and every call through
this method threw `UndefVarError: H_eff not defined in local scope` — the path was dead
rather than silently wrong. The momentum entry point is unaffected, since for an
`MPO` it converts to a `MultilineMPO` and dispatches to the `MultilineQP` method.

The regression test uses the classical Ising transfer matrix rather than the six-vertex
model of the neighbouring testset: with the latter the quasiparticle eigenproblem is only
loosely converged (the eigenpair residual is ~1e-2 on both entry points), while for the
former the two entry points agree to ~1e-11.

Carved out of #449 to keep that PR documentation-only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: `isfinite` for `WindowMPOHamiltonian`

`Base.isfinite(O::AbstractMPO) = isfinite(typeof(O))` requires every concrete operator
type to define the trait, and `WindowMPOHamiltonian` did not, so both `isfinite(H)` and
`isfinite(typeof(H))` threw a `MethodError`. A window Hamiltonian acts on a finite
number of sites, so the trait is `true`, matching how it otherwise behaves as a finite
Hamiltonian; it is spelled and placed like the `FiniteMPO(Hamiltonian)` definitions.

Carved out of #449 to keep that PR documentation-only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* shrink changelog

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@lkdvos
lkdvos force-pushed the docs/content-wave1 branch from d792dec to 1e67ee6 Compare August 3, 2026 22:53
`quantum1d` and `classic2d` grouped by the physics of the model, which is not how a reader
arrives: they come with a task ("I need a ground state", "I need finite temperature") and
have to open every example to find out which one does it. Regroup into `groundstates`,
`excitations`, `dynamics` and `statmech`, and give the gallery index a one-paragraph summary
per example so it can be scanned.

`examples/make.jl` now discovers groups by listing its own subdirectories instead of naming
them, so adding a group needs no pipeline change. The gallery sidebar in `docs/make.jl`
mirrors the same grouping.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A hand-held, sequential path for someone who has never used the package: install it, find a
ground state with DMRG, take the same model to the thermodynamic limit with VUMPS, quench
it, extract excitations, then re-run the whole thing with symmetries. Each page ends where
the next begins, and the transverse-field Ising model runs through all of them so the
reader accumulates familiarity rather than meeting a new model per page.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
lkdvos and others added 6 commits August 3, 2026 19:09
Where the tutorials teach, these answer "how do I do X" for someone who already knows what
they want: build a state or a Hamiltonian, pick and configure a ground-state algorithm, grow
or truncate a bond dimension, evolve in time, measure observables and entanglement, find
excitations, run statistical-mechanics and quasi-1D calculations, diagnose a solve that will
not converge, use threads and GPUs, and save results. `howto/index.md` is a browsable index
so a reader can scan for their task instead of reading through.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The `man/` section mixed explanation, recipes and reference on the same page, which made it
hard to know what any given page was for. These nine pages take over its explanatory role
and nothing else: what TensorKit's vector spaces mean for MPS, what an MPS is and what the
gauge freedom buys, how finite and infinite differ, how operators and Hamiltonians are
represented, what symmetries do to the tensors, how to choose among the algorithms, what
environments are, how parallelism is structured, and which numerical errors matter.

Recipe material from `man/` moved to the how-to pages and reference material to `lib/`, so
`man/` is deleted rather than left as a stale duplicate. The two diagrams worth keeping are
moved across; the three parallelism benchmark plots are dropped, since they described
machine-specific timings with no provenance.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A single `@autodocs Modules = [MPSKit]` dump gives no way to find the function you want.
Split it into topic pages that mirror the how-to structure — states, operators, ground
states, bond dimension, time evolution, excitations, observables, environments — with
`lib/public.md` as the annotated entry point to the exported API.

`lib/internals.md` collects what is deliberately not part of the public interface and is
marked as unstable. `lib/lib.md` keeps the exhaustive autodocs listing as a backstop, so
nothing is unreachable if a docstring is missing from a topic page.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The old landing page was a short paragraph and a link list, which told a visitor nothing
about whether the package solves their problem. It now leads with what MPSKit does, a
runnable transverse-field Ising ground-state example, feature cards for the properties that
actually differentiate it (symmetries, finite and infinite on the same footing, the
algorithm coverage, performance), and pointers into the tutorial track.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
These pages were drafted before #482, which renamed every `trscheme` keyword to `trunc` and
split renormalization out of `imaginary_evolution` into its own `normalize` keyword.

The rename is mechanical. The `normalize` change is not: the pages claimed that
imaginary-time evolution renormalizes at every step so the norm stays at one, which is now
false — `normalize` defaults to `false` and the norm is preserved in both real and imaginary
time. Corrected where imaginary-time evolution is introduced, with the recipe page showing
both behaviors.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both landed after these pages were drafted, and the pages enumerate the time-evolution
options, so leaving them out would have shipped a listing that is wrong by omission.

`BUG` (#468) gets a how-to recipe, a paragraph in the algorithm landscape, and a row in the
decision table. Two things are worth stating explicitly and are easy to get wrong from the
name alone: it is the one single-site integrator that can change bond dimension, and a
`truncrank(D)` leaves the state at `2D`, because each half-sweep only truncates the previous
one's basis augmentation — so a follow-up `SvdCut` is needed to actually land on `D`.

`Zipup` (#470) is documented alongside the propagator-MPO route it belongs to, including the
two API differences from the variational path: no initial guess, and a 2-tuple return. It is
not mentioned on the statistical-mechanics page, since it is finite open-boundary only.

`approximate`/`approximate!` had no topical reference home at all; they now live on the
time-evolution reference page next to `Zipup`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@lkdvos
lkdvos force-pushed the docs/content-wave1 branch from 1e67ee6 to 9c884ca Compare August 3, 2026 23:09
@lkdvos
lkdvos changed the base branch from main to docs/examples-regroup August 3, 2026 23:09
@lkdvos lkdvos changed the title docs: content wave 1 (reference + how-to pages) docs: Diátaxis restructure — tutorials, how-to guides, concepts, library reference Aug 3, 2026
@lkdvos
lkdvos force-pushed the docs/examples-regroup branch 2 times, most recently from ba92131 to ff58ac4 Compare August 5, 2026 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants