I'm trying to define a custom gate for my computations. I decided to copy the structure in one of the files in qiskit.extensions.standard
package. Here is the code of h.py
(Hadamard gate):
# -*- coding: utf-8 -*-
# Copyright 2017, IBM.
#
# This source code is licensed under the Apache License, Version 2.0 found in
# the LICENSE.txt file in the root directory of this source tree.
# pylint: disable=invalid-name
"""
Hadamard gate.
"""
from qiskit.circuit import Gate
from qiskit.circuit import QuantumCircuit
from qiskit.circuit import InstructionSet
from qiskit.circuit import QuantumRegister
from qiskit.qasm import pi
from qiskit.dagcircuit import DAGCircuit
from qiskit.extensions.standard import header # pylint: disable=unused-import
from qiskit.extensions.standard.u2 import U2Gate
class HGate(Gate):
"""Hadamard gate."""
def __init__(self, qubit, circ=None):
"""Create new Hadamard gate."""
super().__init__("h", [], [qubit], circ)
def _define_decompositions(self):
"""
gate h a { u2(0,pi) a; }
"""
decomposition = DAGCircuit()
q = QuantumRegister(1, "q")
decomposition.add_qreg(q)
decomposition.add_basis_element("u2", 1, 0, 2)
rule = [
U2Gate(0, pi, q[0])
]
for inst in rule:
decomposition.apply_operation_back(inst)
self._decompositions = [decomposition]
def inverse(self):
"""Invert this gate."""
return self # self-inverse
def reapply(self, circ):
"""Reapply this gate to corresponding qubits in circ."""
self._modifiers(circ.h(self.qargs[0]))
def h(self, q):
"""Apply H to q."""
if isinstance(q, QuantumRegister):
instructions = InstructionSet()
for j in range(q.size):
instructions.add(self.h((q, j)))
return instructions
if isinstance(q, QuantumRegister):
instructions = InstructionSet()
for j in range(q.size):
instructions.add(self.h(q))
return instructions
self._check_qubit(q)
return self._attach(HGate(q, self))
QuantumCircuit.h = h
Trying to change the names of the class, the property of QuantumCircuit
and the name string in Gate
constructor results in an exception (name of the gate) is not in the list of basic operations
if I try to either draw or execute an example circuit containing the gate.
"
""
[1]-const gate.
"""
from qiskit.circuit import Gate
from qiskit.circuit import QuantumCircuit
from qiskit.circuit import InstructionSet
from qiskit.circuit import QuantumRegister
from qiskit.qasm import pi
from qiskit.dagcircuit import DAGCircuit
from qiskit.extensions.standard import header # pylint: disable=unused-import
from qiskit.extensions.standard.u2 import U2Gate
class OneConstGate(Gate):
def __init__(self, qubit, circ=None):
super().__init__("oneconst", [], [qubit], circ)
def _define_decompositions(self):
decomposition = DAGCircuit()
q = QuantumRegister(1, "q")
decomposition.add_qreg(q)
decomposition.add_basis_element("u2", 1, 0, 2)
rule = [
U2Gate(0, pi, q[0])
]
for inst in rule:
decomposition.apply_operation_back(inst)
self._decompositions = [decomposition]
def inverse(self):
"""Invert this gate."""
return self # self-inverse
def reapply(self, circ):
"""Reapply this gate to corresponding qubits in circ."""
self._modifiers(circ.oneconst(self.qargs[0]))
def oneconst(self, q):
"""Apply H to q."""
if isinstance(q, QuantumRegister):
instructions = InstructionSet()
for j in range(q.size):
instructions.add(self.oneconst((q, j)))
return instructions
if isinstance(q, QuantumRegister):
instructions = InstructionSet()
for j in range(q.size):
instructions.add(self.oneconst(q))
return instructions
self._check_qubit(q)
return self._attach(OneConstGate(q, self))
QuantumCircuit.oneconst = oneconst
Here is the example code:
x = QuantumRegister(1, 'x')
gate = QuantumCircuit(x)
gate.oneconst(x[0])
gate.draw()
Note that I haven't changed any logic yet. Just the names. Did I forgot something?
Edit (1):
I had a look at header.py
code in qiskit.extensions.standard
. Adding these lines of code remove the error on draw
method, but not in execute
method:
import sympy
from qiskit.circuit import QuantumCircuit
from qiskit.qasm import _node as node
QuantumCircuit.definitions["oneconst"] = {
"print": False,
"opaque": False,
"n_args": 0,
"n_bits": 1,
"args": [],
"bits": ["a"],
# gate x a { u3(pi,0,pi) a; }
"body": node.GateBody([
node.CustomUnitary([
node.Id("u3", 0, ""),
node.ExpressionList([
node.Real(sympy.pi),
node.Int(0),
node.Real(sympy.pi)
]),
node.PrimaryList([
node.Id("a", 0, "")
])
])
])
}