Documentation

CsdLean4.Mathlib.QuantumInfo.RegisterTensor

Splitting a qubit register into a Hilbert tensor product #

Category: 1-Mathlib (CSD-free; staged as a Mathlib-upstream candidate).

A register of a + b qubits factors as the Hilbert tensor product of its first a and its last b qubits:

QReg (a + b) ≃ₗᵢ[ℂ] QReg a ⊗[ℂ] QReg b (regTensorEquiv).

This is the identification recorded as missing in MATHLIB-GAPS.md (specs/mathlib-gaps-plan.md MG-5). Mathlib carries the inner-product structure on E ⊗[𝕜] F (Analysis/InnerProductSpace/TensorProduct.lean), but nothing connected it to the concrete EuclideanSpace/PiLp model that QReg uses — so "apply this operator to those wires and the identity elsewhere" could not even be stated.

The construction is two reindexings and an orthonormal basis:

The payoff for consumers is tensorFirst: an operator on the first a qubits extended by the identity on the remaining b, as an operator on QReg (a + b), with tensorFirst_basisState computing its action.

Scope #

Finite-dimensional and concrete throughout; no completion or topological tensor product is involved (in finite dimensions the algebraic tensor product already carries the Hilbert structure). The split is at a prefix of the wires; an arbitrary wire subset would compose this with a permutation reindexing, which is not done here.

References #

QuantumInfo/Register.lean (QReg, basisState); MATHLIB-GAPS.md (the register tensor-factorisation row this closes); specs/mathlib-gaps-plan.md (MG-5).

The product-index model is a tensor product #

The concrete model of a Hilbert tensor product: a Euclidean space on a product index is the tensor product of the Euclidean spaces on the factors. Both sides carry orthonormal bases indexed by ι × κ — the standard basis on the left, the tensor of the standard bases on the right — so the isometry is the change of basis.

Equations
Instances For

    On standard basis vectors the identification is the expected one.

    Splitting the wire index #

    def QuantumInfo.regSplitEquiv (a b : ) :
    (Fin (a + b)Fin 2) (Fin aFin 2) × (Fin bFin 2)

    The index bijection behind the register split: a bitstring on a + b wires is a pair of bitstrings, on the first a and the last b.

    Equations
    Instances For
      @[simp]
      theorem QuantumInfo.regSplitEquiv_apply (a b : ) (z : Fin (a + b)Fin 2) :
      (regSplitEquiv a b) z = (fun (i : Fin a) => z (Fin.castAdd b i), fun (j : Fin b) => z (Fin.natAdd a j))
      noncomputable def QuantumInfo.splitReg (a b : ) :
      QReg (a + b) ≃ₗᵢ[] EuclideanSpace ((Fin aFin 2) × (Fin bFin 2))

      The register split, as an isometry onto the product-indexed Euclidean space.

      Equations
      Instances For
        @[simp]
        theorem QuantumInfo.splitReg_basisState (a b : ) (z : Fin (a + b)Fin 2) :

        ★★ The register tensor factorisation #

        noncomputable def QuantumInfo.regTensorEquiv (a b : ) :

        ★★ A register splits as a Hilbert tensor product of its wire blocks.

        Equations
        Instances For
          @[simp]
          theorem QuantumInfo.regTensorEquiv_basisState (a b : ) (z : Fin (a + b)Fin 2) :
          (regTensorEquiv a b) (basisState z) = (basisState fun (i : Fin a) => z (Fin.castAdd b i)) ⊗ₜ[] basisState fun (j : Fin b) => z (Fin.natAdd a j)

          The factorisation acts as expected on computational basis states: a bitstring goes to the tensor of its two blocks.

          Operators on a wire block, extended by the identity #

          noncomputable def QuantumInfo.tensorFirst {a b : } (A : QReg a →L[] QReg a) :
          QReg (a + b) →L[] QReg (a + b)

          An operator on the first a wires, extended by the identity on the last b — the "local tensor factor" a register-level statement needs.

          Equations
          • One or more equations did not get rendered due to their size.
          Instances For
            theorem QuantumInfo.tensorFirst_apply {a b : } (A : QReg a →L[] QReg a) (v : QReg (a + b)) :
            theorem QuantumInfo.tensorFirst_basisState {a b : } (A : QReg a →L[] QReg a) (z : Fin (a + b)Fin 2) :
            (tensorFirst A) (basisState z) = (regTensorEquiv a b).symm (A (basisState fun (i : Fin a) => z (Fin.castAdd b i)) ⊗ₜ[] basisState fun (j : Fin b) => z (Fin.natAdd a j))

            The action on computational basis states: the operator hits the first block, the second block rides along. This is the computation rule a hybrid-circuit argument consumes.

            @[simp]

            The identity extends to the identity.