Пример #1
0
    def test_slice(self):
        """Verify circuit.data can be sliced."""
        qr = QuantumRegister(2)
        qc = QuantumCircuit(qr)

        qc.h(0)
        qc.cx(0, 1)
        qc.h(1)
        qc.cx(1, 0)
        qc.h(1)
        qc.cx(0, 1)
        qc.h(0)

        h_slice = qc.data[::2]
        cx_slice = qc.data[1:-1:2]

        self.assertEqual(h_slice, [
            (HGate(), [qr[0]], []),
            (HGate(), [qr[1]], []),
            (HGate(), [qr[1]], []),
            (HGate(), [qr[0]], []),
        ])
        self.assertEqual(cx_slice, [
            (CnotGate(), [qr[0], qr[1]], []),
            (CnotGate(), [qr[1], qr[0]], []),
            (CnotGate(), [qr[0], qr[1]], []),
        ])
Пример #2
0
    def _define(self):
        definition = []
        # No controls:
        #   q = b
        # One Control:
        #   q = b, c1
        # Two Controls:
        #   q = c1, c2, b
        q = QuantumRegister(self.total_n, "q")
        rule = []

        angles = [0] * self.n
        for i in range(self.n):
            if self.a & (1 << i):
                for j in range(i, self.n):
                    angles[j] += np.pi / 2**(j - i)

        # Inverse of U1 gates is just a negative theta
        if self._inverse:
            for i in range(len(angles)):
                angles[i] *= -1

        # No controlled bits
        if self.c1 is None and self.c2 is None:
            for i in range(len(angles)):
                rule.append((U1Gate(angles[i]), [q[i]], []))

        # One controlled bit
        if self.c1 and self.c2 is None:
            for i in range(len(angles)):
                rule.append((Cu1Gate(angles[i]), [q[self.total_n - 1],
                                                  q[i]], []))

        # Two controlled bits
        # Uses sqrt of U1 gates which is just half of theta
        if self.c1 and self.c2:
            for i in range(len(angles)):
                rule.append((Cu1Gate(angles[i] / 2.), [q[1], q[i + 2]], []))
                # circ.cu1(angles[i]/2., c2, b[i])
            rule.append((CnotGate(), [q[0], q[1]], []))
            # circ.cx(c1, c2)

            for i in range(len(angles)):
                rule.append((Cu1Gate(-angles[i] / 2.), [q[1], q[i + 2]], []))
                # circ.cu1(-angles[i]/2., c2, b[i])
            rule.append((CnotGate(), [q[0], q[1]], []))
            # circ.cx(c1, c2)
            for i in range(len(angles)):
                rule.append((Cu1Gate(angles[i] / 2.), [q[0], q[i + 2]], []))
                # circ.cu1(angles[i]/2., c1, b[i])

        for inst in rule:
            definition.append(inst)
        self.definition = definition
Пример #3
0
    def test_instruction_init(self):
        """Test initialization from a circuit."""
        gate = CnotGate()
        op = Operator(gate).data
        target = gate.to_matrix()
        global_phase_equivalent = matrix_equal(op, target, ignore_phase=True)
        self.assertTrue(global_phase_equivalent)

        gate = CHGate()
        op = Operator(gate).data
        had = HGate().to_matrix()
        target = np.kron(had, np.diag([0, 1])) + np.kron(
            np.eye(2), np.diag([1, 0]))
        global_phase_equivalent = matrix_equal(op, target, ignore_phase=True)
        self.assertTrue(global_phase_equivalent)
