Interface: Introduction

In this example, we show how to use True-Qᵀᴹ’s interface to convert between common software representations of quantum circuits.

Import True-Qᵀᴹ, Cirq, pyQuil, and Qiskit:

import trueq as tq
import cirq
import pyquil
import qiskit

Define a True-Qᵀᴹ circuit:

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},
    ]
)

Convert the circuit into representations in Qiskit, Cirq, and PyQuil:

qiskit_circuit = circuit.to_qiskit()
cirq_circuit = circuit.to_cirq()
pyquil_circuit = circuit.to_pyquil()

Since we have converted the circuit into representations corresponding to different Python packages, each representation will print according to the setup of each package.

Print the circuit compiled for Qiskit:

qiskit_circuit.draw()
     ┌───────────────────┐  ░                          ░
q_0: ┤ U3(pi,-pi/2,pi/2) ├──░──■───────────────────────░─────────────
     ├───────────────────┴┐ ░  │ ┌───────────────────┐ ░
q_1: ┤ U3(pi,-3pi/2,pi/2) ├─░──┼─┤ U3(pi,-pi/2,pi/2) ├─░─────────────
     └────────────────────┘ ░  │ └───────────────────┘ ░
q_2: ───────────────────────░──■───────────────────────░─────────────
                            ░                          ░ ┌──────────┐
q_3: ───────────────────────░──────────────────────────░─┤ U2(0,pi) ├
                            ░                          ░ └──────────┘
q_4: ───────────────────────░──────────────────────────░─────────────
                            ░                          ░ ┌──────────┐
q_5: ───────────────────────░──────────────────────────░─┤ U1(pi/2) ├
                            ░                          ░ └──────────┘


Print the circuit compiled for Cirq:

cirq_circuit
               ┌──┐
(0, 0): ───X────@─────────
                │
(1, 0): ───Y────┼X────────
                │
(2, 0): ────────@─────────

(3, 0): ──────────────H───

(5, 0): ──────────────S───
               └──┘


Print the circuit compiled for pyQuil:

print(pyquil_circuit)

Out:

DECLARE ro BIT[5]
X 0
Y 1
CZ 0 2
X 1
H 3
S 5

Convert each circuit back to a True-Qᵀᴹ circuit object:

qiskit_circuit.to_trueq()
  •  
    • (0) Gate.x
      • Name:

        • Gate.x
      • Aliases:

        • Gate.x
        • Gate.cliff1
      • Generators:

        • 'X': 180.0
      • Matrix:

    • (1) Gate.y
      • Name:

        • Gate.y
      • Aliases:

        • Gate.y
        • Gate.cliff2
      • Generators:

        • 'Y': -180.0
      • Matrix:

  • imm
    • (1) Gate.x
      • Name:

        • Gate.x
      • Aliases:

        • Gate.x
        • Gate.cliff1
      • Generators:

        • 'X': 180.0
      • Matrix:

    • (0, 2) Gate.cz
      • Name:

        • Gate.cz
      • Aliases:

        • Gate.cz
      • Likeness:

        • CNOT
      • Generators:

        • 'IZ': 90.0
        • 'ZI': 90.0
        • 'ZZ': -90.0
      • Matrix:

  •  
    • (3) Gate.h
      • Name:

        • Gate.h
      • Aliases:

        • Gate.h
        • Gate.cliff12
      • Generators:

        • 'X': 127.279
        • 'Z': 127.279
      • Matrix:

    • (5) Gate.s
      • Name:

        • Gate.s
      • Aliases:

        • Gate.s
        • Gate.cliff9
      • Generators:

        • 'Z': 90.0
      • Matrix:



cirq_circuit.to_trueq()
  •  
    • (0) Gate.x
      • Name:

        • Gate.x
      • Aliases:

        • Gate.x
        • Gate.cliff1
      • Generators:

        • 'X': 180.0
      • Matrix:

    • (1) Gate.y
      • Name:

        • Gate.y
      • Aliases:

        • Gate.y
        • Gate.cliff2
      • Generators:

        • 'Y': 180.0
      • Matrix:

  • imm
    • (1) Gate.x
      • Name:

        • Gate.x
      • Aliases:

        • Gate.x
        • Gate.cliff1
      • Generators:

        • 'X': 180.0
      • Matrix:

    • (0, 2) Gate.cz
      • Name:

        • Gate.cz
      • Aliases:

        • Gate.cz
      • Likeness:

        • CNOT
      • Generators:

        • 'IZ': 90.0
        • 'ZI': 90.0
        • 'ZZ': -90.0
      • Matrix:

  •  
    • (3) Gate.h
      • Name:

        • Gate.h
      • Aliases:

        • Gate.h
        • Gate.cliff12
      • Generators:

        • 'X': 127.279
        • 'Z': 127.279
      • Matrix:

    • (4) Gate.s
      • Name:

        • Gate.s
      • Aliases:

        • Gate.s
        • Gate.cliff9
      • Generators:

        • 'Z': 90.0
      • Matrix:



pyquil_circuit.to_trueq()
  •  
    • (0) PyQuil.x()
      • Name:

        • PyQuil.x
      • Aliases:

        • Gate.x
        • Gate.cliff1
      • Generators:

        • 'X': 180.0
      • Matrix:

    • (1) PyQuil.y()
      • Name:

        • PyQuil.y
      • Aliases:

        • Gate.y
        • Gate.cliff2
      • Generators:

        • 'Y': 180.0
      • Matrix:

  • imm
    • (0, 2) PyQuil.cz()
      • Name:

        • PyQuil.cz
      • Aliases:

        • Gate.cz
      • Generators:

        • 'IZ': 90.0
        • 'ZI': 90.0
        • 'ZZ': -90.0
      • Matrix:

  •  
    • (1) PyQuil.x()
      • Name:

        • PyQuil.x
      • Aliases:

        • Gate.x
        • Gate.cliff1
      • Generators:

        • 'X': 180.0
      • Matrix:

    • (3) PyQuil.h()
      • Name:

        • PyQuil.h
      • Aliases:

        • Gate.h
        • Gate.cliff12
      • Generators:

        • 'X': 127.279
        • 'Z': 127.279
      • Matrix:

    • (5) PyQuil.s()
      • Name:

        • PyQuil.s
      • Aliases:

        • Gate.s
        • Gate.cliff9
      • Generators:

        • 'Z': 90.0
      • Matrix:



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_cirq_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): ────────────────────────────Rz(0.468π)───────────@───────────────Rx(π)──────Rz(-0.532π)───
                                                         │
(1, 0): ─────────────────Rx(π)──────Rz(π)────────Rx(π)───┼────────────────────────────────────────
                                                         │
(2, 0): ───Rz(-0.252π)───Rx(0.5π)───Rz(-0.5π)────────────X───Rz(-0.5π)───Rx(0.5π)───Rz(0.252π)────

(3, 0): ─────────────────────────────────────────────────────Rz(0.5π)────Rx(0.5π)───Rz(0.5π)──────

(5, 0): ────────────────────────────────────────────────────────────────────────────Rz(0.5π)──────


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────@─────────
                │
(1, 0): ───Y────┼X────────
                │
(2, 0): ────────@─────────

(3, 0): ──────────────H───

(5, 0): ──────────────S───
               └──┘


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.085 seconds)

Gallery generated by Sphinx-Gallery