Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZNE doesn't repeat RX or CNOT gates when there is no RX or CNOT in the circuit #1305

Open
mho291 opened this issue Apr 25, 2024 · 1 comment
Assignees
Labels
bug Something isn't working
Milestone

Comments

@mho291
Copy link

mho291 commented Apr 25, 2024

Describe the bug
Zero Noise Extrapolation (ZNE) is a quantum error mitigation technique that creates a few circuits with increasing amounts of noise in each circuit. Then it computes the expectation value of the observable and extrapolates backwards to the zero-noise limit.

I have noticed that the function get_noisy_circuit is used to artificially create noisy circuits by repeating some (U * U^dagger) pairs. It looks like this get_noisy_circuit(circuit, num_insertions, insertion_gate). The insertion_gate can either be RX or CNOT while num_insertion >= 1.

I've ran various scenarios:

  1. When the circuit contains n number of CNOT gates, and we have insertion_gate = CNOT, each of the n CNOTs has an extra num_insertion (CNOT * CNOT)s appended. This is ok.
  2. When the circuit contains n number of RX gates, and we have insertion_gate = RX, we expect to see num_insertion (RX * RX`^dagger) gates being appended. However, none appears.
  3. When the circuit contains no RX or CNOT gates and insertion_gate = RX or insertion_gate = CNOT, we do not see num_insertion (RX * RX^dagger) or num_insertion (CNOT * CNOT) gates being appended.

Scenarios 2 and 3 appear to have some issue.

Code to reproduce scenarios 1, 2

from qibo import Circuit, gates
import numpy as np
from qibo.models.error_mitigation import get_noisy_circuit

circuit = Circuit(2)
circuit.add(gates.H(0))
circuit.add(gates.RX(0, np.pi/3))
circuit.add(gates.CNOT(0, 1))
circuit.add(gates.CZ(0, 1))
circuit.add(gates.iSWAP(0, 1))
circuit.add(gates.H(0))
circuit.add(gates.H(1))
circuit.add(gates.CNOT(1, 0))
circuit.add(gates.M(0, 1))

print('Original circuit')
print(circuit.draw())

ZNE_circuit = get_noisy_circuit(circuit, num_insertions = 1, insertion_gate = "CNOT")
print('ZNE_circuit')
print(ZNE_circuit.draw())

ZNE_circuit2 = get_noisy_circuit(circuit, num_insertions = 1, insertion_gate = "RX")
print('ZNE_circuit2')
print(ZNE_circuit2.draw())

Running this code gives this output:

Original circuit:
q0: ─HRXooiHXMq1: ──────XZiHoMZNE_circuit:
q0: ─HRXooooiHXXXMq1: ──────XXXZiHoooMZNE_circuit2:
q0: ─HRXooiHXMq1: ──────XZiHoM

Code to reproduce scenario 3

circuit = Circuit(2)
circuit.add(gates.H(0))
circuit.add(gates.CZ(0, 1))
circuit.add(gates.M(0, 1))

print('Original circuit')
print(circuit.draw())

ZNE_circuit3 = get_noisy_circuit(circuit, num_insertions = 1, insertion_gate = "CNOT")

print('ZNE circuit3:')
print(ZNE_circuit3.draw())

ZNE_circuit4 = get_noisy_circuit(circuit, num_insertions = 1, insertion_gate = "RX")
print('ZNE circuit4:')
print(ZNE_circuit4.draw())

Running this code gives:

Original circuit
q0: ─HoMq1: ───ZMZNE circuit3:
q0: ─HoMq1: ───ZMZNE circuit4:
q0: ─HoMq1: ───ZM
@mho291 mho291 added the bug Something isn't working label Apr 25, 2024
@mho291
Copy link
Author

mho291 commented May 29, 2024

Update; Fixing this with a global unitary folding under pull request #1327.

@MatteoRobbiati MatteoRobbiati added this to the Qibo 0.2.9 milestone Jun 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants