15Using symmetry without changing the question

A smaller symmetry sector must still contain the state you mean.

~20 min reading10 sections3 knowledge checks

Progress is saved only in this browser. No account or tracking.

A symmetry partitions a space

Concept plate 15
ZZ eigenvalue +1ZZ eigenvalue -100 1101 10Choose the physical sector, not merely the smaller label
For the toy operator Z tensor Z, the basis states 00 and 11 have eigenvalue +1; 01 and 10 have eigenvalue -1. Selecting a sector removes possibilities only when it matches the target problem.
  • 1Even parity: 00 and 11
  • 2Odd parity: 01 and 10
  • 3Carry the selected sector downstream
Original technical lesson · 1 contextual figure addedDownload original MarkdownJump to the interactive model

A smaller calculation must still answer the same question

Our target remains neutral, singlet N₂ at 1.85 Å. The selected six-spatial-orbital model has three active alpha and three active beta electrons. Lesson 14 translated its operator into twelve occupation qubits without claiming that every state of those qubits describes the intended molecule.

Symmetry now offers two different kinds of saving. We can organize classical arrays so that independent sectors are stored and processed separately. We can also sometimes remove qubits whose values are fixed after an appropriate encoding transformation. These are not the same operation. Neither licenses choosing a lower-energy state with the wrong electron count or spin.

A useful engineering rule is to name the constraint before using the saving. “These two arrays share restricted-spin storage” is a data statement. “The state has three alpha electrons” is a particle-sector statement. “This encoded Z operator has eigenvalue minus one” is a qubit-sector statement. They can be related, but none substitutes for the others.

This lesson follows the native symmetry vocabulary, its Python bindings, and the actual tapering path at revision 97a3ff4f. The general mathematical derivation is explicitly distinguished from capabilities shipped in this implementation. No symmetry search, matrix diagonalization, circuit compilation, or test is being executed.

What a symmetry preserves

A symmetry operation changes the description of a system while leaving the relevant physics unchanged. For a Hamiltonian HH and a unitary symmetry operation UU, this means UHU†=HUHU^\dagger=H. Equivalently, UU commutes with HH: [H,U]=HU−UH=0[H,U]=HU-UH=0.

A group is a collection of operations closed under composition, including an identity and inverses, with associative composition. A representation describes those abstract operations as matrices acting on states. We need these words because a molecule’s geometric rotations, an electron-number phase rotation, and a Pauli string on qubits are quite different objects even when all are called symmetries.

A conserved observable QQ satisfies [H,Q]=0[H,Q]=0. Its eigenvalue can label a sector: the set of states with that value. To see why sectors decouple, let Q∣a⟩=qa∣a⟩Q|a\rangle=q_a|a\rangle and Q∣b⟩=qb∣b⟩Q|b\rangle=q_b|b\rangle. Then

0=⟨a∣[Q,H]∣b⟩=(qa−qb)⟨a∣H∣b⟩.0=\langle a|[Q,H]|b\rangle =(q_a-q_b)\langle a|H|b\rangle.

If qa≠qbq_a\ne q_b, the Hamiltonian matrix element must vanish. States in those different sectors cannot mix under this Hamiltonian. This is a stronger reason for a zero than a coefficient happening to be numerically small.

For our spin-conserving electronic model, the number operators NαN_\alpha and NβN_\beta commute with the Hamiltonian. Their sum is the active electron number NN; their difference gives spin projection Sz=(Nα−Nβ)/2S_z=(N_\alpha-N_\beta)/2 in units where ℏ=1\hbar=1. Electron number has integer eigenvalues, although its associated phase operations eiθNe^{i\theta N}, for continuous angle θ\theta, form a continuous symmetry. There is no contradiction between discrete electron counts and a continuous symmetry group.

Particle-number parity retains less information: (−1)N(-1)^N is plus one for even counts and minus one for odd counts. Three alpha electrons and five alpha electrons have the same alpha parity. Preserving parity therefore does not select exact electron number.

