Skip to content

Observable Notation Reference

QuartumSE uses Pauli strings to specify quantum observables for expectation value estimation. This guide explains the notation, common patterns, and expected values for standard quantum states.


Pauli String Syntax

Basic Format

An observable is written as a string of Pauli operators, one per qubit:

from quartumse.shadows.core import Observable

# Single-qubit observables
Observable("X")     # X (Pauli-X) on qubit 0
Observable("Y")     # Y (Pauli-Y) on qubit 0
Observable("Z")     # Z (Pauli-Z) on qubit 0
Observable("I")     # I (Identity) on qubit 0

# Multi-qubit observables
Observable("ZII")   # Z on qubit 0, Identity on qubits 1 and 2
Observable("ZZI")   # Z on qubits 0 and 1, Identity on qubit 2
Observable("ZZZ")   # Z on all three qubits
Observable("XXX")   # X on all three qubits

Qubit Ordering

QuartumSE uses little-endian (Qiskit-style) qubit ordering: - Leftmost character = qubit 0 - Rightmost character = highest-index qubit

# For a 3-qubit circuit
Observable("XYZ")
# X on qubit 0
# Y on qubit 1
# Z on qubit 2

Coefficients

Observables can have multiplicative coefficients:

Observable("ZZ", coefficient=0.5)   # 0.5 × Z₀Z₁
Observable("XX", coefficient=-1.0)  # -1.0 × X₀X₁

Output format: Results use {coefficient}*{pauli_string} notation:

result.observables.keys()
# Returns: ['1.0*ZII', '1.0*ZZI', '1.0*ZZZ']


Pauli Operator Properties

Eigenvalues

All Pauli operators have eigenvalues ±1:

Operator Eigenstate Eigenvalue
X |+⟩ = (|0⟩ + |1⟩)/√2 +1
X |-⟩ = (|0⟩ - |1⟩)/√2 -1
Y |i+⟩ = (|0⟩ + i|1⟩)/√2 +1
Y |i-⟩ = (|0⟩ - i|1⟩)/√2 -1
Z |0⟩ +1
Z |1⟩ -1

Commutation Relations

  • Observables commute if they share qubits only on I or matching Pauli operators
  • Observables anticommute if they differ on an odd number of qubits
# Commuting observables (can measure simultaneously)
Observable("ZII") and Observable("ZZI")  # ✓ commute
Observable("XII") and Observable("YZZ")  # ✓ commute (different qubits)

# Anticommuting observables (cannot measure simultaneously)
Observable("XII") and Observable("ZII")  # ✗ anticommute (differ on qubit 0)
Observable("ZZ") and Observable("XZ")    # ✗ anticommute (differ on qubit 0)

Expected Values for Common States

Computational Basis States

|00⟩ state:

Observable("ZI"): +1.0   # Z₀ = +1 (qubit 0 is |0⟩)
Observable("IZ"): +1.0   # Z₁ = +1 (qubit 1 is |0⟩)
Observable("ZZ"): +1.0   # Z₀Z₁ = (+1)(+1) = +1
Observable("XI"):  0.0   # X₀ = 0 (|0⟩ is equal superposition of X eigenstates)
Observable("XX"):  0.0   # X₀X₁ = 0

|11⟩ state:

Observable("ZI"): -1.0   # Z₀ = -1 (qubit 0 is |1⟩)
Observable("IZ"): -1.0   # Z₁ = -1 (qubit 1 is |1⟩)
Observable("ZZ"): +1.0   # Z₀Z₁ = (-1)(-1) = +1
Observable("XI"):  0.0   # X₀ = 0
Observable("XX"):  0.0   # X₀X₁ = 0

Bell States

|Φ⁺⟩ = (|00⟩ + |11⟩)/√2 (Bell state):

Observable("ZI"):  0.0   # Equal |0⟩ and |1⟩ on qubit 0
Observable("IZ"):  0.0   # Equal |0⟩ and |1⟩ on qubit 1
Observable("ZZ"): +1.0   # Correlated: both qubits have same parity
Observable("XX"): +1.0   # Both qubits in X-basis |+⟩
Observable("YY"): -1.0   # Y correlation
Observable("XY"):  0.0   # No XY correlation

|Ψ⁻⟩ = (|01⟩ - |10⟩)/√2 (singlet state):

Observable("ZI"):  0.0
Observable("IZ"):  0.0
Observable("ZZ"): -1.0   # Anti-correlated
Observable("XX"): -1.0
Observable("YY"): -1.0
Observable("XZ"):  0.0

GHZ States

|GHZ(3)⟩ = (|000⟩ + |111⟩)/√2:

GHZ states are stabilized by even-parity Z operators:

# Single-qubit Z observables → 0 (equal superposition)
Observable("ZII"):  0.0
Observable("IZI"):  0.0
Observable("IIZ"):  0.0

# Two-qubit Z observables → +1 (even parity stabilizers)
Observable("ZZI"): +1.0
Observable("ZIZ"): +1.0
Observable("IZZ"): +1.0

# Three-qubit Z observables → -1 (odd parity)
Observable("ZZZ"): -1.0

# X observables
Observable("XXX"): +1.0  # All qubits in |+⟩ superposition
Observable("XII"):  0.0  # Single X → 0
Observable("XXI"):  0.0  # Two X's → 0