Пример #4
0
    def run(self, dag):
        """Run the CXDirection pass on `dag`.

        Flips the cx nodes to match the directed coupling map. Modifies the
        input dag.

        Args:
            dag (DAGCircuit): DAG to map.

        Returns:
            DAGCircuit: The rearranged dag for the coupling map

        Raises:
            TranspilerError: If the circuit cannot be mapped just by flipping the
                cx nodes.
        """
        cmap_edges = set(self.coupling_map.get_edges())

        if len(dag.qregs) > 1:
            raise TranspilerError(
                'CXDirection expects a single qreg input DAG,'
                'but input DAG had qregs: {}.'.format(dag.qregs))

        for cnot_node in dag.named_nodes('cx', 'CX'):
            control = cnot_node.qargs[0]
            target = cnot_node.qargs[1]

            physical_q0 = control.index
            physical_q1 = target.index

            if self.coupling_map.distance(physical_q0, physical_q1) != 1:
                raise TranspilerError(
                    'The circuit requires a connection between physical '
                    'qubits %s and %s' % (physical_q0, physical_q1))

            if (physical_q0, physical_q1) not in cmap_edges:
                # A flip needs to be done

                # Create the replacement dag and associated register.
                sub_dag = DAGCircuit()
                sub_qr = QuantumRegister(2)
                sub_dag.add_qreg(sub_qr)

                # Add H gates before
                sub_dag.apply_operation_back(U2Gate(0, pi), [sub_qr[0]], [])
                sub_dag.apply_operation_back(U2Gate(0, pi), [sub_qr[1]], [])

                # Flips the cx
                sub_dag.apply_operation_back(CnotGate(),
                                             [sub_qr[1], sub_qr[0]], [])

                # Add H gates after
                sub_dag.apply_operation_back(U2Gate(0, pi), [sub_qr[0]], [])
                sub_dag.apply_operation_back(U2Gate(0, pi), [sub_qr[1]], [])

                dag.substitute_node_with_dag(cnot_node, sub_dag)

        return dag
 def test_circuit_append(self):
     """Test appending controlled gate to quantum circuit"""
     circ = QuantumCircuit(5)
     inst = CnotGate()
     circ.append(inst.control(), qargs=[0, 2, 1])
     circ.append(inst.control(2), qargs=[0, 3, 1, 2])
     circ.append(inst.control().control(), qargs=[0, 3, 1, 2])  # should be same as above
     self.assertEqual(circ[1][0], circ[2][0])
     self.assertEqual(circ.depth(), 3)
     self.assertEqual(circ[0][0].num_ctrl_qubits, 2)
     self.assertEqual(circ[1][0].num_ctrl_qubits, 3)
     self.assertEqual(circ[2][0].num_ctrl_qubits, 3)
     self.assertEqual(circ[0][0].num_qubits, 3)
     self.assertEqual(circ[1][0].num_qubits, 4)
     self.assertEqual(circ[2][0].num_qubits, 4)
     for instr in circ:
         gate = instr[0]
         self.assertTrue(isinstance(gate, ControlledGate))
Пример #6
0
def comp_cnot_gate_list(qub1, qub2, quant_reg, inverse_cnot=False):
    ret_params = []

    if not inverse_cnot:
        ret_params.append([CnotGate(), [quant_reg[qub1], quant_reg[qub2]]])
    else:
        ret_params.append([HGate(), [quant_reg[qub1]]])
        ret_params.append([HGate(), [quant_reg[qub2]]])

        ret_params.append([CnotGate(), [quant_reg[qub1], quant_reg[qub2]]])

        ret_params.append([HGate(), [quant_reg[qub1]]])
        ret_params.append([HGate(), [quant_reg[qub2]]])

    ret = []
    for elem in ret_params:
        ret.append(DAGNode({"op": elem[0], "qargs": elem[1], "type": "op"}))

    return ret
Пример #7
0
 def test_cnot_rxx_decompose(self):
     """Verify CNOT decomposition into RXX gate is correct"""
     cnot = Operator(CnotGate())
     decomps = [
         cnot_rxx_decompose(),
         cnot_rxx_decompose(plus_ry=True, plus_rxx=True),
         cnot_rxx_decompose(plus_ry=True, plus_rxx=False),
         cnot_rxx_decompose(plus_ry=False, plus_rxx=True),
         cnot_rxx_decompose(plus_ry=False, plus_rxx=False)
     ]
     for decomp in decomps:
         self.assertTrue(cnot.equiv(decomp))
Пример #8
0
    def test_index_gates(self):
        """Verify finding the index of a inst/qarg/carg tuple in circuit.data."""
        qr = QuantumRegister(2)
        qc = QuantumCircuit(qr)

        qc.h(0)
        qc.cx(0, 1)
        qc.h(1)
        qc.h(0)

        self.assertEqual(qc.data.index((HGate(), [qr[0]], [])), 0)
        self.assertEqual(qc.data.index((CnotGate(), [qr[0], qr[1]], [])), 1)
        self.assertEqual(qc.data.index((HGate(), [qr[1]], [])), 2)
Пример #9
0
    def test_getitem_by_insertion_order(self):
        """Verify one can get circuit.data items in insertion order."""
        qr = QuantumRegister(2)
        qc = QuantumCircuit(qr)
        qc.h(0)
        qc.cx(0, 1)
        qc.h(1)

        data = qc.data

        self.assertEqual(data[0], (HGate(), [qr[0]], []))
        self.assertEqual(data[1], (CnotGate(), [qr[0], qr[1]], []))
        self.assertEqual(data[2], (HGate(), [qr[1]], []))
