The error you're encountering is because the Qiskit backend isn't able to compute the expectation value of an operator on a circuit that contains classical measurement instructions.
To compute the expectation value after the measurements, you'd typically have to:
- Run the circuit for multiple shots
- For each shot, obtain the measurement result and calculate the expectation value
- Average the results of the expectation values over all shots
Here's how this could look:
# Create the Observable using SparsePauliOp
X = SparsePauliOp(Pauli('X'))
M_hat = X.tensor(X).tensor(X).tensor(X).tensor(X).tensor(X)
matrix_m_hat = np.real(M_hat.to_matrix())
n = 6
# Quantum circuit
psi = QuantumCircuit(n)
psi.x(0)
psi.h(1)
psi.measure_all()
# Use Aer's qasm_simulator
backend = Aer.get_backend('qasm_simulator')
t_qc = transpile(psi, backend=backend)
result = backend.run(t_qc, shots=1000).result()
counts = result.get_counts()
for key, value in counts.items():
# Convert bit string to state vector
idx = int(key, 2) # Convert binary string to integer
state_vector = np.zeros(2**n)
state_vector[idx] = 1
# Calculate expectation value for this outcome
outcome_exp_value = statevector.T.conj() @ matrix_m_hat @ statevector
expectation_value += outcome_exp_value * value
expectation_value /= 1000 # Divide by total number of shots to get the average
print(f"Expectation Value: {np.round(expectation_value,2).real}")
As an alternative, if you are just simulating, you could use a statevector simulator to compute the expectation value directly. With this, you don't have to go through the process of measuring, counting, and then estimating the expectation values. This could look something like:
# Create the Observable using SparsePauliOp
X = SparsePauliOp(Pauli('X'))
M_hat = X.tensor(X).tensor(X).tensor(X).tensor(X).tensor(X)
matrix_m_hat = np.real(M_hat.to_matrix())
# Circuit
psi = QuantumCircuit(6)
psi.x(0)
psi.h(1)
# No measurements or resets needed for statevector simulation
simulator = Aer.get_backend('statevector_simulator')
result = execute(psi, simulator).result()
statevector = np.array(result.get_statevector())
# Compute the expectation value
expectation = statevector.T.conj() @ matrix_m_hat @ statevector
print("expectation: ", expectation.real)
Note that this might not be the most efficient implementation, but is a good illustration of the idea.