Total spin is another distinction. A total-spin eigenstate has S2S^2 eigenvalue S(S+1)S(S+1) and multiplicity 2S+12S+1. Fixing Sz=0S_z=0 permits a singlet but also the zero-projection components of higher-spin states. An unrestricted determinant can additionally mix total-spin components. Neither equal alpha/beta counts nor an alpha/beta storage label proves a singlet.

The molecular point group consists of spatial transformations, such as rotations, reflections, or inversion, that preserve a fixed nuclear geometry. Orbitals may transform in its irreducible representations, the elementary independent pieces of a representation. In an abelian group, operations commute and irreducible representations can be one-dimensional; nonabelian groups can require multidimensional pieces. These concepts explain familiar orbital labels and degeneracies. They do not establish that the current software automatically discovers or exploits every such label. Geometry distortions, external fields, or a changed model can also break a symmetry that was valid elsewhere along a path.

The two symmetry APIs have different jobs

The native single-particle vocabulary lives in data/symmetry/symmetry.hpp, with implementation and a Python facade. Its current AxisName enumeration contains Spin only. There is no populated point-group axis in this vocabulary at this revision. A broad container design is not evidence of a general point-group finder, irreducible-representation solver, or spin-adapted CI implementation.

SpinValue stores twice a spin-projection label. axes.alpha() carries +1 and axes.beta() −1. axes.spin(two_s, equivalent=True) constructs the allowed labels from -two_s to +two_s in steps of two. For electron spin use two_s=1, not a molecular singlet multiplicity. axes.spin_value(two_ms) and SpinValue(two_ms) can carry other integer values; an appropriate axis determines whether a value is admissible. Such a label is data, not a calculation of a many-electron spin eigenstate.

A SymmetryAxis contains its name, admissible labels, and an equivalent flag. Here equivalent means the labels may share numerical storage, as restricted alpha/beta molecular-orbital coefficients can. It does not mean the two spin states are physically identical. A SymmetryProduct collects the axes for an index slot. A SymmetryLabel supplies one value per axis and serves as a hashable addressing key. An empty product and empty label represent an axis-free quantity. Current loader dispatch recognizes the spin kind; inventing a point-group tag in JSON does not extend the implementation.

Separately, data.Symmetries is a small Python container for active-space alpha/beta counts. It exposes n_alpha, n_beta, n_particles, and sz; from_wavefunction reads get_active_num_electrons(), and from_ansatz reads the bundled wavefunction. It does not discover symmetry by inspecting the Hamiltonian matrix.

A particularly important naming limit is Symmetries.spin_multiplicity: the implementation returns abs(n_alpha - n_beta) + 1. That is a count-derived convention, equal to 2∣Sz∣+12|S_z|+1, not a measurement or proof of SS. For a general state, total spin is not determined by these two counts. Use the property with that qualification rather than silently interpreting 1 as certified singlet character. The tests verify the formula; they do not establish a general spin-purity theorem.

A spin-blocked array you can actually interpret

A tensor is an indexed array; rank is its number of index slots, not its numerical matrix rank. A symmetry-blocked tensor associates a label tuple with a dense block. Each slot also has an extent, the number of indices available for a particular label.

For example, a spin-diagonal one-body operator in two spatial orbitals has a 2×2 alpha block and a 2×2 beta block. In a restricted representation those blocks can share the same numerical matrix. This source-backed instructional example follows the Python storage tests:

import numpy as np
from qdk_chemistry.data import symmetry as sym

spin = sym.SymmetryProduct([sym.axes.spin(1, True)])
a = sym.SymmetryLabel([sym.axes.alpha()])
b = sym.SymmetryLabel([sym.axes.beta()])
extents = {a: 2, b: 2}
h = np.array([[-1.0, 0.2], [0.2, 0.5]])  # illustrative entries

blocks = sym.SymmetryBlockedTensorRank2(
    [spin, spin],
    [extents, extents],
    [((a, a), h)],
)
alpha_block = blocks.block((a, a))
beta_block = blocks.block((b, b))

