# Measurement of readout errors for error mitigation algorithms

I am using an error mitigation algorithm that uses the readout errors p(0|1) and p(1|0) to correct the errors due to noise in my original circuit. I am trying to measure the readout errors in the same circuit as shown in the image. As shown in the circuit, I am resetting the two qubits twice.

The first part of the circuit corresponds to my original algorithm and in the second and the third parts I am measuring the readout error of the two qubits by observing the counts.

I've tried calculating the readout error rates using a separate circuit but I notice that the readout error rates fluctuate considerably within short periods of time, so they might change between the execution of my original circuit and readout error measurement circuit. Also, it is tricky to map the readout error measurement circuit to the same physical qubits which are being used by my original circuit.

I know that I can use the library function backend.properties().readout_error(n), but it returns the average of p(0|1) and p(1|0) and it stays constant over time but the actual measured readout error fluctuates over time.

1. Is this a reasonable way to calculate the readout error rates of the two qubits?
2. Is there a better way to accomplish what I am trying to do?

backend.properties().readout_error(n) provides the (latest) readout error calibration data for qubit n. So, this does provide a reasonable measure of the expected readout error rate for that qubit.

You are on the right track for quantifying readout errors. See this qiskit page. You can use $$2^n$$ (where n $$n$$ is the number of qubits) circuits composed of preparing all binary sequences of length n with Pauli X gates (or no Pauli X gates) in order to get a full $$nxn$$ confusion matrix with respect to the readout errors. This confusion matrix can then be used to mitigate measurement errors for a circuit that was run on those $$n$$ qubits. As you correctly pointed out, it is important to get those calibration circuits to be near in time to your main problem circuit, because error rates do drift over time.

I assume based on your use of mid circuit measurements and resets, you want to get good measurement error rates as close in time to your original circuit as possible. This is certainly an option, however if you couple several circuits into a job you should be able to separate out your original circuit and your readout error measurements.

You mentioned having problems making sure your logical circuit is always mapped to the same physical qubits. There are two things I have found which make this possible to do.

First, you can locally transpile the circuit with a specific initial layout: qiskit.compiler.transpile(circuit, initial_layout=[1, 2, 3, 4]). You will also need to supply the coupling_map argument to make sure the connectivity is correct.

Second, directly run the circuit using backend.run(circuit), as opposed to the execute(circuit, backend) method which calls the transpiler before sending it to the backend.

However, I would advise inspecting the job metadata after you have run a job in order to pull out the compiled circuit(s) to make sure it is the structure and connectivity you wanted.

• What about optimization_level? Does Qiskit respect the initial_layout even if optimization_level is set to the maximum ie. 3? Commented Jan 18, 2023 at 0:20
• Right, excellent question. Short answer: I would advice trying it out for yourself to double check because the transpiler behavior is not deterministic, even when seeded (at least this was the case for some versions that I worked with). I think that the transpiler almost always respects the initial layout even when optimization_level=3. There are exceptions though, for example for very large circuit sizes sometimes ancilla qubits that are outside of that initial layout will be used to help decrease gate depth with while using swapping. Commented Jan 18, 2023 at 2:52