Interface: Introduction

In this example, we demonstrate how to convert between the True-Q™ python circuit representation and other popular third party representations. These conversions will only be available if the corresponding python packages are installed.

We start by defining a test circuit to work with:

import trueq as tq

circuit = tq.Circuit(
    [
        {(0,): tq.Gate.x, (1,): tq.Gate.y},
        {(0, 2): tq.Gate.cz, (1,): tq.Gate.x},
        {(3,): tq.Gate.h, (5,): tq.Gate.s},
    ]
)
circuit.measure_all()
True-Q formatting will not be loaded without trusting this notebook or rerunning the affected cells. Notebooks can be marked as trusted by clicking "File -> Trust Notebook".
Circuit
Key:
No key present in circuit.
 
Marker 0
Compilation tools may only recompile cycles with equal markers.
(0): Gate.x
Name:
  • Gate.x
Aliases:
  • Gate.x
  • Gate.cliff1
Generators:
  • 'X': 180.0
Matrix:
  • 1.00 1.00
(1): Gate.y
Name:
  • Gate.y
Aliases:
  • Gate.y
  • Gate.cliff2
Generators:
  • 'Y': 180.0
Matrix:
  • -1.00j 1.00j
 
 
Marker 0
Compilation tools may only recompile cycles with equal markers.
(0, 2): Gate.cz
Name:
  • Gate.cz
Aliases:
  • Gate.cz
Likeness:
  • CNOT
Generators:
  • 'IZ': 90.0
  • 'ZI': 90.0
  • 'ZZ': -90.0
Matrix:
  • 1.00 1.00 1.00 -1.00
(1): Gate.x
Name:
  • Gate.x
Aliases:
  • Gate.x
  • Gate.cliff1
Generators:
  • 'X': 180.0
Matrix:
  • 1.00 1.00
 
 
Marker 0
Compilation tools may only recompile cycles with equal markers.
(3): Gate.h
Name:
  • Gate.h
Aliases:
  • Gate.h
  • Gate.cliff12
Generators:
  • 'X': 127.279
  • 'Z': 127.279
Matrix:
  • 0.71 0.71 0.71 -0.71
(5): Gate.s
Name:
  • Gate.s
Aliases:
  • Gate.s
  • Gate.cliff9
Generators:
  • 'Z': 90.0
Matrix:
  • 0.71 -0.71j 0.71 0.71j
 
1
Marker 1
Compilation tools may only recompile cycles with equal markers.
(0): Meas()
Name:
  • Meas()
(1): Meas()
Name:
  • Meas()
(2): Meas()
Name:
  • Meas()
(3): Meas()
Name:
  • Meas()
(5): Meas()
Name:
  • Meas()


Cirq

Convert the circuit to a Cirq circuit object:

cirq_circuit = circuit.to_cirq()
cirq_circuit
               ┌──┐
(0, 0): ───X────@─────M───
                │     │
(1, 0): ────────┼Z────M───
                │     │
(2, 0): ────────@─────M───
                      │
(3, 0): ────────H─────M───
                      │
(5, 0): ────────S─────M───
               └──┘


Perform the inverse conversion (to_trueq() is monkey-patched onto their circuit object at True-Q™ import time):

cirq_circuit.to_trueq()
True-Q formatting will not be loaded without trusting this notebook or rerunning the affected cells. Notebooks can be marked as trusted by clicking "File -> Trust Notebook".
Circuit
Key:
No key present in circuit.
 
Marker 0
Compilation tools may only recompile cycles with equal markers.
(0): Gate.x
Name:
  • Gate.x
Aliases:
  • Gate.x
  • Gate.cliff1
Generators:
  • 'X': 180.0
Matrix:
  • 1.00 1.00
 
1
Marker 1
Compilation tools may only recompile cycles with equal markers.
(0, 2): Gate.cz
Name:
  • Gate.cz
Aliases:
  • Gate.cz
Likeness:
  • CNOT
Generators:
  • 'IZ': 90.0
  • 'ZI': 90.0
  • 'ZZ': -90.0
