Beispiel #1
0
    def test_topological_nodes(self):
        """The topological_nodes() method"""
        self.dag.apply_operation_back(CnotGate(), [self.qubit0, self.qubit1],
                                      [])
        self.dag.apply_operation_back(HGate(), [self.qubit0], [])
        self.dag.apply_operation_back(CnotGate(), [self.qubit2, self.qubit1],
                                      [])
        self.dag.apply_operation_back(CnotGate(), [self.qubit0, self.qubit2],
                                      [])
        self.dag.apply_operation_back(HGate(), [self.qubit2], [])

        named_nodes = self.dag.topological_nodes()

        expected = [('qr[0]', []), ('qr[1]', []),
                    ('cx', [(QuantumRegister(3, 'qr'), 0),
                            (QuantumRegister(3, 'qr'), 1)]),
                    ('h', [(QuantumRegister(3, 'qr'), 0)]), ('qr[2]', []),
                    ('cx', [(QuantumRegister(3, 'qr'), 2),
                            (QuantumRegister(3, 'qr'), 1)]),
                    ('cx', [(QuantumRegister(3, 'qr'), 0),
                            (QuantumRegister(3, 'qr'), 2)]),
                    ('h', [(QuantumRegister(3, 'qr'), 2)]), ('qr[0]', []),
                    ('qr[1]', []), ('qr[2]', []), ('cr[0]', []), ('cr[0]', []),
                    ('cr[1]', []), ('cr[1]', [])]
        self.assertEqual(expected, [(i.name, i.qargs) for i in named_nodes])
Beispiel #2
0
 def _define_decompositions(self):
     decomposition = DAGCircuit()
     q = QuantumRegister(5, "q")
     decomposition.add_qreg(q)
     decomposition.add_basis_element("u1", 1, 0, 1)
     decomposition.add_basis_element("cx", 2, 0, 0)
     decomposition.add_basis_element("ccx", 3, 0, 0)
     decomposition.add_basis_element("c3x", 4, 0, 0)
     decomposition.add_basis_element("c4x", 5, 0, 0)
     rule = [
         C4NotGate(q[0], q[1], q[2], q[3], q[4]),
         C3NotGate(q[0], q[1], q[2], q[3]),
         ToffoliGate(q[0], q[1], q[2]),
         CnotGate(q[0], q[1]),
         U1Gate(-self.param[0] / 16, q[1]),
         U1Gate(-self.param[0] / 8, q[2]),
         U1Gate(-self.param[0] / 4, q[3]),
         U1Gate(-self.param[0] / 2, q[4]),
         CnotGate(q[0], q[1]),
         ToffoliGate(q[0], q[1], q[2]),
         C3NotGate(q[0], q[1], q[2], q[3]),
         C4NotGate(q[0], q[1], q[2], q[3], q[4]),
         U1Gate(self.param[0] / 16, q[0]),
         U1Gate(self.param[0] / 16, q[1]),
         U1Gate(self.param[0] / 8, q[2]),
         U1Gate(self.param[0] / 4, q[3]),
         U1Gate(self.param[0] / 2, q[4])
     ]
     for inst in rule:
         decomposition.apply_operation_back(inst)
     self._decompositions = [decomposition]
Beispiel #3
0
 def test_dag_collect_runs(self):
     """Test the collect_runs method with 3 different gates."""
     self.dag.apply_operation_back(U1Gate(3.14), [self.qubit0])
     self.dag.apply_operation_back(U1Gate(3.14), [self.qubit0])
     self.dag.apply_operation_back(U1Gate(3.14), [self.qubit0])
     self.dag.apply_operation_back(CnotGate(), [self.qubit2, self.qubit1])
     self.dag.apply_operation_back(CnotGate(), [self.qubit1, self.qubit2])
     self.dag.apply_operation_back(HGate(), [self.qubit2])
     collected_runs = self.dag.collect_runs(['u1', 'cx', 'h'])
     self.assertEqual(len(collected_runs), 3)
     for run in collected_runs:
         if run[0].name == 'cx':
             self.assertEqual(len(run), 2)
             self.assertEqual(['cx'] * 2, [x.name for x in run])
             self.assertEqual(
                 [[self.qubit2, self.qubit1], [self.qubit1, self.qubit2]],
                 [x.qargs for x in run])
         elif run[0].name == 'h':
             self.assertEqual(len(run), 1)
             self.assertEqual(['h'], [x.name for x in run])
             self.assertEqual([[self.qubit2]], [x.qargs for x in run])
         elif run[0].name == 'u1':
             self.assertEqual(len(run), 3)
             self.assertEqual(['u1'] * 3, [x.name for x in run])
             self.assertEqual([[self.qubit0], [self.qubit0], [self.qubit0]],
                              [x.qargs for x in run])
         else:
             self.fail('Unknown run encountered')
