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
363 stars 160 forks source link

Fix idle qubit register indexing #1255

Closed Aaron-Robertson closed 1 year ago

Aaron-Robertson commented 2 years ago

Pre-Report Checklist

Issue Description

Qiskit circuits built on registers like qiskit.QuantumRegister(1) for _ in range(4) insert (and remove) idle identities poorly, in particular when combined with DDD. Qubit index returns 0 for registers of the given type (and so other qubits are altered).

How to Reproduce

Code Snippet

import qiskit
from mitiq.ddd.insertion import insert_ddd_sequences
from mitiq.ddd.rules import xx, xyxy

qreg = [qiskit.QuantumRegister(1) for _ in range(4)]
circuit_qiskit_one = qiskit.QuantumCircuit(*qreg)
for q in qreg:
    circuit_qiskit_one.x(q)
    circuit_qiskit_one.x(3)

print(circuit_qiskit_one)
print(insert_ddd_sequences(circuit_qiskit_one, xyxy))

Error Output


    ┌───┐                    
q0: ┤ X ├────────────────────
    ├───┤                    
q1: ┤ X ├────────────────────
    ├───┤                    
q2: ┤ X ├────────────────────
    ├───┤┌───┐┌───┐┌───┐┌───┐
q3: ┤ X ├┤ X ├┤ X ├┤ X ├┤ X ├
    └───┘└───┘└───┘└───┘└───┘
    ┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐
q0: ┤ X ├┤ I ├┤ X ├┤ Y ├┤ X ├┤ Y ├
    ├───┤├───┤├───┤├───┤├───┤├───┤
q1: ┤ X ├┤ I ├┤ X ├┤ Y ├┤ X ├┤ Y ├
    ├───┤├───┤├───┤├───┤├───┤├───┤
q2: ┤ X ├┤ I ├┤ X ├┤ Y ├┤ X ├┤ Y ├
    ├───┤├───┤├───┤├───┤├───┤├───┤
q3: ┤ X ├┤ X ├┤ X ├┤ X ├┤ X ├┤ I ├
    └───┘└───┘└───┘└───┘└───┘└───┘
andreamari commented 2 years ago

Assigned to @Rahul-Mistri !

natestemen commented 2 years ago

Can someone who has a bit more context here please provide what the expected output is? @Aaron-Robertson @andreamari @Rahul-Mistri

andreamari commented 2 years ago

I think the expected result is the following:

     ┌───┐                    
q_0: ┤ X ├────────────────────
     ├───┤                    
q_1: ┤ X ├────────────────────
     ├───┤                    
q_2: ┤ X ├────────────────────
     ├───┤┌───┐┌───┐┌───┐┌───┐
q_3: ┤ X ├┤ X ├┤ X ├┤ X ├┤ X ├
     └───┘└───┘└───┘└───┘└───┘
     ┌───┐┌───┐┌───┐┌───┐┌───┐
q_0: ┤ X ├┤ X ├┤ Y ├┤ X ├┤ Y ├
     ├───┤├───┤├───┤├───┤├───┤
q_1: ┤ X ├┤ X ├┤ Y ├┤ X ├┤ Y ├
     ├───┤├───┤├───┤├───┤├───┤
q_2: ┤ X ├┤ X ├┤ Y ├┤ X ├┤ Y ├
     ├───┤├───┤├───┤├───┤├───┤
q_3: ┤ X ├┤ X ├┤ X ├┤ X ├┤ X ├
     └───┘└───┘└───┘└───┘└───┘
Misty-W commented 2 years ago

hi @Rahul-Mistri, wanted to check if you're planning to work on this issue in the current milestone (0.21, closes Nov 30). If not, no worries, someone on the UF team can pick this up.

Happy to help clear any roadblocks!

natestemen commented 2 years ago

I took a look at this today and it seems to be a bit thorny. The problem goes away if one defines their circuit using a single register:

qreg = qiskit.QuantumRegister(4)
circuit_qiskit_one = qiskit.QuantumCircuit(qreg)
...

I'm not familiar enough with Qiskit to know if both are widely used, but it would be good to have these functions work regardless of how a user defined their circuit.

The problem arises because we use the index attribute of Qubit objects, which is register dependent, and hence how one defines their circuit affects the results of both https://github.com/unitaryfund/mitiq/blob/6af27485859e1b284d2607d5ef901078a303931b/mitiq/interface/mitiq_qiskit/conversions.py#L121-L123 and https://github.com/unitaryfund/mitiq/blob/6af27485859e1b284d2607d5ef901078a303931b/mitiq/interface/mitiq_qiskit/conversions.py#L150-L153

This issue, should probably be address in tandem with https://github.com/unitaryfund/mitiq/issues/1422. In fact they may be the same issue, really.

@Rahul-Mistri do you have any notes on this that differ/agree with my understanding?