This code is not executed here. Both returned blocks describe the same illustrative matrix under restricted storage. num_blocks() counts the two accessible keys, not necessarily two independent allocations. The mixed (a,b) block has not been supplied. A dense .block(...) request for an absent block raises; it does not silently allocate a zero matrix.

For unrestricted storage, construct axes.spin(1, False) and supply independent alpha and beta blocks. Restricted storage cannot be used as a trick to merge genuinely different matrices. The actual common storage implementation activates spin-partner aliasing when every slot has an equivalent spin axis. It flips the spin values simultaneously across all slots. It checks compatible extents and requires explicitly supplied partners to share backing storage. The operative rule is in that implementation; older comments requiring identical SymmetryProduct object identity are not the current test in the code.

An alias is another key referencing the same immutable backing block. It is not a transpose, complex conjugate, index permutation, or newly computed matrix. In particular, sharing (alpha,alpha,beta,beta) and its spin-flipped partner does not itself tell a consumer how a four-index Coulomb tensor should be contracted. The chemist-order and mixed alpha-pair/beta-pair conventions from Lessons 12–14 still apply.

The exported dense families are SymmetryBlockedTensorRank1 through Rank4, with corresponding ...Complex variants. Rank 1 uses a vector; rank 2 a matrix; rank 3 stores a producer-chosen matrix reshaping of three indices; rank 4 is flat packed. The shape validator checks exact rank-1/rank-2 extents and the rank-3 total product. For rank 4 it requires a nonempty flat vector but deliberately leaves packing length to the producer. A successful constructor is therefore not a universal guarantee that an arbitrary rank-4 vector has the desired integral layout.

Complex storage permits complex values. It does not make every Hamiltonian constructor, RDM contraction, or solver complex-capable. That familiar container-versus-consumer distinction remains essential.

Index sets, counts, sparse maps, and contractions

SymmetryBlockedIndexSet associates each label with a sorted, unique list of indices in a declared universe. This is how active or inactive orbital selections can carry separate spin channels. The Python helper spin_index_set(num_modes, alpha, beta, equivalent=True) builds one. Its num_modes is the orbital universe size per spin channel in this helper, not an instruction to allocate that many physical qubits.

For a restricted six-orbital selection inside the original 28-spatial-orbital model, the conceptual lists can both be [4,5,6,7,8,9], with universe size 28. Those are full-space MO identities. The active Hamiltonian subsequently uses local positions 0–5. For unequal spin selections use non-equivalent storage; the helper’s default equivalent=True is not an invitation to alias unequal lists. The implementation checks strictly increasing indices and bounds. It does not diagnose whether those indices retain the same chemical character at another geometry.

SymmetryBlockedScalarCount stores a scalar count per sector, for example alpha=3 and beta=3. Counts need not have the same storage equivalence as orbital coefficients: a restricted-open-shell calculation can share spatial orbitals but have unequal alpha/beta populations. Use non-equivalent axes for independent counts. Its scalar implementation computes unit extents internally because the payload is one scalar per label, not a selected-index vector.

SymmetryBlockedSparseMapRank4 maps a sector label tuple to a map of local four-index tuples and real values. Its .get(labels, indices) returns zero when an entry or the entire block is absent, unlike the dense .block accessor. It validates stored index bounds at construction. num_entries() counts entries through accessible block keys, so aliases are included in that count. These are the actual sparse-map semantics, not a general rule that every missing chemistry quantity means zero.

Why does blocking save work? If a matrix is block diagonal, a multiplication can be performed independently in each block. Two blocks of size KK require two dense matrix products of rough cubic cost, instead of one size-2K2K product that spends work on known zeros. This is an illustrative scaling comparison, not a timing claim. Savings depend on the consumer actually honoring the blocks.

For a one-particle density matrix γ\gamma, an orbital change within a sector has the familiar form γ′=U†γU\gamma^{\prime}=U^\dagger\gamma U, where UU describes the basis rotation in that sector. Density and integral contractions must sum over the matching spin blocks, using their actual index order and conjugation rules. The blocked storage classes do not provide an automatic general tensor-algebra compiler, point-group Clebsch–Gordan machinery, or arbitrary orbital transformation simply because labels are present. A rotation mixing sectors must transform the symmetry representation as well; old labels cannot be retained blindly.

