|
| 1 | +Let’s say you want to compute the expectation value of the two-qubit Pauli operator: |
| 2 | + |
| 3 | + |
| 4 | + |
| 5 | +\langle \psi(\boldsymbol{\theta}) | X \otimes Y | \psi(\boldsymbol{\theta}) \rangle |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | +This operator acts non-trivially on both qubits, so: |
| 10 | + |
| 11 | + |
| 12 | + |
| 13 | +You must measure both qubits, |
| 14 | +And you must rotate their measurement bases so you’re measuring in the X and Y bases, respectively. |
| 15 | + |
| 16 | + |
| 17 | + |
| 18 | + |
| 19 | + |
| 20 | + |
| 21 | + |
| 22 | +Start in standard basis: All measurements are by default in the computational basis (Z-basis). |
| 23 | +Change basis for X and Y: |
| 24 | +To measure X, apply a Hadamard gate (H): |
| 25 | +H |0\rangle = |+\rangle, H |1\rangle = |-\rangle |
| 26 | +To measure Y, apply S† followed by H: |
| 27 | +H S^\dagger |0\rangle = |+_y\rangle, \quad H S^\dagger |1\rangle = |- _y\rangle |
| 28 | + |
| 29 | +Measure both qubits in Z basis, then multiply results: |
| 30 | +Convert bitstrings to eigenvalues: 0 \mapsto +1, 1 \mapsto -1 |
| 31 | +Compute average of product (qubit 0 value × qubit 1 value) |
| 32 | + |
| 33 | + |
| 34 | + |
| 35 | + |
| 36 | + |
| 37 | + |
| 38 | + |
| 39 | + |
| 40 | + |
| 41 | + |
| 42 | +✅ Qiskit example |
| 43 | + |
| 44 | + |
| 45 | + |
| 46 | +from qiskit import QuantumCircuit, Aer, transpile |
| 47 | +from qiskit.primitives import Sampler |
| 48 | +import numpy as np |
| 49 | + |
| 50 | +# Create a simple 2-qubit state for testing |
| 51 | +qc = QuantumCircuit(2) |
| 52 | +qc.h(0) |
| 53 | +qc.cx(0, 1) # Create Bell state (|00> + |11>)/sqrt(2) |
| 54 | + |
| 55 | +# Rotate to X⊗Y measurement basis |
| 56 | +qc.h(0) # Measure X on qubit 0 |
| 57 | +qc.sdg(1); qc.h(1) # Measure Y on qubit 1 |
| 58 | + |
| 59 | +# Add measurement |
| 60 | +qc.measure_all() |
| 61 | + |
| 62 | +# Sample |
| 63 | +sampler = Sampler() |
| 64 | +result = sampler.run(qc, shots=1000).result() |
| 65 | +counts = result.quasi_dists[0] |
| 66 | + |
| 67 | +# Map bitstrings to +1/-1 eigenvalues |
| 68 | +def pauli_xy_expectation(counts): |
| 69 | + expval = 0 |
| 70 | + for bitstring, prob in counts.items(): |
| 71 | + # Qiskit stores bitstring as little-endian |
| 72 | + b0 = 1 if bitstring[-1] == '0' else -1 # qubit 0 (X) |
| 73 | + b1 = 1 if bitstring[-2] == '0' else -1 # qubit 1 (Y) |
| 74 | + expval += b0 * b1 * prob |
| 75 | + return expval |
| 76 | + |
| 77 | +print("Estimated ⟨X ⊗ Y⟩:", pauli_xy_expectation(counts)) |
| 78 | +💡 Expected result: ~0 for Bell state, because ⟨X⊗Y⟩ vanishes due to symmetry. |
| 79 | + |
| 80 | + |
| 81 | + |
| 82 | + |
| 83 | + |
| 84 | + |
| 85 | + |
| 86 | +✅ PennyLane version |
| 87 | + |
| 88 | + |
| 89 | + |
| 90 | +import pennylane as qml |
| 91 | +from pennylane import numpy as np |
| 92 | + |
| 93 | +dev = qml.device("default.qubit", wires=2, shots=1000) |
| 94 | + |
| 95 | +@qml.qnode(dev) |
| 96 | +def xy_expectation(): |
| 97 | + # Prepare Bell state |
| 98 | + qml.Hadamard(0) |
| 99 | + qml.CNOT([0, 1]) |
| 100 | + # Measure X⊗Y |
| 101 | + return qml.expval(qml.PauliX(0) @ qml.PauliY(1)) |
| 102 | + |
| 103 | +print("Estimated ⟨X ⊗ Y⟩:", xy_expectation()) |
| 104 | +This uses PennyLane’s abstract Pauli operators and handles basis rotation for you internally. |
| 105 | + |
| 106 | + |
| 107 | + |
| 108 | + |
| 109 | + |
| 110 | + |
| 111 | + |
| 112 | + |
| 113 | +🧠 Summary |
| 114 | + |
| 115 | + |
| 116 | + |
| 117 | +Goal |
| 118 | + |
| 119 | +What you do |
| 120 | + |
| 121 | +Measure ⟨X⟩ |
| 122 | + |
| 123 | +Apply H, then measure |
| 124 | + |
| 125 | +Measure ⟨Y⟩ |
| 126 | + |
| 127 | +Apply S† + H, then measure |
| 128 | + |
| 129 | +Measure ⟨X ⊗ Y⟩ |
| 130 | + |
| 131 | +Apply above rotations to both qubits, measure both, and post-process |
0 commit comments