Matrix:
  • 1.00 1.00 1.00 -1.00
(1): Gate.z
Name:
  • Gate.z
Aliases:
  • Gate.z
  • Gate.cliff3
Generators:
  • 'Z': 180.0
Matrix:
  • 1.00 -1.00
(3): Gate.h
Name:
  • Gate.h
Aliases:
  • Gate.h
  • Gate.cliff12
Generators:
  • 'X': 127.279
  • 'Z': 127.279
Matrix:
  • 0.71 0.71 0.71 -0.71
(5): Gate.s
Name:
  • Gate.s
Aliases:
  • Gate.s
  • Gate.cliff9
Generators:
  • 'Z': 90.0
Matrix:
  • 1.00 1.00j
 
2
Marker 2
Compilation tools may only recompile cycles with equal markers.
(0): Meas()
Name:
  • Meas()
(1): Meas()
Name:
  • Meas()
(2): Meas()
Name:
  • Meas()
(3): Meas()
Name:
  • Meas()
(5): Meas()
Name:
  • Meas()


PyQuil

Convert the circuit to a PyQuil circuit object:

pyquil_circuit = circuit.to_pyquil()
print(pyquil_circuit)

Out:

DECLARE ro BIT[5]
X 0
CZ 0 2
H 3
S 5
Z 1
MEASURE 0 ro[0]
MEASURE 1 ro[1]
MEASURE 2 ro[2]
MEASURE 3 ro[3]
MEASURE 5 ro[4]

Perform the inverse conversion (to_trueq() is monkey-patched onto their circuit object at True-Q™ import time):

pyquil_circuit.to_trueq()
True-Q formatting will not be loaded without trusting this notebook or rerunning the affected cells. Notebooks can be marked as trusted by clicking "File -> Trust Notebook".
Circuit
Key:
No key present in circuit.
 
Marker 0
Compilation tools may only recompile cycles with equal markers.
(0): Gate.x
Name:
  • Gate.x
Aliases:
  • Gate.x
  • Gate.cliff1
Generators:
  • 'X': 180.0
Matrix:
  • 1.00 1.00
 
 
Marker 0
Compilation tools may only recompile cycles with equal markers.
(0, 2): CZ()
Name:
  • CZ()
Aliases:
  • Gate.cz
Likeness:
  • CNOT
Generators:
  • 'IZ': 90.0
  • 'ZI': 90.0
  • 'ZZ': -90.0
Matrix:
  • 1.00 1.00 1.00 -1.00
(1): Gate.z
Name:
  • Gate.z
Aliases:
  • Gate.z
  • Gate.cliff3
Generators:
  • 'Z': 180.0
Matrix:
  • 1.00 -1.00
(3): Gate.h
Name:
  • Gate.h
Aliases:
  • Gate.h
  • Gate.cliff12
Generators:
  • 'X': 127.279
  • 'Z': 127.279
Matrix:
  • 0.71 0.71 0.71 -0.71
(5): Gate.s
Name:
  • Gate.s
Aliases:
  • Gate.s
  • Gate.cliff9
Generators:
  • 'Z': 90.0
Matrix:
  • 0.71 -0.71j 0.71 0.71j


Qiskit

Convert the circuit to a Qiskit circuit object:

qiskit_circuit = circuit.to_qiskit()
qiskit_circuit.draw("mpl")
interface software

Out:

<Figure size 956.385x618.722 with 1 Axes>

Perform the inverse conversion (to_trueq() is monkey-patched onto their circuit object at True-Q™ import time):

qiskit_circuit.to_trueq()
True-Q formatting will not be loaded without trusting this notebook or rerunning the affected cells. Notebooks can be marked as trusted by clicking "File -> Trust Notebook".
Circuit
Key:
No key present in circuit.
 
Marker 0
Compilation tools may only recompile cycles with equal markers.
(0): Gate.x
Name:
  • Gate.x
Aliases:
  • Gate.x
  • Gate.cliff1
Generators:
  • 'X': 180.0
Matrix:
  • 1.00 1.00
 
 
Marker 0
Compilation tools may only recompile cycles with equal markers.
(0, 2): Gate.cz
Name:
  • Gate.cz
