1
$\begingroup$

I want to use IBMQ's runtime Estimator primitive to address their systems. Since it has no function to return the transpiled circuit, but I need the knowledge what circuit exactly was executed in the end, I want to do the transpilation locally and then give that circuit into the estimator.

For the transpiling I add the needed post-rotations for measuring non-PauliZ, then add the classical registers for the measurements and then transpile this circuit. So I end up with a complete circuit with classical registers and qubits on which nothing happens, they are just part of the device. (see code below)

What is a elegant way to separate this into a circuit and an observable that I can pass to the estimator?

minimal `code example:

from qiskit import QuantumCircuit, transpile, IBMQ
from qiskit_ibm_runtime import QiskitRuntimeService
backend='ibmq_quito'
service=QiskitRuntimeService()
backend=service.get_backend(backend)

#circuit
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)

#post-rotations: want to measure 'XZ'
meas_circuit= QuantumCircuit(2)
meas_circuit.h(0)

#add post-rotations to circuit
full_circ=circuit.compose(meas_circuit).measure_all(inplace=False)

#transpile
trans_circ = transpile(full_circ, backend)

print(trans_circ)

I want to use the estimator to measure the expectation value of ZZ on the non-idle qubits of trans_circ.

Since I need the same number of observables and qubits, can I just take the identity as observable for the qubits I am not interested in? Those will just give factors of 1 to each term of the expectation value. What I tried was:

service=QiskitRuntimeService()
session=Session(service=service, backend=backend)
options=Options()
options.resilience_level=3
estimator=Estimator(session=session, options=options)

params=[]
obs=SparsePauliOp.from_list([("IIIZZ", 1)])


job=estimator.run(circuits=trans_circ, observables=obs, parameter_values=params)
expvals=job.result().values
print(expvals)

This gives me some output, but I am not sure whether it is correct: It returns values around 0.95 while I calculated an expectation value of 0.5 on paper. Is there a mistake or do I see the impact of noise of the hardware here like in this question?

Also what happens to the measurement instructions here? Are they ignored? Do I need them or better separate?

$\endgroup$
1
  • $\begingroup$ Can you add your code in the description? That way others can help you better. $\endgroup$ Dec 15, 2022 at 17:41

1 Answer 1

1
$\begingroup$

The problem here should be in how your are creating your SparsePauliOp observable: if you want to measure the expectation value of $Z_0Z_1$ (non-idle qubits of the transpiled circuit), you have to do

obs = SparsePauliOp.from_list([("IIIZZ", 1)])

and not

obs = SparsePauliOp.from_list([("ZZIII", 1)])

Take a look to the qiskit.quantum_info.SparsePauliOp.from_list documentation for more details.

$\endgroup$
4
  • $\begingroup$ Thank you for this note. I have overseen this completely. I changed the code above accordingly. But this still doesn't give me the expected result. $\endgroup$ Dec 19, 2022 at 12:51
  • $\begingroup$ Could you give some more details about the expected result you are looking for? $\endgroup$ Jan 13, 2023 at 9:52
  • $\begingroup$ I tested it again with error mitigation. With that I get reasonable results of ~-0.009 when I expect 0 as expectation value. It seems like the deviance I have seen is actually due to the hardware errors only. $\endgroup$ Jan 13, 2023 at 12:22
  • $\begingroup$ The question remaining is what happens to the measurement instructions? Are they ignored in any case or do they influence my result and I just don't see it in my simple example? $\endgroup$ Jan 13, 2023 at 12:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.