Skip to content
Back to skills

Operators And Transforms

ASecurity

"Operate on OpenFermion's symbolic and tensor operator

  • 247 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 8, 2026
toolspythongobashexpressapi

Works with

  • api

Security analysis

A100/100

Pro scans all 5 files and shows the line behind each finding

Scanned September 8, 2026

npx -y skills add VectorSpaceLab/AREX-Skill --skill operators-and-transforms --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Operators And Transforms?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Operators And Transforms
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/vectorspacelab-operators-and-transforms/badge)](https://www.skillsdirectory.com/skills/vectorspacelab-operators-and-transforms)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: operators-and-transforms
description: "Operate on OpenFermion's symbolic and tensor operator
  representations, normalize and validate terms, and choose or apply
  fermion-to-qubit mappings."
metadata:
  disco-role: operating
disable-model-invocation: true
license: Apache 2.0
---

# Operators and transforms

Use this sub-skill when a task needs second-quantized operator algebra, Pauli
strings, Majorana or bosonic ladder operators, tensor-backed interaction
representations, normal ordering, Hermitian checks, commutators/BCH terms, or a
fermion-to-qubit mapping. It covers the public OpenFermion APIs and small,
inspectable operators; route model construction and chemistry file formats to
[hamiltonians-and-chemistry](../hamiltonians-and-chemistry/SKILL.md), circuit
synthesis/simulation to [circuits-and-simulation](../circuits-and-simulation/SKILL.md),
and large eigensolvers or RDM workflows to
[analysis-and-measurements](../analysis-and-measurements/SKILL.md).

## Fast route

1. **Identify the representation.** Use `FermionOperator` for arbitrary
   fermionic ladder-polynomials, `QubitOperator` for sums of Pauli strings,
   `BosonOperator` for bosonic ladders, and `MajoranaOperator` for products of
   Majorana generators. Use `InteractionOperator` or `PolynomialTensor` only
   when fixed tensor structure and array operations are useful.
2. **Construct with explicit conventions.** Fermion/boson strings use `p^` for
   creation and `p` for annihilation. Qubit strings use `X0`, `Y1`, or `Z2`.
   The empty string/tuple is identity; a no-argument constructor is zero.
   Keep the factor order of fermionic terms until `normal_ordered` is called.
3. **Validate before mapping.** Check `count_qubits(op)`,
   `is_hermitian(op)`, and the relevant number-preservation predicate. For
   malformed input, inspect index/action types first; see
   [troubleshooting](references/troubleshooting.md).
4. **Choose a map deliberately.** Use `jordan_wigner` for the direct canonical
   mapping and broad compatibility; `bravyi_kitaev` for a Fenwick-tree mapping
   with an optional explicit qubit count; `binary_code_transform` for a
   supplied `BinaryCode` (including parity, checksum, or qubit-saving codes).
   Use `reverse_jordan_wigner` only for the JW inverse direction.
5. **Compare representations, not term dictionaries.** JW and BK generally
   produce different Pauli strings but represent equivalent operators. Compare
   spectra or sparse matrices only after choosing the same Hilbert-space size.
6. **Cross the sparse boundary intentionally.** Use `get_sparse_operator` only
   after mapping/normalization and pass `n_qubits` for padded fermion/qubit
   spaces. For bosons, pass a finite `trunc`; this is a Fock-space cutoff, not
   a qubit count.

## Core recipes

```python
from openfermion import (
    FermionOperator, QubitOperator, bravyi_kitaev, count_qubits,
    hermitian_conjugated, jordan_wigner, normal_ordered,
)

hop = FermionOperator("0^ 1", 0.5)
hop += hermitian_conjugated(hop)
hop = normal_ordered(hop)
assert hop.is_normal_ordered()
print(count_qubits(hop))                 # 2
jw = jordan_wigner(hop)                  # 0.25 [X0 X1] + 0.25 [Y0 Y1]
bk = bravyi_kitaev(hop, n_qubits=2)      # equivalent, different strings
```

Use `op.terms` for programmatic inspection. Its keys are tuples of
`(index, action)` pairs: `(index, 1)`/`(index, 0)` for creation/annihilation and
`(index, "X"|"Y"|"Z")` for Pauli factors. `+=`, `-=`, `*=`, and `/=` mutate;
ordinary arithmetic returns a copy. Same-type products are algebraically
simplified, including Pauli phases. `compress()` removes near-zero terms;
`isclose(other, rtol=..., atol=...)` is preferable to comparing printed text.

For a quick CPU-only smoke check from any working directory, run the bundled
[smoke_transform.py](scripts/smoke_transform.py) helper:

```bash
python scripts/smoke_transform.py --help
python scripts/smoke_transform.py --mapping jw --sparse
```

The helper uses only public imports, a two-mode hopping term, and a tiny sparse
matrix; it does not read source files or use the network.

## Decision points and boundaries

- `normal_ordered` is a representation rewrite using canonical
  anti-commutation/commutation relations; it can increase term count and is
  exponential in the locality of a ladder term. For chemistry-style
  two-body operators, `chemist_ordered` requires a two-body,
  number-conserving `FermionOperator`.
- `InteractionOperator` assumes a number-conserving, Hermitian interaction
  Hamiltonian structure. It is not a general replacement for an arbitrary
  `FermionOperator`; use the latter for non-Hermitian or non-number-conserving
  expressions.
- `jordan_wigner` maps `FermionOperator`, `MajoranaOperator`,
  `InteractionOperator`, and diagonal Coulomb representations, but has no
  `n_qubits` argument. `bravyi_kitaev` accepts `FermionOperator`,
  `MajoranaOperator`, and `InteractionOperator`; its `n_qubits` may pad the
  first two kinds. Never pass a value below `count_qubits`.
- Custom binary codes are constrained by the code's `n_modes` and
  `n_qubits`; they are not a general way to pad an operator. Nonlinear or
  qubit-saving codes can expand a term into many Pauli strings.
- `reverse_jordan_wigner` accepts only a `QubitOperator` and returns a
  `FermionOperator`; it is not a general inverse for BK or arbitrary binary
  codes. Round-trip after `compress()` is the useful correctness check.
- Sparse conversion is a representation boundary, not a solver. Keep large
  eigenspectrum, ground-state, RDM, measurement, and model-builder work in the
  routed sub-skills.

For signatures, term schemas, tensor indexing, and concrete expected outputs,
read [api-reference.md](references/api-reference.md). For mapping formulas,
variants, qubit-count rules, and binary-code choices, read
[transforms.md](references/transforms.md). For failure diagnosis, read
[troubleshooting.md](references/troubleshooting.md).

## Recovery guidance

When recovering an operator transformation from partial notes, first reconstruct
the exact term tuple and coefficient, then normal-order it and record
`count_qubits`. Build the smallest Hermitian hopping or number-operator fixture,
map it with JW and the selected alternative, and compare canonical algebra
(`commutator`/`anticommutator`), term counts, and—when feasible—small sparse
matrices. Do not infer a BK or binary-code qubit count from a printed term:
carry the explicit `n_qubits`/code dimensions through the experiment. Preserve
whether a mismatch is a convention issue (mode order, creation order, or
Majorana indexing), an invalid input, or a true transform limitation.

Files in this skill

  • SKILL.md6.5 KB
  • references/api-reference.md10.5 KB
  • references/transforms.md8.6 KB
  • references/troubleshooting.md8.6 KB
  • scripts/smoke_transform.py2.9 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.