unitaryfund / mitiq

Mitiq is an open source toolkit for implementing error mitigation techniques on most current intermediate-scale quantum computers.
https://mitiq.readthedocs.io
GNU General Public License v3.0
358 stars 157 forks source link

`pec.sample_circuit` drops idle qubits #2061

Closed rmlarose closed 10 months ago

rmlarose commented 11 months ago

Issue Description

Circuits returned by pec.sample_circuit do not contain idle qubits present in the original circuit, and also have different register names.

How to Reproduce

import qiskit
from mitiq import pec

# Circuit.
qreg = qiskit.QuantumRegister(3, name="Q")
circuit = qiskit.QuantumCircuit(qreg)
circuit.h(qreg[0])
circuit.cnot(qreg[0], qreg[1])
circuit.measure_active()
print(circuit)
#            ┌───┐      ░ ┌─┐   
#       Q_0: ┤ H ├──■───░─┤M├───
#            └───┘┌─┴─┐ ░ └╥┘┌─┐
#       Q_1: ─────┤ X ├─░──╫─┤M├
#                 └───┘ ░  ║ └╥┘
#       Q_2: ───────────░──╫──╫─
#                       ░  ║  ║ 
# measure: 2/══════════════╩══╩═
#                          0  1 

# Representation.
cnot_circuit = qiskit.QuantumCircuit(qreg)
cnot_circuit.cnot(qreg[0], qreg[1])
rep = pec.represent_operation_with_global_depolarizing_noise(cnot_circuit, noise_level=0.01)

# Sample.
circuits, *_ = pec.sample_circuit(circuit, [rep])
for circuit in circuits:
    print(circuit)
#                    ┌───┐     ┌─┐   
#               q_0: ┤ H ├──■──┤M├───
#                    └───┘┌─┴─┐└╥┘┌─┐
#               q_1: ─────┤ X ├─╫─┤M├
#                         └───┘ ║ └╥┘
# m_reg_measure_0: 1/═══════════╩══╬═
#                               0  ║ 
# m_reg_measure_1: 1/══════════════╩═
#                                  0 

Expected behavior

The circuit(s) returned by pec.sample_circuit should have the same registers and qubits as the input circuit: here, one register named "Q", the qubit "Q_2" present, and one measurement register named "measure" with two bits.


Environment Context Use the `about()` function to summarize information on operating system, python version and dependencies. ```python from mitiq import about about() ``` ```text Mitiq: A Python toolkit for implementing error mitigation on quantum computers ============================================================================== Authored by: Mitiq team, 2020 & later (https://github.com/unitaryfund/mitiq) Mitiq Version: 0.30.0 Core Dependencies ----------------- Cirq Version: 1.2.0 NumPy Version: 1.26.1 SciPy Version: 1.11.2 Optional Dependencies --------------------- PyQuil Version: 3.2.1 Qiskit Version: 0.44.2 Braket Version: Not installed Python Version: 3.10.13 Platform Info: Linux (x86_64) ``` Additional Python Environment Details (`pip freeze` or `conda list`): ``` Copy and paste the output of `pip freeze` or `conda list` here. ```
andreamari commented 11 months ago

Some additional info about this issue:

other Mitiq techniques such as ZNE and DDD work correctly, since they make use of the following decorator which handles many conversion problems, including qiskit idle qubits: https://github.com/unitaryfund/mitiq/blob/68b2b12230a1c00077ffd23cef8c122f63daf200/mitiq/interface/conversions.py#L261

The decorator is not used in pec.sample_circuit, and this fact is the origin of the problem.

My suggestion would be to find a way to apply the decorator accept_qprogram_and_validate or a similar new decorator to pec.sample_circuit.

Note that, unfortunately, sample_circuit maps 1 circuit to many circuits, while the existing decorator accept_qprogram_and_validate works with functions mapping 1 circuit to 1 circuit. So one cannot just write @accept_qprogram_and_validate on top of def sample_circuit().

rmlarose commented 11 months ago

Thanks @andreamari I also identified this as the origin of the issue. I remember going through this process with ZNE and I think PEC just needs to use the fixes we implemented there. Hopefully it's fairly easy to do - perhaps a sample_once function which could be wrapped by the decorator and then is repeatedly called by sample_circuit?

andreamari commented 11 months ago

That could work but I am checking if it's possible to have a one-to-many decorator which would make things more efficients. In the past I remember that sampling circuits one-by-one was very slow and so we decided to sample all circuits in a single batch.