Gates in qsearch¶
The classes representing quantum gates are found in gates.py
, and are subclasses of qsearch.gates.Gate
. You will need to work with Gate
objects to crate custom gatesets, and you will get a Gate
object as a return value from compilation.
# Here are some examples of what you can do with Gate objects
U3 = qsearch.U3Gate()
CNOT = qsearch.CNOTGate()
# get the matrix that a gate represents in a numpy matrix format
U3_unitary = U3.matrix([np.pi/2, np.pi/4, np./pi/6]) # the array of parameters must be provided
CNOT_unitary = CNOT.matrix([]) # cnot takes no parameters so an empty array is provided
# combine multiple gates to form a larger circuit
mycircuit = ProductGate(KroneckerGate(U3,U3), CNOT) # note that mycircuit is itself an instance of Gate
Provided Gates¶
For more information, see the API documentation in qsearch.gates
.
Custom Gates¶
There is an existing gate that can be customized to your needs. However it will not show up when you assembly the circuit to OpenQASM or Qiskit.
UGate
- represents the gate deqsribed by the unitaryU
passed to__init__
, and takes upqudits
qudits.
You can also write your own Gate
subclasses the required functions are:
__init__
- you must customize the initializer to setself.num_inputs
to the number of parameters for the gate (e.g. 3 for U3 or ZXZXZ, 0 for CNOT), andself.qudits
to the number of qudits used by the gate (e.g. 1 for U3 or ZXZXZ, 2 for CNOT).matrix(v)
- here you generate and return the matrix represented by your gate when passed the parameters provided in the arrayv
.
Assembling with Custom Gates¶
If you want your code to output your custom gates when assembling, you must implement assemble
as well.
assemble(v, i)
- here you are givenv
, the list of parameters needed for your gate, andi
, the index of the first qubit in the set of qubits that your gate is assigned. You must return an array of the form[gate1, gate2]
wheregate1
andgate2
are tuples that represent gates that the assembler will be able to interpret. For example,ZXZXZGate
returns an array for 5 tuples, one for each of the Z and X gates that it is based on, butU3Gate
only returns an array of 1 tuple because the assembler interprets it as a single gate. The tuples take the form("gate", gatename, parameters, indices)
, where the word “gate” is included to specify that this tuple represents a well defined gate as opposed to a Kronecker product of gates,gatename
is a string that will be used to look up the relevant format to print this gate when assembling, andparameters
is a list of the parameters formatted and organized the way they are needed to fill the format specified in the assembler, andindices
is a list of the indices of the involved qubits.
Faster Solving with Jacobians¶
If you would like to take advantage of faster solvers that can take advantage of the Jacobian (marked with Jac
in their name), and your custom gate uses one or more parameters, you will need to implement mat_jac
as well.
mat_jac(v)
- here you generate and return a tuple(U, [J1, ... ,Jn])
whereU
is the same matrix you would return inmatrix
, and[J1, ... ,Jn]
is a list of matrix derivatives, where J1 is the matrix of derivatives with respect to the first parameter inv
, and so on for all the parameters in v. If your custom gate is constant (self.num_inputs == 0
), then you can take advantage of Jacobian solvers without implementingmat_jac
yourself.