Beispiel #4
0
 def _define_decompositions(self):
     """
     gate cu3(theta,phi,lambda) c, t
     { u1((lambda-phi)/2) t; cx c,t;
       u3(-theta/2,0,-(phi+lambda)/2) t; cx c,t;
       u3(theta/2,phi,0) t;
     }
     """
     decomposition = DAGCircuit()
     q = QuantumRegister(2, "q")
     decomposition.add_qreg(q)
     decomposition.add_basis_element("u1", 1, 0, 1)
     decomposition.add_basis_element("u3", 1, 0, 3)
     decomposition.add_basis_element("cx", 2, 0, 0)
     rule = [
         U1Gate((self.param[2] - self.param[1]) / 2, q[1]),
         CnotGate(q[0], q[1]),
         U3Gate(-self.param[0] / 2, 0, -(self.param[1] + self.param[2]) / 2,
                q[1]),
         CnotGate(q[0], q[1]),
         U3Gate(self.param[0] / 2, self.param[1], 0, q[1])
     ]
     for inst in rule:
         decomposition.apply_operation_back(inst)
     self._decompositions = [decomposition]
Beispiel #5
0
 def _define_decompositions(self):
     """
     gate ch a,b {
     h b;
     sdg b;
     cx a,b;
     h b;
     t b;
     cx a,b;
     t b;
     h b;
     s b;
     x b;
     s a;}
     """
     decomposition = DAGCircuit()
     q = QuantumRegister(2, "q")
     decomposition.add_qreg(q)
     rule = [
         HGate(q[1]),
         SdgGate(q[1]),
         CnotGate(q[0], q[1]),
         HGate(q[1]),
         TGate(q[1]),
         CnotGate(q[0], q[1]),
         TGate(q[1]),
         HGate(q[1]),
         SGate(q[1]),
         XGate(q[1]),
         SGate(q[0])
     ]
     for inst in rule:
         decomposition.apply_operation_back(inst)
     self._decompositions = [decomposition]
    def test_remove_op_node_longer(self):
        """ Test remove_op_node method in a "longer" dag"""
        self.dag.apply_operation_back(CnotGate(), [self.qubit0, self.qubit1])
        self.dag.apply_operation_back(HGate(), [self.qubit0])
        self.dag.apply_operation_back(CnotGate(), [self.qubit2, self.qubit1])
        self.dag.apply_operation_back(CnotGate(), [self.qubit0, self.qubit2])
        self.dag.apply_operation_back(HGate(), [self.qubit2])

        named_nodes = [node for node in self.dag.nodes_in_topological_order()]
        self.dag.remove_op_node(named_nodes[2])

        expected = [('qr[0]', []),
                    ('h', [self.qubit0]),
                    ('qr[1]', []),
                    ('qr[2]', []),
                    ('cx', [self.qubit2, self.qubit1]),
                    ('cx', [self.qubit0, self.qubit2]),
                    ('h', [self.qubit2]),
                    ('qr[0]', []),
                    ('qr[1]', []),
                    ('qr[2]', []),
                    ('cr[0]', []),
                    ('cr[0]', []),
                    ('cr[1]', []),
                    ('cr[1]', [])]
        self.assertEqual(expected,
                         [(i.name, i.qargs) for i in self.dag.nodes_in_topological_order()])
Beispiel #7
0
 def _define(self):
     """
     gate ch a,b {
     h b;
     sdg b;
     cx a,b;
     h b;
     t b;
     cx a,b;
     t b;
     h b;
     s b;
     x b;
     s a;}
     """
     definition = []
     q = QuantumRegister(2, "q")
     rule = [(HGate(), [q[1]], []), (SdgGate(), [q[1]], []),
             (CnotGate(), [q[0], q[1]], []), (HGate(), [q[1]], []),
             (TGate(), [q[1]], []), (CnotGate(), [q[0], q[1]], []),
             (TGate(), [q[1]], []), (HGate(), [q[1]], []),
             (SGate(), [q[1]], []), (XGate(), [q[1]], []),
             (SGate(), [q[0]], [])]
     for inst in rule:
         definition.append(inst)
     self.definition = definition