Пример #10
0
    def test_iter(self):
        """Verify circuit.data can behave as an iterator."""
        qr = QuantumRegister(2)
        qc = QuantumCircuit(qr)

        qc.h(0)
        qc.cx(0, 1)
        qc.h(1)

        iter_ = iter(qc.data)
        self.assertEqual(next(iter_), (HGate(), [qr[0]], []))
        self.assertEqual(next(iter_), (CnotGate(), [qr[0], qr[1]], []))
        self.assertEqual(next(iter_), (HGate(), [qr[1]], []))
        self.assertRaises(StopIteration, next, iter_)
Пример #11
0
    def test_setting_data_is_validated(self):
        """Verify setting circuit.data is broadcast and validated."""
        qr = QuantumRegister(2)
        qc = QuantumCircuit(qr)

        qc.data = [(HGate(), [qr[0]], []), (CnotGate(), [0, 1], []),
                   (HGate(), [(qr, 1)], [])]

        expected_qc = QuantumCircuit(qr)

        expected_qc.h(0)
        expected_qc.cx(0, 1)
        expected_qc.h(1)

        self.assertEqual(qc, expected_qc)

        with self.assertRaises(QiskitError):
            qc.data = [(HGate(), [qr[0], qr[1]], [])]
        with self.assertRaises(QiskitError):
            qc.data = [(HGate(), [], [qr[0]])]
Пример #12
0
    def test_extend_is_validated(self):
        """Verify extending circuit.data is broadcast and validated."""
        qr = QuantumRegister(2)
        qc = QuantumCircuit(qr)

        qc.data.extend([(HGate(), [qr[0]], []), (CnotGate(), [0, 1], []),
                        (HGate(), [(qr, 1)], [])])

        expected_qc = QuantumCircuit(qr)

        expected_qc.h(0)
        expected_qc.cx(0, 1)
        expected_qc.h(1)

        self.assertEqual(qc, expected_qc)

        self.assertRaises(QiskitError, qc.data.extend,
                          [(HGate(), [qr[0], qr[1]], [])])
        self.assertRaises(QiskitError, qc.data.extend,
                          [(HGate(), [], [qr[0]])])
Пример #13
0
    def test_append_is_validated(self):
        """Verify appended gates via circuit.data are broadcast and validated."""
        qr = QuantumRegister(2)
        qc = QuantumCircuit(qr)

        qc.data.append((HGate(), [qr[0]], []))
        qc.data.append((CnotGate(), [0, 1], []))
        qc.data.append((HGate(), [(qr, 1)], []))

        expected_qc = QuantumCircuit(qr)

        expected_qc.h(0)
        expected_qc.cx(0, 1)
        expected_qc.h(1)

        self.assertEqual(qc, expected_qc)

        self.assertRaises(QiskitError, qc.data.append,
                          (HGate(), [qr[0], qr[1]], []))
        self.assertRaises(QiskitError, qc.data.append, (HGate(), [], [qr[0]]))
Пример #14
0
    def test_insert_is_validated(self):
        """Verify inserting gates via circuit.data are broadcast and validated."""
        qr = QuantumRegister(2)
        qc = QuantumCircuit(qr)

        qc.data.insert(0, (HGate(), [qr[0]], []))
        qc.data.insert(1, (CnotGate(), [0, 1], []))
        qc.data.insert(2, (HGate(), [qr[1]], []))

        expected_qc = QuantumCircuit(qr)

        expected_qc.h(0)
        expected_qc.cx(0, 1)
        expected_qc.h(1)

        self.assertEqual(qc, expected_qc)

        self.assertRaises(CircuitError, qc.data.insert, 0,
                          (HGate(), [qr[0], qr[1]], []))
        self.assertRaises(CircuitError, qc.data.insert, 0,
                          (HGate(), [], [qr[0]]))
