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
For more information, see the API documentation in
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 unitary
__init__, and takes up
You can also write your own
Gate subclasses the required functions are:
__init__- you must customize the initializer to set
self.num_inputsto the number of parameters for the gate (e.g. 3 for U3 or ZXZXZ, 0 for CNOT), and
self.quditsto 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 array
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 given
v, the list of parameters needed for your gate, and
i, the index of the first qubit in the set of qubits that your gate is assigned. You must return an array of the form
gate2are tuples that represent gates that the assembler will be able to interpret. For example,
ZXZXZGatereturns an array for 5 tuples, one for each of the Z and X gates that it is based on, but
U3Gateonly 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,
gatenameis a string that will be used to look up the relevant format to print this gate when assembling, and
parametersis a list of the parameters formatted and organized the way they are needed to fill the format specified in the assembler, and
indicesis 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])where
Uis the same matrix you would return in
[J1, ... ,Jn]is a list of matrix derivatives, where J1 is the matrix of derivatives with respect to the first parameter in
v, 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 implementing