How can I find a Clifford+T approximation of an arbitrary one qubit gate in Qiskit?

I know the Solovay-Kitaev algorithm can achieve this. Is there an implementation of this or any other algorithm for the same task in Qiskit? Or perhaps some other library that interfaces well with Qiskit?

On the Qiskit front, a Solovay-Kitaev algorithm implementation is on its way https://github.com/Qiskit/qiskit-terra/pull/5657.

If you want to use or have a look to this LNoorl:feature/sk-pass branch (remember is a WIP), you can install it like this:

pip install git+https://github.com/LNoorl/qiskit-terra.git@feature/sk-pass


Here is a usage example:

from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import TGate, HGate, TdgGate
from qiskit.transpiler.passes import SolovayKitaevDecomposition

circuit = QuantumCircuit(1)
circuit.rx(0.7, 0)

print('Orginal circuit:')
print(circuit)

basis_gates = [TGate(), TdgGate(), HGate()]
skd = SolovayKitaevDecomposition(recursion_degree=2, basis_gates=basis_gates, depth=5)

discretized = skd(circuit)

print('Discretized circuit:')
print(discretized)

Orginal circuit:
┌─────────┐
q_0: ┤ RX(0.7) ├
└─────────┘
Discretized circuit:
global phase: -π/8
┌───┐┌───┐┌───┐┌─────┐┌───┐┌───┐┌───┐┌───┐┌───┐┌─────┐┌───┐┌───┐┌───┐»
q_0: ┤ H ├┤ T ├┤ H ├┤ TDG ├┤ H ├┤ T ├┤ H ├┤ T ├┤ H ├┤ TDG ├┤ H ├┤ T ├┤ H ├»
└───┘└───┘└───┘└─────┘└───┘└───┘└───┘└───┘└───┘└─────┘└───┘└───┘└───┘»
«     ┌─────┐┌───┐┌─────┐┌─────┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌─────┐»
«q_0: ┤ TDG ├┤ H ├┤ TDG ├┤ TDG ├┤ H ├┤ T ├┤ H ├┤ T ├┤ T ├┤ H ├┤ T ├┤ H ├┤ TDG ├»
«     └─────┘└───┘└─────┘└─────┘└───┘└───┘└───┘└───┘└───┘└───┘└───┘└───┘└─────┘»
«     ┌─────┐┌───┐┌─────┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌─────┐┌───┐┌─────┐»
«q_0: ┤ TDG ├┤ H ├┤ TDG ├┤ H ├┤ T ├┤ H ├┤ T ├┤ H ├┤ T ├┤ H ├┤ TDG ├┤ H ├┤ TDG ├»
«     └─────┘└───┘└─────┘└───┘└───┘└───┘└───┘└───┘└───┘└───┘└─────┘└───┘└─────┘»
«     ┌─────┐┌───┐┌─────┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌─────┐
«q_0: ┤ TDG ├┤ H ├┤ TDG ├┤ H ├┤ T ├┤ T ├┤ H ├┤ T ├┤ H ├┤ TDG ├
«     └─────┘└───┘└─────┘└───┘└───┘└───┘└───┘└───┘└───┘└─────┘
$$$$

• Thanks for this answer! Can I use any universal set of basis gates? Commented Apr 22, 2021 at 12:33
• you can try any basis set, even when it is not universal. However, universal sets will work with any circuit in the universe :P Commented Apr 23, 2021 at 9:52
• It only decomposes single qubit gates though right? Line 94 here github.com/LNoorl/qiskit-terra/blob/master/qiskit/transpiler/… Commented Apr 26, 2021 at 10:53
• @luciano, I'm trying to run skd = SolovayKitaevDecomposition(recursion_degree=2, basis_gates=basis_gates, depth=5) but I get an error __init__() got an unexpected keyword argument 'basis_gates'. How do I fix this? Also, it seems the location of the algorithm is now at from qiskit.transpiler.synthesis.solovay_kitaev. Commented Oct 11, 2022 at 23:17

You should transpile first to cx and u3, so it will deal with 2Q gates

from qiskit import transpile
from qiskit import QuantumCircuit
from qiskit.synthesis import generate_basic_approximations
from qiskit.transpiler.passes import SolovayKitaev

# basic_approx_depth - size of basic circuits pool - as the RAM size I will to give
# recursion_degree=1 -> best aprox from pool
# bigger recursion_degree -> use only basic aproximations
# recursion_degree - choose by resolution wanted
def qasm_to_clifford_and_t(qc, basic_approx_depth=3):
qc = transpile(qc,basis_gates=["cx","u3"])
basis = ["x", "y", "z", "s", "sdg", "t", "tdg", "z", "h"]
approx = generate_basic_approximations(basis, depth=basic_approx_depth)
skd = SolovayKitaev(recursion_degree=1, basic_approximations=approx)
new_qc = skd(qc)
new_qc.draw()

return new_qc

qc = QuantumCircuit(3)
qc.cry(0.5,2,1)
qc.ry(0.3,2)
qc.ccx(0,1,2)
new_qc = qasm_to_clifford_and_t(qc)
new_qc.draw()
`