Aliases:
  • Gate.cz
Likeness:
  • CNOT
Generators:
  • 'IZ': 90.0
  • 'ZI': 90.0
  • 'ZZ': -90.0
Matrix:
  • 1.00 1.00 1.00 -1.00
(1): Gate.z
Name:
  • Gate.z
Aliases:
  • Gate.z
  • Gate.cliff3
Generators:
  • 'Z': 180.0
Matrix:
  • 1.00 -1.00
(3): Gate.h
Name:
  • Gate.h
Aliases:
  • Gate.h
  • Gate.cliff12
Generators:
  • 'X': 127.279
  • 'Z': 127.279
Matrix:
  • 0.71 0.71 0.71 -0.71
(5): Gate.s
Name:
  • Gate.s
Aliases:
  • Gate.s
  • Gate.cliff9
Generators:
  • 'Z': 90.0
Matrix:
  • 0.71 -0.71j 0.71 0.71j
 
 
Marker 0
Compilation tools may only recompile cycles with equal markers.
(0): Meas()
Name:
  • Meas()
(1): Meas()
Name:
  • Meas()
(2): Meas()
Name:
  • Meas()
(3): Meas()
Name:
  • Meas()
(5): Meas()
Name:
  • Meas()


Priority Lists

During conversion between representations in True-Q™ and other software packages, there is often a degeneracy in how a gate can be represented. For example, an identity gate could be written as Z(phi), X(phi), Y(phi), … with phi = 0.

In these cases, the priority list associated with the interface to a software package will handle the degeneracy by converting preferentially to gates which appear higher on the priority list.

Each interface has a default priority list and corresponding configuration file preset. To update a priority list and configuration file (using Cirq as an example), users can provide a priority list via set_priority_list() and retrieve the current priority list via get_config(). Replacing cirq in these commands with pyquil or qiskit will interact in the same way with their corresponding interfaces.

Look at the priority list for the interface between True-Q™ and Cirq:

tq.interface.cirq.get_priority_list()

Out:

['I', 'X', 'Y', 'Z', 'H', 'S', 'T', 'CZ', 'CNOT', 'XX', 'YY', 'ZZ', 'ISWAP', 'SWAP', 'rx', 'ry', 'rz', 'FSimGate', 'ms', 'PhasedXPowGate']

Set a limited priority list, containing only CNOT, rx, and rz:

tq.interface.cirq.set_priority_list(["CNOT", "rx", "rz"])

Convert the circuit defined above to Cirq using the updated priority list:

circuit.to_cirq()
(0, 0): ───Rx(π)──────Rz(-0.5π)───@─────────────────────────Rz(0.5π)───M───
                                  │                                    │
(1, 0): ──────────────────────────┼─────────────────────────Rz(π)──────M───
                                  │                                    │
(2, 0): ───Rx(0.5π)───Rz(0.5π)────X───Rz(0.5π)───Rx(0.5π)───Rz(π)──────M───
                                                                       │
(3, 0): ──────────────────────────────Rz(0.5π)───Rx(0.5π)───Rz(0.5π)───M───
                                                                       │
(5, 0): ────────────────────────────────────────────────────Rz(0.5π)───M───


Note

Setting the priority list to None resets to the default priority list.

Reset the priority list to the default:

tq.interface.cirq.set_priority_list(None)

Convert the circuit to Cirq using the default priority list:

circuit.to_cirq()
               ┌──┐
(0, 0): ───X────@─────M───
                │     │
(1, 0): ────────┼Z────M───
                │     │
(2, 0): ────────@─────M───
                      │
(3, 0): ────────H─────M───
                      │
(5, 0): ────────S─────M───
               └──┘


As you can see in the printed circuits, changing the priority list alters the gates used in converting from True-Q™ to other software. For example, removing the X gate from the priority list causes the interface to pick the next viable representation of this operation, so that the X gates are given as rotations about X by \(\pi\).

Total running time of the script: ( 0 minutes 0.256 seconds)

Gallery generated by Sphinx-Gallery