Пример #15
0
def two_qubit_kak(unitary):
    """Decompose a two-qubit gate over SU(2)+CNOT using the KAK decomposition.

    Args:
        unitary (Unitary): a 4x4 unitary operator to decompose.

    Returns:
        QuantumCircuit: a circuit implementing the unitary over SU(2)+CNOT

    Raises:
        QiskitError: input not a unitary, or error in KAK decomposition.
    """
    unitary_matrix = unitary.representation
    if unitary_matrix.shape != (4, 4):
        raise QiskitError("two_qubit_kak: Expected 4x4 matrix")
    phase = la.det(unitary_matrix)**(-1.0/4.0)
    # Make it in SU(4), correct phase at the end
    U = phase * unitary_matrix
    # B changes to the Bell basis
    B = (1.0/math.sqrt(2)) * np.array([[1, 1j, 0, 0],
                                       [0, 0, 1j, 1],
                                       [0, 0, 1j, -1],
                                       [1, -1j, 0, 0]], dtype=complex)

    # We also need B.conj().T below
    Bdag = B.conj().T
    # U' = Bdag . U . B
    Uprime = Bdag.dot(U.dot(B))
    # M^2 = trans(U') . U'
    M2 = Uprime.T.dot(Uprime)

    # Diagonalize M2
    # Must use diagonalization routine which finds a real orthogonal matrix P
    # when M2 is real.
    D, P = la.eig(M2)
    D = np.diag(D)
    # If det(P) == -1 then in O(4), apply a swap to make P in SO(4)
    if abs(la.det(P)+1) < 1e-5:
        swap = np.array([[1, 0, 0, 0],
                         [0, 0, 1, 0],
                         [0, 1, 0, 0],
                         [0, 0, 0, 1]], dtype=complex)
        P = P.dot(swap)
        D = swap.dot(D.dot(swap))

    Q = np.sqrt(D)  # array from elementwise sqrt
    # Want to take square root so that Q has determinant 1
    if abs(la.det(Q)+1) < 1e-5:
        Q[0, 0] = -Q[0, 0]

    # Q^-1*P.T = P' -> QP' = P.T (solve for P' using Ax=b)
    Pprime = la.solve(Q, P.T)
    # K' now just U' * P * P'
    Kprime = Uprime.dot(P.dot(Pprime))

    K1 = B.dot(Kprime.dot(P.dot(Bdag)))
    A = B.dot(Q.dot(Bdag))
    K2 = B.dot(P.T.dot(Bdag))
    # KAK = K1 * A * K2
    KAK = K1.dot(A.dot(K2))

    # Verify decomp matches input unitary.
    if la.norm(KAK - U) > 1e-6:
        raise QiskitError("two_qubit_kak: KAK decomposition " +
                          "does not return input unitary.")

    # Compute parameters alpha, beta, gamma so that
    # A = exp(i * (alpha * XX + beta * YY + gamma * ZZ))
    xx = np.array([[0, 0, 0, 1],
                   [0, 0, 1, 0],
                   [0, 1, 0, 0],
                   [1, 0, 0, 0]], dtype=complex)

    yy = np.array([[0, 0, 0, -1],
                   [0, 0, 1, 0],
                   [0, 1, 0, 0],
                   [-1, 0, 0, 0]], dtype=complex)

    zz = np.array([[1, 0, 0, 0],
                   [0, -1, 0, 0],
                   [0, 0, -1, 0],
                   [0, 0, 0, 1]], dtype=complex)

    A_real_tr = A.real.trace()
    alpha = math.atan2(A.dot(xx).imag.trace(), A_real_tr)
    beta = math.atan2(A.dot(yy).imag.trace(), A_real_tr)
    gamma = math.atan2(A.dot(zz).imag.trace(), A_real_tr)

    # K1 = kron(U1, U2) and K2 = kron(V1, V2)
    # Find the matrices U1, U2, V1, V2

    # Find a block in K1 where U1_ij * [U2] is not zero
    L = K1[0:2, 0:2]
    if la.norm(L) < 1e-9:
        L = K1[0:2, 2:4]
        if la.norm(L) < 1e-9:
            L = K1[2:4, 2:4]
    # Remove the U1_ij prefactor
    Q = L.dot(L.conj().T)
    U2 = L / math.sqrt(Q[0, 0].real)

    # Now grab U1 given we know U2
    R = K1.dot(np.kron(np.identity(2), U2.conj().T))
    U1 = np.zeros((2, 2), dtype=complex)
    U1[0, 0] = R[0, 0]
    U1[0, 1] = R[0, 2]
    U1[1, 0] = R[2, 0]
    U1[1, 1] = R[2, 2]

    # Repeat K1 routine for K2
    L = K2[0:2, 0:2]
    if la.norm(L) < 1e-9:
        L = K2[0:2, 2:4]
        if la.norm(L) < 1e-9:
            L = K2[2:4, 2:4]
    Q = np.dot(L, np.transpose(L.conjugate()))
    V2 = L / np.sqrt(Q[0, 0])
    R = np.dot(K2, np.kron(np.identity(2), np.transpose(V2.conjugate())))

    V1 = np.zeros_like(U1)
    V1[0, 0] = R[0, 0]
    V1[0, 1] = R[0, 2]
    V1[1, 0] = R[2, 0]
    V1[1, 1] = R[2, 2]

    if la.norm(np.kron(U1, U2) - K1) > 1e-4:
        raise QiskitError("two_qubit_kak: K1 != U1 x U2")
    if la.norm(np.kron(V1, V2) - K2) > 1e-4:
        raise QiskitError("two_qubit_kak: K2 != V1 x V2")

    test = la.expm(1j*(alpha * xx + beta * yy + gamma * zz))
    if la.norm(A - test) > 1e-4:
        raise QiskitError("two_qubit_kak: " +
                          "Matrix A does not match xx,yy,zz decomposition.")

    # Circuit that implements K1 * A * K2 (up to phase), using
    # Vatan and Williams Fig. 6 of quant-ph/0308006v3
    # Include prefix and suffix single-qubit gates into U2, V1 respectively.

    V2 = np.array([[np.exp(1j*np.pi/4), 0],
                   [0, np.exp(-1j*np.pi/4)]], dtype=complex).dot(V2)
    U1 = U1.dot(np.array([[np.exp(-1j*np.pi/4), 0],
                          [0, np.exp(1j*np.pi/4)]], dtype=complex))

    # Corrects global phase: exp(ipi/4)*phase'
    U1 = U1.dot(np.array([[np.exp(1j*np.pi/4), 0],
                          [0, np.exp(1j*np.pi/4)]], dtype=complex))
    U1 = phase.conjugate() * U1

    # Test
    g1 = np.kron(V1, V2)
    g2 = np.array([[1, 0, 0, 0],
                   [0, 0, 0, 1],
                   [0, 0, 1, 0],
                   [0, 1, 0, 0]], dtype=complex)

    theta = 2*gamma - np.pi/2

    Ztheta = np.array([[np.exp(1j*theta/2), 0],
                       [0, np.exp(-1j*theta/2)]], dtype=complex)

    kappa = np.pi/2 - 2*alpha
    Ykappa = np.array([[math.cos(kappa/2), math.sin(kappa/2)],
                       [-math.sin(kappa/2), math.cos(kappa/2)]], dtype=complex)
    g3 = np.kron(Ztheta, Ykappa)
    g4 = np.array([[1, 0, 0, 0],
                   [0, 1, 0, 0],
                   [0, 0, 0, 1],
                   [0, 0, 1, 0]], dtype=complex)

    zeta = 2*beta - np.pi/2
    Yzeta = np.array([[math.cos(zeta/2), math.sin(zeta/2)],
                      [-math.sin(zeta/2), math.cos(zeta/2)]], dtype=complex)
    g5 = np.kron(np.identity(2), Yzeta)
    g6 = g2
    g7 = np.kron(U1, U2)

    V = g2.dot(g1)
    V = g3.dot(V)
    V = g4.dot(V)
    V = g5.dot(V)
    V = g6.dot(V)
    V = g7.dot(V)

    if la.norm(V - U*phase.conjugate()) > 1e-6:
        raise QiskitError("two_qubit_kak: " +
                          "sequence incorrect, unknown error")

    v1_param = euler_angles_1q(V1)
    v2_param = euler_angles_1q(V2)
    u1_param = euler_angles_1q(U1)
    u2_param = euler_angles_1q(U2)

    v1_gate = U3Gate(v1_param[0], v1_param[1], v1_param[2])
    v2_gate = U3Gate(v2_param[0], v2_param[1], v2_param[2])
    u1_gate = U3Gate(u1_param[0], u1_param[1], u1_param[2])
    u2_gate = U3Gate(u2_param[0], u2_param[1], u2_param[2])

    q = QuantumRegister(2)
    return_circuit = QuantumCircuit(q)

    return_circuit.append(v1_gate, [q[1]])

    return_circuit.append(v2_gate, [q[0]])

    return_circuit.append(CnotGate(), [q[0], q[1]])

    gate = U3Gate(0.0, 0.0, -2.0*gamma + np.pi/2.0)
    return_circuit.append(gate, [q[1]])

    gate = U3Gate(-np.pi/2.0 + 2.0*alpha, 0.0, 0.0)
    return_circuit.append(gate, [q[0]])

    return_circuit.append(CnotGate(), [q[1], q[0]])

    gate = U3Gate(-2.0*beta + np.pi/2.0, 0.0, 0.0)
    return_circuit.append(gate, [q[0]])

    return_circuit.append(CnotGate(), [q[0], q[1]])

    return_circuit.append(u1_gate, [q[1]])

    return_circuit.append(u2_gate, [q[0]])

    return return_circuit