Rule for GHZ: - Even number of Z operators → +1 - Odd number of Z operators → 0 (for single Z) or -1 (for all Z)

|GHZ(4)⟩ = (|0000⟩ + |1111⟩)/√2:

Observable("ZIII"):  0.0
Observable("ZZII"): +1.0
Observable("ZZZI"): +1.0
Observable("ZZZZ"): +1.0  # Even number (4) of Z's
Observable("XXXX"): +1.0

W States

|W(3)⟩ = (|001⟩ + |010⟩ + |100⟩)/√3:

Observable("ZII"): -1/3  # Two |0⟩ components, one |1⟩
Observable("IZI"): -1/3
Observable("IIZ"): -1/3
Observable("ZZZ"): -1/3  # Mix of even/odd parities
Observable("XXX"):  1/3  # Partial correlation

Hamiltonian Observables

Many quantum algorithms estimate Hamiltonian energy:

Ising Model (1D chain)

# H = Σᵢ JᵢZᵢZᵢ₊₁ + ΣᵢhᵢZᵢ
# For 3 qubits with J=-1.0, h=0.5:

Observable("ZZI", coefficient=-1.0)  # Z₀Z₁ interaction
Observable("IZZ", coefficient=-1.0)  # Z₁Z₂ interaction
Observable("ZII", coefficient=0.5)   # Z₀ field
Observable("IZI", coefficient=0.5)   # Z₁ field
Observable("IIZ", coefficient=0.5)   # Z₂ field

# Total energy = sum of all observable expectation values

Molecular Hamiltonians (VQE)

# H₂ molecule (example coefficients)
Observable("II", coefficient=-0.8105)    # Identity term
Observable("ZI", coefficient=0.1721)     # Z₀ term
Observable("IZ", coefficient=0.1721)     # Z₁ term
Observable("ZZ", coefficient=-0.2279)    # Z₀Z₁ correlation
Observable("XX", coefficient=0.1809)     # XX exchange
Observable("YY", coefficient=0.1809)     # YY exchange

Interpreting Results

Confidence Intervals

QuartumSE reports 95% confidence intervals around expectation values:

result.observables["1.0*ZZZ"]
# {
#     'expectation_value': -0.9922,
#     'variance': 0.0156,
#     'ci_95': (-1.0353, -0.9491),
#     'ci_width': 0.0862
# }

Interpretation: - Expectation value: -0.9922 (close to theoretical -1.0 for GHZ) - Variance: 0.0156 (measurement uncertainty) - 95% CI: [-1.0353, -0.9491] (true value likely in this range) - CI width: 0.0862 (precision measure; smaller is better)

Comparing to Theory

Example: GHZ(3) validation

# Theoretical expectations
theory = {
    "1.0*ZII":  0.0,
    "1.0*ZZI": +1.0,
    "1.0*ZZZ": -1.0,
}

# Experimental results
for obs_str, data in result.observables.items():
    estimated = data['expectation_value']
    expected = theory[obs_str]
    ci = data['ci_95']

    # Check if theory is within confidence interval
    in_ci = ci[0] <= expected <= ci[1]
    status = "✓" if in_ci else "✗"

    print(f"{obs_str:10} Est: {estimated:+.4f}  "
          f"Theory: {expected:+.4f}  {status}")

Output:

1.0*ZII    Est: +0.0039  Theory: +0.0000  ✓
1.0*ZZI    Est: +0.9961  Theory: +1.0000  ✓
1.0*ZZZ    Est: -0.9922  Theory: -1.0000  ✓


Common Patterns

Entanglement Witnesses

CHSH Inequality:

# S = |⟨XX⟩ + ⟨XY⟩ + ⟨YX⟩ - ⟨YY⟩|
# Classical limit: S ≤ 2
# Quantum (Bell state): S = 2√2 ≈ 2.828

Observable("XX")  # ⟨XX⟩
Observable("XY")  # ⟨XY⟩
Observable("YX")  # ⟨YX⟩
Observable("YY")  # ⟨YY⟩

Fidelity Estimation

Overlap with target state |ψ⟩:

# F = ⟨ψ|ρ|ψ⟩ = Σᵢ ⟨Pᵢ⟩ / 2ⁿ
# where Pᵢ are stabilizer observables

# For GHZ(3):
observables = [
    Observable("ZZI"),  # Stabilizer 1
    Observable("IZZ"),  # Stabilizer 2
]
# F ≈ (1 + ⟨ZZI⟩ + ⟨IZZ⟩ + ⟨ZZI⟩⟨IZZ⟩) / 4

Symmetry Testing

Check parity symmetry:

# Even parity: should be +1 or -1
Observable("ZZZZ")

# If result ≈ 0, state lacks definite parity
# (e.g., equal mixture of even/odd states)


Further Reading


Quick Reference

Observable Name Measures
I Identity Always +1
X Pauli-X X-basis projection
Y Pauli-Y Y-basis projection
Z Pauli-Z Computational basis projection
ZZ Z-correlation Parity between two qubits
XX X-correlation X-basis entanglement
ZZZ 3-qubit parity Stabilizer for GHZ states

Tip: When debugging, start with Z observables (ZI, ZZ, etc.) since they measure in the computational basis and are easier to interpret from bitstring histograms.