2
$\begingroup$

I am wondering whether Qiskit (or other quantum program language) can perform gate synthesis with parametrised precision.

I tried with

from qiskit.transpiler.passes.synthesis import SolovayKitaev

But this package can only decompose to a sequence of Clifford+T gates.

What I am looking for is a method accepting an arbitrary gate set and an approximation parameter.

$\endgroup$

2 Answers 2

2
$\begingroup$

The "method accepting an arbitrary gate" is a tricky part". There are methods with some set of gates that you might have to later translate with a further transpiler pass.

For the approximation part, take a look to Approximate Quantum Compiler (AQC), included in Qiskit 0.36 (Terra 0.19, Apr 2022). I personally prefer to use it as a plugin with the UnitarySynthesis and configure it via plugin_config. In particular, you can set the optimizer (see the available ones here) and its parameters.

In the following example, consider SLSQP(maxiter). By changing maxiter you can extend the computation time in favor of more exact approximation:

  1. Create a circuit with a random unitary (4 qubits in this case)
from qiskit import QuantumCircuit from qiskit.quantum_info import Operator from qiskit.quantum_info.random import random_unitary qc = QuantumCircuit(4) qc.unitary(random_unitary(16, seed=0), [0,1,2,3]) original_matrix = Operator(qc).data 
  1. Take UnitarySynthesis and an optimizer (SLSQP in this case)
from qiskit.transpiler.passes.synthesis.unitary_synthesis import UnitarySynthesis from qiskit.algorithms.optimizers import SLSQP 
  1. Using the aqc plugin, set optimizer with different maxiter. By the way, you can put some basis in basis_gates, not an arbitrary basis tho:

    a. With SLSQP(1), it takes 192ms in my laptop and the accumulated error is 78.

result = UnitarySynthesis(basis_gates=["rx", "ry", "rz", "cx"], method='aqc', plugin_config={"seed": 42, "optimizer": SLSQP(1)})(qc) import numpy as np approx_matrix = Operator(result).data np.sum(np.abs(original_matrix - approx_matrix)) 
77.80895049882317 

b. With SLSQP(10), it takes 1.55s in my laptop and the accumulated error is 36.

result = UnitarySynthesis(basis_gates=["rx", "ry", "rz", "cx"], method='aqc', plugin_config={"seed": 42, "optimizer": SLSQP(10)})(qc) approx_matrix = Operator(result).data np.sum(np.abs(original_matrix-approx_matrix)) 
35.63557540562521 

c. With SLSQP(100), it takes 13.9s in my laptop and the accumulated error is 4.

result = UnitarySynthesis(basis_gates=["rx", "ry", "rz", "cx"], method='aqc', plugin_config={"seed": 42, "optimizer": SLSQP(100)})(qc) approx_matrix = Operator(result).data np.sum(np.abs(original_matrix-approx_matrix)) 
4.048035307578057 
$\endgroup$
0
$\begingroup$

BQSKit can do this exactly. You will need to calculate the unitary of your gate, and you can just plug that into its compile function.

You can accomplish this with the following:

from bqskit import compile, MachineModel from bqskit.ir.gates import CZGate, U3Gate # import the gates you want to use model = MachineModel(number_qubits, gate_set={CZGate(), ...}) # Define your desired gateset output_circuit = compile(gate_unitary_input, model, synthesis_epsilon=1e-8) 

In the above code snippet, you define the desired gate set inside of a MachineModel object and then compile your gate into a circuit. The resulting solution will be at most synthesis_epsilon away from the target unitary. You may also need to set the max_synthesis_size parameter in the compile call if your input is larger than 3 qubits.

For more info, you can refer to the BQSKit documentation or tutorial.

$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.