Serialization records the rank/scalar specialization, per-slot symmetry metadata, extents, and groups of keys sharing a stored block. The tensor loader restores that shared structure, and existing tests check real/complex ranks and aliases. Prefer the matching loader over manually stripping labels back into an unlabeled tuple. This is an identity-preservation issue, not merely file-format decoration. We have read those tests without writing or round-tripping any files.

From conserved quantities to removable qubits

Now turn from classical array organization to a qubit Hamiltonian Hq=∑tctPtH_q=\sum_t c_tP_t. A Pauli symmetry SS is a Hermitian Pauli operator with S2=IS^2=I that commutes with the Hamiltonian. Its possible eigenvalues are +1 and −1. The two-element structure is called a Z₂ symmetry; it is a mathematical parity-like group, not necessarily a single-qubit Z gate in the original encoding.

The centralizer of the Hamiltonian’s Pauli terms is the set of Pauli words commuting with all of them. Lesson 14’s binary masks offer a way to find it. Represent a candidate word by (x,z)(x,z) and each Hamiltonian term by (xt,zt)(x_t,z_t). Commutation requires

xt⋅z+zt⋅x=0(mod2)x_t\cdot z+z_t\cdot x=0\pmod 2

for every retained term. These are linear equations over GF(2), the arithmetic of zero and one with addition given by XOR. Binary Gaussian elimination can find independent solutions. Independence means one generator is not a product of the others.

That is a general mathematical recipe, not a current find_all_symmetries API in this repository. The shipped tapering path examined here uses known particle parities in particular encodings; it does not expose a general Hamiltonian centralizer search, commuting-generator selection, and arbitrary Clifford-synthesis pipeline.

Even in a general implementation, a nullspace basis is not yet the final answer. Selected generators must commute with one another to admit simultaneous sector eigenvalues. Their phases must be tracked: binary masks alone do not distinguish a Pauli word from its negative. A product generator’s eigenvalue must equal the product of its constituent signed eigenvalues. Treating dependent generators as independent could remove too many degrees of freedom.

A Clifford unitary maps Pauli words to Pauli words, up to signs, under conjugation. For an independent commuting generator set, one can seek a Clifford CC with CSjC†=ZqjCS_jC^\dagger=Z_{q_j}, absorbing any minus sign consistently into the sector value. This is a special transformation, not a property of every unitary. In the transformed Hamiltonian, each removable position then carries only I or Z when the symmetry is exact. Substituting Zqj=sjZ_{q_j}=s_j, with sj=±1s_j=\pm1, removes that qubit within the chosen sector.

A two-qubit tapering example by hand

Take the illustrative operator

H=aZ0+bZ1+cX0X1,S=Z0Z1.H=aZ_0+bZ_1+cX_0X_1, \qquad S=Z_0Z_1.

The coefficients a,b,ca,b,c are arbitrary real toy parameters, not molecular integrals. Every term commutes with SS. Let CC be CNOT with control 0 and target 1. Conjugation gives

CSC†=Z1,CHC†=aZ0+bZ0Z1+cX0.CSC^\dagger=Z_1, \qquad CHC^\dagger=aZ_0+bZ_0Z_1+cX_0.

In the S=sS=s sector, remove qubit 1 and obtain

Different parity sectors have different spectra#

Supplementary · Analytical illustration

Toy eigenenergy (arbitrary units)
Different parity sectors have different spectraToy eigenenergy (arbitrary units) versus Selected symmetry eigenvalue s. Lower eigenvalue; Upper eigenvalue. Exact assumptions and selected numerical values follow this plot.-1-0.500.51s = −1s = +1Different parity sectors have different spectraToy eigenenergy (arbitrary units) versus Selected symmetry eigenvalue s. Lower eigenvalue; Upper eigenvalue. Exact assumptions and selected numerical values follow this plot.-1-0.500.51s = −1s = +1
Selected symmetry eigenvalue s
  • Lower eigenvalue
  • Upper eigenvalue

