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:
- 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
- Take
UnitarySynthesis and an optimizer (SLSQP in this case)
from qiskit.transpiler.passes.synthesis.unitary_synthesis import UnitarySynthesis from qiskit.algorithms.optimizers import SLSQP
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