Beispiel #8
0
    def _multiplex(self, target_gate, list_of_angles):
        """
        Return a recursive implementation of a multiplexor circuit,
        where each instruction itself has a decomposition based on
        smaller multiplexors.

        The LSB is the multiplexor "data" and the other bits are multiplexor "select".

        Args:
            target_gate (Gate): Ry or Rz gate to apply to target qubit, multiplexed
                over all other "select" qubits
            list_of_angles (list[float]): list of rotation angles to apply Ry and Rz

        Returns:
            DAGCircuit: the circuit implementing the multiplexor's action
        """
        list_len = len(list_of_angles)
        local_num_qubits = int(math.log2(list_len)) + 1

        q = QuantumRegister(local_num_qubits)
        circuit = QuantumCircuit(q)
        circuit.name = "multiplex" + local_num_qubits.__str__()

        lsb = q[0]
        msb = q[local_num_qubits - 1]

        # case of no multiplexing: base case for recursion
        if local_num_qubits == 1:
            circuit.append(target_gate(list_of_angles[0]), [q[0]])
            return circuit

        # calc angle weights, assuming recursion (that is the lower-level
        # requested angles have been correctly implemented by recursion
        angle_weight = scipy.kron([[0.5, 0.5], [0.5, -0.5]],
                                  np.identity(2 ** (local_num_qubits - 2)))

        # calc the combo angles
        list_of_angles = angle_weight.dot(np.array(list_of_angles)).tolist()

        # recursive step on half the angles fulfilling the above assumption
        multiplex_1 = self._multiplex(target_gate, list_of_angles[0:(list_len // 2)])
        circuit.append(multiplex_1.to_instruction(), q[0:-1])

        # attach CNOT as follows, thereby flipping the LSB qubit
        circuit.append(CnotGate(), [msb, lsb])

        # implement extra efficiency from the paper of cancelling adjacent
        # CNOTs (by leaving out last CNOT and reversing (NOT inverting) the
        # second lower-level multiplex)
        multiplex_2 = self._multiplex(target_gate, list_of_angles[(list_len // 2):])
        if list_len > 1:
            circuit.append(multiplex_2.to_instruction().mirror(), q[0:-1])
        else:
            circuit.append(multiplex_2.to_instruction(), q[0:-1])

        # attach a final CNOT
        circuit.append(CnotGate(), [msb, lsb])

        return circuit
Beispiel #9
0
    def _multiplex(self, bottom_gate, bottom_qubit_index, list_of_angles):
        """
        Internal recursive method to create gates to perform rotations on the
        imaginary qubits: works by rotating LSB (and hence ALL imaginary
        qubits) by combo angle and then flipping sign (by flipping the bit,
        hence moving the complex amplitudes) of half the imaginary qubits
        (CNOT) followed by another combo angle on LSB, therefore executing
        conditional (on MSB) rotations, thereby disentangling LSB.
        """
        list_len = len(list_of_angles)
        target_qubit = self.nth_qubit_from_least_sig_qubit(bottom_qubit_index)

        # Case of no multiplexing = base case for recursion
        if list_len == 1:
            return bottom_gate(list_of_angles[0], target_qubit)

        local_num_qubits = int(math.log2(list_len)) + 1
        control_qubit = self.nth_qubit_from_least_sig_qubit(
            local_num_qubits - 1 + bottom_qubit_index)

        # calc angle weights, assuming recursion (that is the lower-level
        # requested angles have been correctly implemented by recursion
        angle_weight = scipy.kron([[0.5, 0.5], [0.5, -0.5]],
                                  numpy.identity(2 ** (local_num_qubits - 2)))

        # calc the combo angles
        list_of_angles = (angle_weight * numpy.matrix(
            list_of_angles).transpose()).reshape(-1).tolist()[0]

        combine_composite_gates = CompositeGate(
            "multiplex" + local_num_qubits.__str__(), [], self.arg)

        # recursive step on half the angles fulfilling the above assumption
        combine_composite_gates._attach(
            self._multiplex(bottom_gate, bottom_qubit_index,
                            list_of_angles[0:(list_len // 2)]))

        # combine_composite_gates.cx(control_qubit,target_qubit) -> does not
        # work as expected because checks circuit
        # so attach CNOT as follows, thereby flipping the LSB qubit
        combine_composite_gates._attach(CnotGate(control_qubit, target_qubit))

        # implement extra efficiency from the paper of cancelling adjacent
        # CNOTs (by leaving out last CNOT and reversing (NOT inverting) the
        # second lower-level multiplex)
        sub_gate = self._multiplex(
            bottom_gate, bottom_qubit_index, list_of_angles[(list_len // 2):])
        if isinstance(sub_gate, CompositeGate):
            combine_composite_gates._attach(sub_gate.reverse())
        else:
            combine_composite_gates._attach(sub_gate)

        # outer multiplex keeps final CNOT, because no adjacent CNOT to cancel
        # with
        if self.num_qubits == local_num_qubits + bottom_qubit_index:
            combine_composite_gates._attach(CnotGate(control_qubit,
                                                     target_qubit))

        return combine_composite_gates
    def test_nodes_in_topological_order(self):
        """ The node_nums_in_topological_order() method"""
        self.dag.apply_operation_back(CnotGate(self.qubit0, self.qubit1))
        self.dag.apply_operation_back(HGate(self.qubit0))
        self.dag.apply_operation_back(CnotGate(self.qubit2, self.qubit1))
        self.dag.apply_operation_back(CnotGate(self.qubit0, self.qubit2))
        self.dag.apply_operation_back(HGate(self.qubit2))

        named_nodes = self.dag.node_nums_in_topological_order()
        self.assertEqual([9, 10, 7, 8, 5, 3, 1, 11, 13, 4, 12, 14, 15, 6, 2],
                         [i for i in named_nodes])
Beispiel #11
0
 def _define(self):
     """
     gate swap a,b { cx a,b; cx b,a; cx a,b; }
     """
     definition = []
     q = QuantumRegister(2, "q")
     rule = [(CnotGate(), [q[0], q[1]], []), (CnotGate(), [q[1], q[0]], []),
             (CnotGate(), [q[0], q[1]], [])]
     for inst in rule:
         definition.append(inst)
     self.definition = definition
Beispiel #12
0
 def _define(self):
     """
     gate rzz(theta) a, b { cx a, b; u1(theta) b; cx a, b; }
     """
     definition = []
     q = QuantumRegister(2, "q")
     rule = [(CnotGate(), [q[0], q[1]], []),
             (U1Gate(self.params[0]), [q[1]], []),
             (CnotGate(), [q[0], q[1]], [])]
     for inst in rule:
         definition.append(inst)
     self.definition = definition
Beispiel #13
0
    def test_remove_op_node_longer(self):
        """Test remove_op_node method in a "longer" dag"""
        self.dag.apply_operation_back(CnotGate(), [self.qubit0, self.qubit1])
        self.dag.apply_operation_back(HGate(), [self.qubit0])
        self.dag.apply_operation_back(CnotGate(), [self.qubit2, self.qubit1])
        self.dag.apply_operation_back(CnotGate(), [self.qubit0, self.qubit2])
        self.dag.apply_operation_back(HGate(), [self.qubit2])

        op_nodes = list(self.dag.topological_op_nodes())
        self.dag.remove_op_node(op_nodes[0])

        expected = [('h', [self.qubit0]), ('cx', [self.qubit2, self.qubit1]),
                    ('cx', [self.qubit0, self.qubit2]), ('h', [self.qubit2])]
        self.assertEqual(expected, [(i.name, i.qargs)
                                    for i in self.dag.topological_op_nodes()])
Beispiel #14
0
 def _process_cnot(self, node):
     """Process a CNOT gate node."""
     id0 = self._process_bit_id(node.children[0])
     id1 = self._process_bit_id(node.children[1])
     if not (len(id0) == len(id1) or len(id0) == 1 or len(id1) == 1):
         raise QiskitError("internal error: qreg size mismatch",
                           "line=%s" % node.line, "file=%s" % node.file)
     maxidx = max([len(id0), len(id1)])
     for idx in range(maxidx):
         if len(id0) > 1 and len(id1) > 1:
             self.dag.apply_operation_back(CnotGate(), [id0[idx], id1[idx]], [], self.condition)
         elif len(id0) > 1:
             self.dag.apply_operation_back(CnotGate(), [id0[idx], id1[0]], [], self.condition)
         else:
             self.dag.apply_operation_back(CnotGate(), [id0[0], id1[idx]], [], self.condition)
Beispiel #15
0
 def _define_decompositions(self):
     """
     gate swap a,b { cx a,b; cx b,a; cx a,b; }
     """
     decomposition = DAGCircuit()
     q = QuantumRegister(2, "q")
     decomposition.add_qreg(q)
     rule = [
         CnotGate(q[0], q[1]),
         CnotGate(q[1], q[0]),
         CnotGate(q[0], q[1])
     ]
     for inst in rule:
         decomposition.apply_operation_back(inst)
     self._decompositions = [decomposition]
Beispiel #16
0
    def test_topological_op_nodes(self):
        """The topological_op_nodes() method"""
        self.dag.apply_operation_back(CnotGate(), [self.qubit0, self.qubit1], [])
        self.dag.apply_operation_back(HGate(), [self.qubit0], [])
        self.dag.apply_operation_back(CnotGate(), [self.qubit2, self.qubit1], [])
        self.dag.apply_operation_back(CnotGate(), [self.qubit0, self.qubit2], [])
        self.dag.apply_operation_back(HGate(), [self.qubit2], [])

        named_nodes = self.dag.topological_op_nodes()

        expected = [('cx', [self.qubit0, self.qubit1]),
                    ('h', [self.qubit0]),
                    ('cx', [self.qubit2, self.qubit1]),
                    ('cx', [self.qubit0, self.qubit2]),
                    ('h', [self.qubit2])]
        self.assertEqual(expected, [(i.name, i.qargs) for i in named_nodes])
Beispiel #17
0
    def test_instructions_equal(self):
        """Test equality of two instructions."""
        hop1 = Instruction('h', 1, 0, [])
        hop2 = Instruction('s', 1, 0, [])
        hop3 = Instruction('h', 1, 0, [])

        self.assertFalse(hop1 == hop2)
        self.assertTrue(hop1 == hop3)

        uop1 = Instruction('u', 1, 0, [0.4, 0.5, 0.5])
        uop2 = Instruction('u', 1, 0, [0.4, 0.6, 0.5])
        uop3 = Instruction('v', 1, 0, [0.4, 0.5, 0.5])
        uop4 = Instruction('u', 1, 0, [0.4, 0.5, 0.5])

        self.assertFalse(uop1 == uop2)
        self.assertTrue(uop1 == uop4)
        self.assertFalse(uop1 == uop3)

        self.assertTrue(HGate() == HGate())
        self.assertFalse(HGate() == CnotGate())
        self.assertFalse(hop1 == HGate())

        eop1 = Instruction('kraus', 1, 0, [np.array([[1, 0], [0, 1]])])
        eop2 = Instruction('kraus', 1, 0, [np.array([[0, 1], [1, 0]])])
        eop3 = Instruction('kraus', 1, 0, [np.array([[1, 0], [0, 1]])])
        eop4 = Instruction('kraus', 1, 0, [np.eye(4)])

        self.assertTrue(eop1 == eop3)
        self.assertFalse(eop1 == eop2)
        self.assertFalse(eop1 == eop4)
Beispiel #18
0
 def _define(self):
     """
     self.u3(theta / 2, 0, 0, q_target)
     self.cx(q_control, q_target)
     self.u3(-theta / 2, 0, 0, q_target)
     self.cx(q_control, q_target)
     """
     definition = []
     q = QuantumRegister(2, "q")
     rule = [(U3Gate(self.params[0] / 2, 0, 0), [q[1]], []),
             (CnotGate(), [q[0], q[1]], []),
             (U3Gate(-self.params[0] / 2, 0, 0), [q[1]], []),
             (CnotGate(), [q[0], q[1]], [])]
     for inst in rule:
         definition.append(inst)
     self.definition = definition
Beispiel #19
0
    def test_layers_basic(self):
        """The layers() method returns a list of layers, each of them with a list of nodes."""
        qreg = QuantumRegister(2, 'qr')
        creg = ClassicalRegister(2, 'cr')
        qubit0 = qreg[0]
        qubit1 = qreg[1]
        clbit0 = creg[0]
        clbit1 = creg[1]
        condition = (creg, 3)
        dag = DAGCircuit()
        dag.add_qreg(qreg)
        dag.add_creg(creg)
        dag.apply_operation_back(HGate(), [qubit0], [])
        dag.apply_operation_back(CnotGate(), [qubit0, qubit1], [],
                                 condition=None)
        dag.apply_operation_back(Measure(), [qubit1, clbit1], [],
                                 condition=None)
        dag.apply_operation_back(XGate(), [qubit1], [], condition=condition)
        dag.apply_operation_back(Measure(), [qubit0, clbit0], [],
                                 condition=None)
        dag.apply_operation_back(Measure(), [qubit1, clbit1], [],
                                 condition=None)

        layers = list(dag.layers())
        self.assertEqual(5, len(layers))

        name_layers = [[
            node.op.name for node in layer["graph"].nodes()
            if node.type == "op"
        ] for layer in layers]

        self.assertEqual(
            [['h'], ['cx'], ['measure'], ['x'], ['measure', 'measure']],
            name_layers)
Beispiel #20
0
    def test_substituting_node_preserves_name_args_condition(self, inplace):
        """Verify name, args and condition are preserved by a substitution."""
        dag = DAGCircuit()
        qr = QuantumRegister(2)
        cr = ClassicalRegister(1)
        dag.add_qreg(qr)
        dag.add_creg(cr)
        dag.apply_operation_back(HGate(), [qr[1]])
        node_to_be_replaced = dag.apply_operation_back(CnotGate(),
                                                       [qr[1], qr[0]],
                                                       condition=(cr, 1))
        node_to_be_replaced.name = 'test_name'
        dag.apply_operation_back(HGate(), [qr[1]])

        replacement_node = dag.substitute_node(node_to_be_replaced,
                                               CzGate(),
                                               inplace=inplace)

        raise_if_dagcircuit_invalid(dag)
        self.assertEqual(replacement_node.name, 'test_name')
        self.assertEqual(replacement_node.qargs, [qr[1], qr[0]])
        self.assertEqual(replacement_node.cargs, [])
        self.assertEqual(replacement_node.condition, (cr, 1))

        self.assertEqual(replacement_node is node_to_be_replaced, inplace)
Beispiel #21
0
    def test_layers_basic(self):
        """ The layers() method returns a list of layers, each of them with a list of nodes."""
        qreg = QuantumRegister(2, 'qr')
        creg = ClassicalRegister(2, 'cr')
        qubit0 = qreg[0]
        qubit1 = qreg[1]
        clbit0 = creg[0]
        clbit1 = creg[1]
        condition = (creg, 3)
        dag = DAGCircuit()
        dag.add_basis_element('h', 1, 0, 0)
        dag.add_basis_element('cx', 2, 0, 0)
        dag.add_basis_element('x', 1, 0, 0)
        dag.add_basis_element('measure', 1, 1, 0)
        dag.add_qreg(qreg)
        dag.add_creg(creg)
        dag.apply_operation_back(HGate(qubit0))
        dag.apply_operation_back(CnotGate(qubit0, qubit1), condition=None)
        dag.apply_operation_back(Measure(qubit1, clbit1), condition=None)
        dag.apply_operation_back(XGate(qubit1), condition=condition)
        dag.apply_operation_back(Measure(qubit0, clbit0), condition=None)
        dag.apply_operation_back(Measure(qubit1, clbit1), condition=None)

        layers = list(dag.layers())
        self.assertEqual(5, len(layers))

        name_layers = [[
            node[1]["op"].name
            for node in layer["graph"].multi_graph.nodes(data=True)
            if node[1]["type"] == "op"
        ] for layer in layers]

        self.assertEqual(
            [['h'], ['cx'], ['measure'], ['x'], ['measure', 'measure']],
            name_layers)
Beispiel #22
0
 def _define(self):
     """
     gate cswap a,b,c
     { cx c,b;
       ccx a,b,c;
       cx c,b;
     }
     """
     definition = []
     q = QuantumRegister(3, "q")
     rule = [(CnotGate(), [q[2], q[1]], []),
             (ToffoliGate(), [q[0], q[1], q[2]], []),
             (CnotGate(), [q[2], q[1]], [])]
     for inst in rule:
         definition.append(inst)
     self.definition = definition
Beispiel #23
0
 def _define(self):
     """
     gate crz(lambda) a,b
     { u1(lambda/2) b; cx a,b;
       u1(-lambda/2) b; cx a,b;
     }
     """
     definition = []
     q = QuantumRegister(2, "q")
     rule = [(U1Gate(self.params[0] / 2), [q[1]], []),
             (CnotGate(), [q[0], q[1]], []),
             (U1Gate(-self.params[0] / 2), [q[1]], []),
             (CnotGate(), [q[0], q[1]], [])]
     for inst in rule:
         definition.append(inst)
     self.definition = definition
Beispiel #24
0
    def setUp(self):
        self.dag = DAGCircuit()
        qreg = QuantumRegister(3, 'qr')
        creg = ClassicalRegister(2, 'cr')
        self.dag.add_qreg(qreg)
        self.dag.add_creg(creg)
        self.dag.add_basis_element(name='h',
                                   number_qubits=1,
                                   number_classical=0,
                                   number_parameters=0)
        self.dag.add_basis_element('cx', 2, 0, 0)
        self.dag.add_basis_element('x', 1, 0, 0)
        self.dag.add_basis_element('measure', 1, 1, 0)
        self.dag.add_basis_element('reset', 1, 0, 0)

        self.qubit0 = qreg[0]
        self.qubit1 = qreg[1]
        self.qubit2 = qreg[2]
        self.clbit0 = creg[0]
        self.clbit1 = creg[1]
        self.condition = (creg, 3)

        self.dag.apply_operation_back(HGate(self.qubit0))
        self.dag.apply_operation_back(CnotGate(self.qubit0, self.qubit1))
        self.dag.apply_operation_back(XGate(self.qubit1))
Beispiel #25
0
 def _define_decompositions(self):
     decomposition = DAGCircuit()
     q = QuantumRegister(6, "q")
     decomposition.add_qreg(q)
     decomposition.add_basis_element("u1", 1, 0, 1)
     decomposition.add_basis_element("h", 1, 0, 0)
     decomposition.add_basis_element("x", 1, 0, 0)
     decomposition.add_basis_element("cx", 2, 0, 0)
     decomposition.add_basis_element("ccx", 3, 0, 0)
     decomposition.add_basis_element("c3x", 4, 0, 0)
     decomposition.add_basis_element("c4x", 5, 0, 0)
     decomposition.add_basis_element("t", 1, 0, 0)
     decomposition.add_basis_element("tdg", 1, 0, 0)
     rule = [
         HGate(q[5]),
         C4NotGate(q[0], q[1], q[2], q[3], q[5]),
         TdgGate(q[5]),
         CnotGate(q[4], q[5]),
         TGate(q[5]),
         C4NotGate(q[0], q[1], q[2], q[3], q[5]),
         TdgGate(q[5]),
         CnotGate(q[4], q[5]),
         TGate(q[5]),
         HGate(q[5]),
         C4NotGate(q[0], q[1], q[2], q[3], q[4]),
         C3NotGate(q[0], q[1], q[2], q[3]),
         ToffoliGate(q[0], q[1], q[2]),
         CnotGate(q[0], q[1]),
         XGate(q[0]),
         U1Gate(-math.pi / 32, q[1]),
         U1Gate(-math.pi / 16, q[2]),
         U1Gate(-math.pi / 8, q[3]),
         U1Gate(-math.pi / 4, q[4]),
         XGate(q[0]),
         CnotGate(q[0], q[1]),
         ToffoliGate(q[0], q[1], q[2]),
         C3NotGate(q[0], q[1], q[2], q[3]),
         C4NotGate(q[0], q[1], q[2], q[3], q[4]),
         U1Gate(math.pi / 32, q[0]),
         U1Gate(math.pi / 32, q[1]),
         U1Gate(math.pi / 16, q[2]),
         U1Gate(math.pi / 8, q[3]),
         U1Gate(math.pi / 4, q[4])
     ]
     for inst in rule:
         decomposition.apply_operation_back(inst)
     self._decompositions = [decomposition]
Beispiel #26
0
 def _define_decompositions(self):
     """
     gate rzz(theta) a, b { cx a, b; u1(theta) b; cx a, b; }
     """
     decomposition = DAGCircuit()
     q = QuantumRegister(2, "q")
     decomposition.add_qreg(q)
     decomposition.add_basis_element("u1", 1, 0, 1)
     decomposition.add_basis_element("cx", 2, 0, 0)
     rule = [
         CnotGate(q[0], q[1]),
         U1Gate(self.param[0], q[0]),
         CnotGate(q[0], q[1])
     ]
     for inst in rule:
         decomposition.apply_operation_back(inst)
     self._decompositions = [decomposition]
Beispiel #27
0
 def _define(self):
     """Calculate a subcircuit that implements this unitary."""
     definition = []
     q = QuantumRegister(2, "q")
     theta = self.params[0]
     rule = [
         (U3Gate(np.pi / 2, theta, 0), [q[0]], []),
         (HGate(), [q[1]], []),
         (CnotGate(), [q[0], q[1]], []),
         (U1Gate(-theta), [q[1]], []),
         (CnotGate(), [q[0], q[1]], []),
         (HGate(), [q[1]], []),
         (U2Gate(-np.pi, np.pi - theta), [q[0]], []),
     ]
     for inst in rule:
         definition.append(inst)
     self.definition = definition
 def _define(self):
     """
     gate cswap a,b,c
     { cx c,b;
       ccx a,b,c;
       # now it is swapped: b,c
       cx pi(c),pi(b);
     }
     """
     definition = []
     q = QuantumRegister(3, "q")
     rule = [(CnotGate(), [q[2], q[1]], []),
             (Ourense_ToffoliGate(), [q[0], q[1], q[2]], []),
             (CnotGate(), [q[1], q[2]], [])]
     for inst in rule:
         definition.append(inst)
     self.definition = definition
Beispiel #29
0
def direction_mapper(circuit_graph, coupling_graph):
    """Change the direction of CNOT gates to conform to CouplingGraph.

    circuit_graph = input DAGCircuit
    coupling_graph = corresponding CouplingGraph

    Adds "h" to the circuit basis.

    Returns a DAGCircuit object containing a circuit equivalent to
    circuit_graph but with CNOT gate directions matching the edges
    of coupling_graph. Raises an exception if the circuit_graph
    does not conform to the coupling_graph.
    """
    if "cx" not in circuit_graph.basis:
        return circuit_graph
    if circuit_graph.basis["cx"] != (2, 0, 0):
        raise MapperError("cx gate has unexpected signature %s" %
                          circuit_graph.basis["cx"])

    qr_fcx = QuantumRegister(2, "fcx")
    flipped_cx_circuit = DAGCircuit()
    flipped_cx_circuit.add_qreg(qr_fcx)
    flipped_cx_circuit.add_basis_element("CX", 2)
    flipped_cx_circuit.add_basis_element("U", 1, 0, 3)
    flipped_cx_circuit.add_basis_element("cx", 2)
    flipped_cx_circuit.add_basis_element("u2", 1, 0, 2)
    flipped_cx_circuit.add_basis_element("h", 1)
    flipped_cx_circuit.add_gate_data("cx", cx_data)
    flipped_cx_circuit.add_gate_data("u2", u2_data)
    flipped_cx_circuit.add_gate_data("h", h_data)
    flipped_cx_circuit.apply_operation_back(HGate(qr_fcx[0]))
    flipped_cx_circuit.apply_operation_back(HGate(qr_fcx[1]))
    flipped_cx_circuit.apply_operation_back(CnotGate(qr_fcx[1], qr_fcx[0]))
    flipped_cx_circuit.apply_operation_back(HGate(qr_fcx[0]))
    flipped_cx_circuit.apply_operation_back(HGate(qr_fcx[1]))

    q_tmp = QuantumRegister(coupling_graph.size(), 'q')
    cg_edges = [((q_tmp, i), (q_tmp, j)) for i, j in coupling_graph.get_edges()]

    for cx_node in circuit_graph.get_named_nodes("cx"):
        nd = circuit_graph.multi_graph.node[cx_node]
        cxedge = tuple(nd["qargs"])
        if cxedge in cg_edges:
            logger.debug("cx %s[%d], %s[%d] -- OK",
                         cxedge[0][0], cxedge[0][1],
                         cxedge[1][0], cxedge[1][1])
            continue
        elif (cxedge[1], cxedge[0]) in cg_edges:
            circuit_graph.substitute_circuit_one(cx_node,
                                                 flipped_cx_circuit,
                                                 wires=[qr_fcx[0], qr_fcx[1]])
            logger.debug("cx %s[%d], %s[%d] -FLIP",
                         cxedge[0][0], cxedge[0][1],
                         cxedge[1][0], cxedge[1][1])
        else:
            raise MapperError("circuit incompatible with CouplingGraph: "
                              "cx on %s" % pprint.pformat(cxedge))
    return circuit_graph
    def test_get_named_nodes(self):
        """The get_named_nodes(AName) method returns all the nodes with name AName"""
        self.dag.apply_operation_back(CnotGate(self.qubit0, self.qubit1))
        self.dag.apply_operation_back(HGate(self.qubit0))
        self.dag.apply_operation_back(CnotGate(self.qubit2, self.qubit1))
        self.dag.apply_operation_back(CnotGate(self.qubit0, self.qubit2))
        self.dag.apply_operation_back(HGate(self.qubit2))

        # The ordering is not assured, so we only compare the output (unordered) sets.
        # We use tuples because lists aren't hashable.
        named_nodes = self.dag.get_named_nodes('cx')
        node_qargs = {tuple(self.dag.multi_graph.node[node_id]["op"].qargs)
                      for node_id in named_nodes}
        expected_qargs = {
            (self.qubit0, self.qubit1),
            (self.qubit2, self.qubit1),
            (self.qubit0, self.qubit2)}
        self.assertEqual(expected_qargs, node_qargs)