Dotted reference: Zero of the toy Hamiltonian.

Model and source. Use the lesson’s Hs = (a + sb)Z + cX with chosen a = 0.6, b = 0.4, c = 0.3 (arbitrary energy units), s = ±1. Eigenvalues are ±√((a + sb)² + c²). Fixed parity is not fixed electron number.

How to read this. Choosing a sector is a physical constraint, not merely a smaller-qubit-count trick. The wrong sector gives a different low energy.

Inspect plotted values

Selected coordinates from the declared analytical or teaching data. Continuous curves are sampled for drawing; discrete outcomes remain discrete.

Different parity sectors have different spectra: plotted values
Seriesxy
Lower eigenvalue0-0.360555
Lower eigenvalue1-1.04403
Upper eigenvalue00.360555
Upper eigenvalue11.04403
Return to this explanation
Hs=(a+sb)Z0+cX0.H_s=(a+s b)Z_0+cX_0.

Its two eigenvalues are ±(a+sb)2+c2\pm\sqrt{(a+s b)^2+c^2}. The plus and minus sectors generally have different spectra. Taking the minimum from one sector is not the same as solving the original four-dimensional problem, and selecting the wrong sector changes the question.

For label interpretation, QubitOperator strings place qubit 0 on the right: the original terms are IZ, ZI, and XX. The transformed terms are IZ, ZZ, and IX. Substituting the left-position Z associated with qubit 1 produces exactly the one-qubit expression above. Do not use the opposite canonical-string direction from PauliOperator without conversion.

Write state kets here as ∣q1q0⟩|q_1q_0\rangle. An even-parity trial state u∣00⟩+v∣11⟩u|00\rangle+v|11\rangle becomes ∣0⟩1⊗(u∣0⟩0+v∣1⟩0)|0\rangle_1\otimes(u|0\rangle_0+v|1\rangle_0) after this CNOT. Qubit 1 is known to be zero and can be removed. An odd-parity state instead has that qubit fixed to one. A superposition spanning both parities leaves it correlated with the rest and cannot be replaced by a single fixed eigenvalue without changing the state.

The example also exposes an observable constraint. An observable that changes the selected parity connects different sectors. Its within-sector projection can be zero even when cross-sector transition matrix elements are physically meaningful. Tapering the Hamiltonian does not justify using every original observable unchanged.

What the current tapering code really does

TaperingSpecification records qubit_indices and matching eigenvalues. Construction checks equal lengths, distinct indices, and values restricted to +1 or −1. It does not contain the Hamiltonian, an automatically discovered generator set, or a general Clifford circuit. Without a register width, the standalone constructor cannot check whether all its indices fit that register.

Its two specialized factories are symmetry_conserving_bravyi_kitaev and parity_two_qubit_reduction. The implementation requires an even mode count M≥4M\ge4 and each spin population at most M/2M/2. It chooses positions

qα=M/2−1,qtotal=M−1q_\alpha=M/2-1,\qquad q_{\mathrm{total}}=M-1

and values sα=(−1)Nαs_\alpha=(-1)^{N_\alpha}, stotal=(−1)Nα+Nβs_{\mathrm{total}}=(-1)^{N_\alpha+N_\beta}. These positions encode the two parities in the supported blocked parity and balanced BK-tree conventions. They are not arbitrary positions that work in an untransformed Jordan–Wigner Hamiltonian.

The public source-backed workflow bundles this specification into a mapping:

from qdk_chemistry.algorithms import create
from qdk_chemistry.data import MajoranaMapping, Symmetries

symmetries = Symmetries(n_alpha=3, n_beta=3)
mapping = MajoranaMapping.parity(12, symmetries)
tapered_hamiltonian = create("qubit_mapper", "qdk").run(active_hamiltonian, mapping)