Пример #16
0
 def test_controlled_x(self):
     """Test creation of controlled x gate"""
     self.assertEqual(XGate().control(), CnotGate())
Пример #17
0
 def test_controlled_cx(self):
     """Test creation of controlled cx gate"""
     self.assertEqual(CnotGate().control(), ToffoliGate())
Пример #18
0
    def _define(self):
        definition = []
        #   q = c1, c2, b, anc
        q = QuantumRegister(self.total_n, "q")

        # No easy way to inverse other than reverse the order of gates and
        # invert them.
        if not self._inverse:
            rule = [
                (PhiADDaGate(self.a, self.n, c1=q[0], c2=q[1]),
                 [q[0], q[1]] + [q[i] for i in range(2, self.n + 2)], []),
                (PhiADDaGate(self.N, self.n, inverse=True),
                 [q[i] for i in range(2, self.n + 2)], []),
                (QFTGate(self.n,
                         inverse=True), [q[i]
                                         for i in range(2, self.n + 2)], []),
                (CnotGate(), [q[self.total_n - 2], q[self.total_n - 1]], []),
                (QFTGate(self.n), [q[i] for i in range(2, self.n + 2)], []),
                (PhiADDaGate(self.N, self.n, c1=q[self.total_n - 1]),
                 [q[i]
                  for i in range(2, self.n + 2)] + [q[self.total_n - 1]], []),
                (PhiADDaGate(self.a, self.n, c1=q[0], c2=q[1], inverse=True),
                 [q[0], q[1]] + [q[i] for i in range(2, self.n + 2)], []),
                (QFTGate(self.n,
                         inverse=True), [q[i]
                                         for i in range(2, self.n + 2)], []),
                (XGate(), [q[self.total_n - 2]], []),
                (CnotGate(), [q[self.total_n - 2], q[self.total_n - 1]], []),
                (XGate(), [q[self.total_n - 2]], []),
                (QFTGate(self.n), [q[i] for i in range(2, self.n + 2)], []),
                (PhiADDaGate(self.a, self.n, c1=q[0], c2=q[1]),
                 [q[0], q[1]] + [q[i] for i in range(2, self.n + 2)], []),
            ]
        else:
            rule = [
                (PhiADDaGate(self.a, self.n, c1=q[0], c2=q[1], inverse=True),
                 [q[0], q[1]] + [q[i] for i in range(2, self.n + 2)], []),
                (QFTGate(self.n,
                         inverse=True), [q[i]
                                         for i in range(2, self.n + 2)], []),
                (XGate(), [q[self.total_n - 2]], []),
                (CnotGate(), [q[self.total_n - 2], q[self.total_n - 1]], []),
                (XGate(), [q[self.total_n - 2]], []),
                (QFTGate(self.n), [q[i] for i in range(2, self.n + 2)], []),
                (PhiADDaGate(self.a, self.n, c1=q[0], c2=q[1]),
                 [q[0], q[1]] + [q[i] for i in range(2, self.n + 2)], []),
                (PhiADDaGate(self.N,
                             self.n,
                             c1=q[self.total_n - 1],
                             inverse=True),
                 [q[i]
                  for i in range(2, self.n + 2)] + [q[self.total_n - 1]], []),
                (QFTGate(self.n,
                         inverse=True), [q[i]
                                         for i in range(2, self.n + 2)], []),
                (CnotGate(), [q[self.total_n - 2], q[self.total_n - 1]], []),
                (QFTGate(self.n), [q[i] for i in range(2, self.n + 2)], []),
                (PhiADDaGate(self.N,
                             self.n), [q[i]
                                       for i in range(2, self.n + 2)], []),
                (PhiADDaGate(self.a, self.n, c1=q[0], c2=q[1], inverse=True),
                 [q[0], q[1]] + [q[i] for i in range(2, self.n + 2)], []),
            ]

        for inst in rule:
            definition.append(inst)
        self.definition = definition