This is an unexecuted pattern assuming the matching six-spatial-orbital active Hamiltonian. The alternative MajoranaMapping.symmetry_conserving_bravyi_kitaev(12, symmetries) uses BK-tree as its base, not the standard Fenwick BK variant. Both descriptions have pre-taper table width 12 and specify removal of qubits 5 and 11 with eigenvalues −1 and +1. The mapped output has ten problem qubits. The count reduction follows the factory contract; no nitrogen spectrum has been computed here.

A crucial remaining dimension is 210=10242^{10}=1024. That is larger than the 400-state exact (3,3) electron sector. Each six-bit spin block has 32 odd-parity strings, so the paired odd-alpha/odd-beta parity space has 32×32=102432\times32=1024 states. It also includes other odd spin populations. The non-power-of-two SCBK test correctly compares against the union of matching-parity sectors, not just one fixed population. Number-conserving evolution of a correctly prepared fixed-population state can remain in its smaller physical sector, but the tapered operator alone does not enforce that preparation.

Each mapper strips the tapering metadata, maps the base encoding, then calls the shared Python taper helper. That helper interprets qubit positions using rightmost-qubit-zero labels, substitutes the specified value for Z, deletes the relevant characters, combines identical remaining words, and keeps combined magnitudes strictly greater than a hard-coded 1e-12. That final cutoff is additional to the native mapper’s configurable screening. It can introduce a tiny extra approximation and does not inherit an arbitrarily tighter mapper threshold.

The helper checks duplicate/out-of-range positions, valid signs, matching list lengths, and that at least one qubit remains. It provides an explicit zero identity term if nothing survives. But it does not reject X or Y on a supposedly removable qubit: it skips that whole Pauli term. Mathematically this is consistent with taking the diagonal sector projection PHPPHP. If the Hamiltonian actually couples sectors, however, it is not a spectrum-preserving symmetry reduction. Thus a specification is not a certificate of commutation. Standard factory assumptions and source tests matter; arbitrary user-written metadata must not be trusted as proof.

The internal _taper_qubits and _taper_result helpers are not general public promises to transform arbitrary states or circuits. The Majorana tests cover expected signs, invalid populations/mode counts, base-versus-tapered metadata, and serialization. Mapper tests check the specialized conserved Z positions and reduced spectra. We have inspected these checks, not executed them.

Choosing and carrying the sector

A known reference can determine a symmetry eigenvalue when it is actually an eigenstate of that symmetry. For a Jordan–Wigner determinant, a Z-string eigenvalue is the product of −1 over occupied positions in the string. For a superposition, all components must belong to the same sector, with phases treated consistently. A Pauli string containing X or Y generally moves a determinant to another configuration, so its expectation cannot be read from a count-of-ones rule.

For a normalized state and a Hermitian Pauli symmetry, ∣⟨S⟩∣=1|\langle S\rangle|=1 certifies a definite ± sector in exact arithmetic. An intermediate expectation, such as zero, is not an instruction to choose the plus sector. Symmetries.from_wavefunction merely reads count information from the wavefunction API; it does not perform all such expectation or variance checks on arbitrary custom states. The determinant/configuration containers’ own validation limits from Lesson 9 remain relevant.

After choosing the sector, the trial state, state-preparation circuit, Hamiltonian, observables, and later controlled evolution must share the transformed and reduced convention. Current ordinary state-preparation methods return Jordan–Wigner occupation circuits. There is no automatic promise in this tapering workflow to convert and taper an arbitrary such circuit. For parity or BK-tree reduction, derive the appropriate state transformation and remove only known fixed positions; alternatively retain the untapered Jordan–Wigner baseline until the state path is validated.

Setting Circuit.encoding to a reduced encoding name does not implement those gates. The deprecated encoding-compatibility facade checks strings only. Matching strings cannot prove matching active orbitals, mode order, removed positions, eigenvalues, or phases. Likewise to_interleaved is a wire permutation, not a replacement for reconstructing a differently ordered fermionic encoding.

The ordinary mapper still leaves get_core_energy() outside the Pauli operator. A Clifford change and a parity substitution do not make nuclear repulsion or frozen-core energy disappear; add the same scalar once in total-energy comparisons. An identity coefficient created during tapering is part of the active operator, not permission to double count that core scalar.

The graph-oriented Verstraete–Cirac mapping from Lesson 14 is a related but distinct use of constraints. Its auxiliary stabilizers define a physical codespace in an enlarged register, and the engine supplies penalty terms. Those auxiliary constraints are not automatically identical to chemical electron-number parity. The correct subspace, state loading, and energy bookkeeping must accompany that representation too.

What the savings mean downstream

Removing two problem qubits reduces a generic dense state-vector dimension by four. It can reduce certain gate and storage costs. It does not necessarily remove two qubits from every peak circuit width: control registers, coefficient-loading registers, shared phase-gradient ancillas, and internal workspaces remain. Physical error-correction overhead is a further layer that this calculation has not estimated.

There can also be costs: finding or verifying generators, applying a basis transformation, adapting observables, reconstructing state preparation, and maintaining consistent sectors along geometries. Near a crossing, the lowest state in one symmetry sector may stop being the state of interest. Symmetry labels are valuable precisely because they let us track that distinction instead of silently following the global minimum.

For our nitrogen story, symmetry-blocked classical data and fixed (3,3) populations are immediately useful. The specialized parity reductions are real operator capabilities, but a fully reduced workflow still needs a matched state path. We will therefore keep the well-defined untapered occupation encoding as the main state-loading baseline while learning what each preparation method actually does. The next lesson asks how to obtain a useful, affordable trial state without pretending that knowing the desired symmetry means knowing the desired eigenvector.

Make the idea your own

Supplementary learning

The original lesson above is preserved in full, with labeled supplemental figures placed beside the relevant explanations. The model and questions below are also learning aids, not newly executed chemistry results.

Explore an active space

Interactive model

Compare all fixed-electron determinants with a fixed spin-projection sector. This count is not a qubit-tapering algorithm.

Illustrative model, not a scientific calculation. Counts only: M spatial orbitals give 2M spin modes and 2M qubits under an untapered direct occupation mapping. Fixed N alpha minus N beta is a spin projection, not proof of a total-spin eigenstate. No basis-quality or energy calculation is performed.

Enable JavaScript to explore this model. The assumptions and original lesson remain readable without it.

Check your understanding

Supplementary learning

Reason through these 3 questions. Your answers do not mark the lesson as read, and nothing is locked.

1. What is essential when using a symmetry to reduce a register?
2. Why are spin-block storage and qubit tapering not the same thing?
3. What should accompany a tapered Hamiltonian?

Enable JavaScript to check and save answers locally.

Source notes & references (20)

No execution or file writes. Populated native symmetry axis is Spin only; no general point-group discovery/centralizer/Clifford tapering search exposed in the inspected pipeline. Symmetries.spin_multiplicity is count-derived, not S2 certification. Actual spin aliasing tests every slot equivalence rather than object identity despite older comments. Rank4 packed shape is producer-defined; dense missing block raises but sparse get returns zero. Specialized tapering fixes alpha/total parity, not exact electron numbers. Helper skips X/Y terms rather than validating commutation and applies its own1e-12 cutoff. No automatic arbitrary state/circuit tapering; core scalar remains separate. General GF2/Clifford and toy spectra are explanatory derivations, not executed native features.

Public source: microsoft/qdk-chemistry, pinned to 97a3ff4fb86e. This course describes that revision, not every later release.

Look up a term

On this page

  1. A smaller calculation must still answer the same question
  2. What a symmetry preserves
  3. The two symmetry APIs have different jobs
  4. A spin-blocked array you can actually interpret
  5. Index sets, counts, sparse maps, and contractions
  6. From conserved quantities to removable qubits
  7. A two-qubit tapering example by hand
  8. What the current tapering code really does
  9. Choosing and carrying the sector
  10. What the savings mean downstream
  11. Interactive model
  12. Knowledge check
  13. Source notes

The complete journey

Course homeGlossarySavedAbout

Search the course

Search titles and the full lesson text.

    Tab to a result, Enter to open. Escape closes search.