def test_remove_op_node(self): """Test remove_op_node method.""" self.dag.apply_operation_back(HGate(), [self.qubit0]) op_nodes = self.dag.gate_nodes() h_gate = op_nodes.pop() self.dag.remove_op_node(h_gate) self.assertEqual(len(self.dag.gate_nodes()), 0)
def test_apply_operation_front(self): """The apply_operation_front() method""" self.dag.apply_operation_back(HGate(self.qubit0)) self.dag.apply_operation_front(Reset(self.qubit0)) h_node = self.dag.op_nodes(op=HGate).pop() reset_node = self.dag.op_nodes(op=Reset).pop() self.assertIn(reset_node, set(self.dag.multi_graph.predecessors(h_node)))
def test_substitute_circuit_one_middle(self): """The method substitute_node_with_dag() replaces a in-the-middle node with a DAG.""" cx_node = self.dag.op_nodes(op=CnotGate).pop() flipped_cx_circuit = DAGCircuit() v = QuantumRegister(2, "v") flipped_cx_circuit.add_qreg(v) flipped_cx_circuit.apply_operation_back(HGate(), [v[0]], []) flipped_cx_circuit.apply_operation_back(HGate(), [v[1]], []) flipped_cx_circuit.apply_operation_back(CnotGate(), [v[1], v[0]], []) flipped_cx_circuit.apply_operation_back(HGate(), [v[0]], []) flipped_cx_circuit.apply_operation_back(HGate(), [v[1]], []) self.dag.substitute_node_with_dag(cx_node, flipped_cx_circuit, wires=[v[0], v[1]]) self.assertEqual(self.dag.count_ops()['h'], 5)
def test_get_named_nodes(self): """The get_named_nodes(AName) method returns all the nodes with name AName""" self.dag.apply_operation_back(CXGate(), [self.qubit0, self.qubit1], []) self.dag.apply_operation_back(HGate(), [self.qubit0], []) self.dag.apply_operation_back(CXGate(), [self.qubit2, self.qubit1], []) self.dag.apply_operation_back(CXGate(), [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.named_nodes('cx') node_qargs = {tuple(node.qargs) for node in named_nodes} expected_qargs = {(self.qubit0, self.qubit1), (self.qubit2, self.qubit1), (self.qubit0, self.qubit2)} self.assertEqual(expected_qargs, node_qargs)
def test_get_op_nodes_particular(self): """The method dag.get_gates_nodes(op=AGate) returns all the AGate nodes""" self.dag.apply_operation_back(HGate(self.qubit0)) self.dag.apply_operation_back(HGate(self.qubit1)) self.dag.apply_operation_back(Reset(self.qubit0)) self.dag.apply_operation_back(CnotGate(self.qubit0, self.qubit1)) op_nodes = self.dag.get_op_nodes(op=HGate(self.qubit0)) self.assertEqual(len(op_nodes), 2) op_node_1 = op_nodes.pop() op_node_2 = op_nodes.pop() self.assertIsInstance(self.dag.multi_graph.nodes[op_node_1]["op"], HGate) self.assertIsInstance(self.dag.multi_graph.nodes[op_node_2]["op"], HGate)
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, []) 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(hop1 == hop2) self.assertTrue(hop1 == hop3) self.assertFalse(uop1 == uop2) self.assertTrue(uop1 == uop4) self.assertFalse(uop1 == uop3) self.assertTrue(HGate() == HGate()) self.assertFalse(HGate() == CnotGate()) self.assertFalse(hop1 == HGate())
def test_apply_operation_back(self): """The apply_operation_back() method.""" self.dag.apply_operation_back(HGate(), [self.qubit0], [], condition=None) self.dag.apply_operation_back(CnotGate(), [self.qubit0, self.qubit1], [], condition=None) self.dag.apply_operation_back(Measure(), [self.qubit1, self.clbit1], [], condition=None) self.dag.apply_operation_back(XGate(), [self.qubit1], [], condition=self.condition) self.dag.apply_operation_back(Measure(), [self.qubit0, self.clbit0], [], condition=None) self.dag.apply_operation_back(Measure(), [self.qubit1, self.clbit1], [], condition=None) self.assertEqual(len(list(self.dag.nodes())), 16) self.assertEqual(len(list(self.dag.edges())), 17)
def test_apply_operation_back(self): """The apply_operation_back() method.""" self.dag.apply_operation_back(HGate(self.qubit0), condition=None) self.dag.apply_operation_back(CnotGate(self.qubit0, self.qubit1), condition=None) self.dag.apply_operation_back(Measure(self.qubit1, self.clbit1), condition=None) self.dag.apply_operation_back(XGate(self.qubit1), condition=self.condition) self.dag.apply_operation_back(Measure(self.qubit0, self.clbit0), condition=None) self.dag.apply_operation_back(Measure(self.qubit1, self.clbit1), condition=None) self.assertEqual(len(self.dag.multi_graph.nodes), 16) self.assertEqual(len(self.dag.multi_graph.edges), 17)
def test_substitute_circuit_one_middle(self): """The method substitute_circuit_one() replaces a in-the-middle node with a DAG.""" cx_node = self.dag.get_op_nodes(op=CnotGate(self.qubit0, self.qubit1)).pop() flipped_cx_circuit = DAGCircuit() v = QuantumRegister(2, "v") flipped_cx_circuit.add_qreg(v) flipped_cx_circuit.add_basis_element("cx", 2) flipped_cx_circuit.add_basis_element("h", 1) flipped_cx_circuit.apply_operation_back(HGate(v[0])) flipped_cx_circuit.apply_operation_back(HGate(v[1])) flipped_cx_circuit.apply_operation_back(CnotGate(v[1], v[0])) flipped_cx_circuit.apply_operation_back(HGate(v[0])) flipped_cx_circuit.apply_operation_back(HGate(v[1])) self.dag.substitute_circuit_one(cx_node, input_circuit=flipped_cx_circuit, wires=[v[0], v[1]]) self.assertEqual(self.dag.count_ops()['h'], 5)
def test_substituting_io_node_raises(self, inplace): """Verify replacing an io node raises.""" dag = DAGCircuit() qr = QuantumRegister(1) dag.add_qreg(qr) io_node = next(dag.nodes()) with self.assertRaises(DAGCircuitError) as _: dag.substitute_node(io_node, HGate(), inplace=inplace)
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("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("t", 1, 0, 0) decomposition.add_basis_element("tdg", 1, 0, 0) rule = [ HGate(q[4]), C3NotGate(q[0], q[1], q[2], q[4]), TdgGate(q[4]), CnotGate(q[3], q[4]), TGate(q[4]), C3NotGate(q[0], q[1], q[2], q[4]), TdgGate(q[4]), CnotGate(q[3], q[4]), TGate(q[4]), HGate(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 / 16, q[1]), U1Gate(-math.pi / 8, q[2]), U1Gate(-math.pi / 4, q[3]), XGate(q[0]), CnotGate(q[0], q[1]), ToffoliGate(q[0], q[1], q[2]), C3NotGate(q[0], q[1], q[2], q[3]), U1Gate(math.pi / 16, q[0]), U1Gate(math.pi / 16, q[1]), U1Gate(math.pi / 8, q[2]), U1Gate(math.pi / 4, q[3]) ] for inst in rule: decomposition.apply_operation_back(inst) self._decompositions = [decomposition]
def test_apply_operation_back_conditional(self): """Test consistency of apply_operation_back with condition set.""" # Single qubit gate conditional: qc.h(qr[2]).c_if(cr, 3) h_gate = HGate() h_gate.condition = self.condition h_node = self.dag.apply_operation_back(h_gate, [self.qubit2], [], h_gate.condition) self.assertEqual(h_node.qargs, [self.qubit2]) self.assertEqual(h_node.cargs, []) self.assertEqual(h_node.condition, h_gate.condition) self.assertEqual( sorted(self.dag._get_multi_graph_in_edges(h_node._node_id)), sorted([ (self.dag.input_map[self.qubit2]._node_id, h_node._node_id, { 'wire': self.qubit2, 'name': 'qr[2]' }), (self.dag.input_map[self.clbit0]._node_id, h_node._node_id, { 'wire': self.clbit0, 'name': 'cr[0]' }), (self.dag.input_map[self.clbit1]._node_id, h_node._node_id, { 'wire': self.clbit1, 'name': 'cr[1]' }), ])) self.assertEqual( sorted(self.dag._get_multi_graph_out_edges(h_node._node_id)), sorted([ (h_node._node_id, self.dag.output_map[self.qubit2]._node_id, { 'wire': self.qubit2, 'name': 'qr[2]' }), (h_node._node_id, self.dag.output_map[self.clbit0]._node_id, { 'wire': self.clbit0, 'name': 'cr[0]' }), (h_node._node_id, self.dag.output_map[self.clbit1]._node_id, { 'wire': self.clbit1, 'name': 'cr[1]' }), ])) if self.dag._USE_RX: self.assertTrue(rx.is_directed_acyclic_graph( self.dag._multi_graph)) else: self.assertTrue(nx.is_directed_acyclic_graph( self.dag._multi_graph))
def _define(self): self.definition = [] q = QuantumRegister(self.num_qubits) for i in range(self.num_qubits): self.definition.append((HGate(), [q[i]], [])) for distance in range(self.num_qubits - i - 1): distance = distance + 1 self.definition.append( (Cu1Gate(pi / 2**distance), [q[distance + i], q[i]], [])) if self.params[0]: self.definition.append((DoSwapsGate(self.num_qubits), q, []))
def test_get_op_nodes_all(self): """The method dag.op_nodes() returns all op nodes""" self.dag.apply_operation_back(HGate(), [self.qubit0], []) self.dag.apply_operation_back(CnotGate(), [self.qubit0, self.qubit1], []) self.dag.apply_operation_back(Reset(), [self.qubit0], []) op_nodes = self.dag.op_nodes() self.assertEqual(len(op_nodes), 3) for node in op_nodes: self.assertIsInstance(node.op, Instruction)
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', [self.qubit0, self.qubit1]), ('h', [self.qubit0]), ('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 named_nodes])
def _define(self): """Calculate a subcircuit that implements this unitary.""" from qiskit.extensions.standard.x import CXGate from qiskit.extensions.standard.u1 import U1Gate from qiskit.extensions.standard.h import HGate definition = [] q = QuantumRegister(2, 'q') theta = self.params[0] rule = [ (HGate(), [q[0]], []), (HGate(), [q[1]], []), (CXGate(), [q[0], q[1]], []), (U1Gate(theta), [q[1]], []), (CXGate(), [q[0], q[1]], []), (HGate(), [q[1]], []), (HGate(), [q[0]], []), ] for inst in rule: definition.append(inst) self.definition = definition
def test_get_op_nodes_all(self): """The method dag.get_op_nodes() returns all op nodes""" self.dag.apply_operation_back(HGate(self.qubit0)) self.dag.apply_operation_back(CnotGate(self.qubit0, self.qubit1)) self.dag.apply_operation_back(Reset(self.qubit0)) op_nodes = self.dag.get_op_nodes() self.assertEqual(len(op_nodes), 3) for node in op_nodes: self.assertIsInstance(self.dag.multi_graph.nodes[node]["op"], Instruction)
def _define(self): """ gate c3sqrtx a,b,c,d { h d; cu1(-pi/8) a,d; h d; cx a,b; h d; cu1(pi/8) b,d; h d; cx a,b; h d; cu1(-pi/8) b,d; h d; cx b,c; h d; cu1(pi/8) c,d; h d; cx a,c; h d; cu1(-pi/8) c,d; h d; cx b,c; h d; cu1(pi/8) c,d; h d; cx a,c; h d; cu1(-pi/8) c,d; h d; } gate c4x a,b,c,d,e { h e; cu1(-pi/2) d,e; h e; c3x a,b,c,d; h d; cu1(pi/4) d,e; h d; c3x a,b,c,d; c3sqrtx a,b,c,e; } """ from qiskit.extensions.standard.u1 import CU1Gate q = QuantumRegister(5, name='q') definition = [ (HGate(), [q[4]], []), (CU1Gate(-numpy.pi / 2), [q[3], q[4]], []), (HGate(), [q[4]], []), (C3XGate(), [q[0], q[1], q[2], q[3]], []), (HGate(), [q[4]], []), (CU1Gate(numpy.pi / 2), [q[3], q[4]], []), (HGate(), [q[4]], []), (C3XGate(), [q[0], q[1], q[2], q[3]], []), (C3XGate(numpy.pi / 8), [q[0], q[1], q[2], q[4]], []), ] self.definition = definition
def _define(self): """ gate ch a,b { s b; h b; t b; cx a, b; tdg b; h b; sdg b; } """ definition = [] q = QuantumRegister(2, "q") rule = [(SGate(), [q[1]], []), (HGate(), [q[1]], []), (TGate(), [q[1]], []), (CnotGate(), [q[0], q[1]], []), (TdgGate(), [q[1]], []), (HGate(), [q[1]], []), (SdgGate(), [q[1]], [])] for inst in rule: definition.append(inst) self.definition = definition
def test_is_parameterized(self): """Test checking if a gate is parameterized (bound/unbound)""" from qiskit.extensions.standard.h import HGate from qiskit.extensions.standard.rx import RXGate theta = Parameter('θ') rxg = RXGate(theta) self.assertTrue(rxg.is_parameterized()) theta_bound = theta.bind({theta: 3.14}) rxg = RXGate(theta_bound) self.assertFalse(rxg.is_parameterized()) h_gate = HGate() self.assertFalse(h_gate.is_parameterized())
def test_get_op_nodes_all(self): """The method dag.get_op_nodes() returns all op nodes""" self.dag.apply_operation_back(HGate(self.qubit0)) self.dag.apply_operation_back(CnotGate(self.qubit0, self.qubit1)) op_nodes = self.dag.get_op_nodes() self.assertEqual(len(op_nodes), 2) op_node_1 = op_nodes.pop() op_node_2 = op_nodes.pop() self.assertIsInstance(self.dag.multi_graph.nodes[op_node_1]["op"], Gate) self.assertIsInstance(self.dag.multi_graph.nodes[op_node_2]["op"], Gate)
def __init__(self, ctrl1: QubitType, ctrl2: QubitType, target: QubitType, circuit: QuantumCircuit = None): """Initialize the CCZGate class. :param ctrl1: The first control qubit used to control the CCZ gate. :param ctrl2: The second control qubit used to control the CCZ gate. :param target: The qubit on which the Z gate is applied. :param circuit: The associated quantum circuit. """ used_qubits = [ctrl1, ctrl2, target] super().__init__(self.__class__.__name__, # name [], # parameters used_qubits, # qubits circuit) # circuit self.comment("CCZ") from qiskit.extensions.standard.h import HGate self._attach(HGate(target, circuit).inverse()) self.ccx(ctrl1, ctrl2, target) self._attach(HGate(target, circuit).inverse())
def test_instructions_equal(self): """Test equality of two instructions. """ qr = QuantumRegister(3) cr = ClassicalRegister(3) hop1 = Instruction('h', [], qr, cr) hop2 = Instruction('s', [], qr, cr) hop3 = Instruction('h', [], qr, cr) uop1 = Instruction('u', [0.4, 0.5, 0.5], qr, cr) uop2 = Instruction('u', [0.4, 0.6, 0.5], qr, cr) uop3 = Instruction('v', [0.4, 0.5, 0.5], qr, cr) uop4 = Instruction('u', [0.4, 0.5, 0.5], qr, cr) self.assertFalse(hop1 == hop2) self.assertTrue(hop1 == hop3) self.assertFalse(uop1 == uop2) self.assertTrue(uop1 == uop4) self.assertFalse(uop1 == uop3) self.assertTrue(HGate(qr[0]) == HGate(qr[1])) self.assertFalse(HGate(qr[0]) == CnotGate(qr[0], qr[1])) self.assertFalse(hop1 == HGate(qr[2]))
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) decomposition.add_basis_element("x", 1, 0, 0) decomposition.add_basis_element("h", 1, 0, 0) decomposition.add_basis_element("cx", 2, 0, 0) decomposition.add_basis_element("t", 1, 0, 0) decomposition.add_basis_element("s", 1, 0, 0) decomposition.add_basis_element("sdg", 1, 0, 0) 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_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', [(QuantumRegister(3, 'qr'), 0), (QuantumRegister(3, 'qr'), 1)]), ('h', [(QuantumRegister(3, 'qr'), 0)]), ('cx', [(QuantumRegister(3, 'qr'), 2), (QuantumRegister(3, 'qr'), 1)]), ('cx', [(QuantumRegister(3, 'qr'), 0), (QuantumRegister(3, 'qr'), 2)]), ('h', [(QuantumRegister(3, 'qr'), 2)])] self.assertEqual(expected, [(i.name, i.qargs) for i in named_nodes])
def test_edges(self): """Test that DAGCircuit.edges() behaves as expected with ops.""" self.dag.apply_operation_back(HGate(), [self.qubit0], [], condition=None) self.dag.apply_operation_back(CXGate(), [self.qubit0, self.qubit1], [], condition=None) self.dag.apply_operation_back(Measure(), [self.qubit1, self.clbit1], [], condition=None) self.dag.apply_operation_back(XGate(), [self.qubit1], [], condition=self.condition) self.dag.apply_operation_back(Measure(), [self.qubit0, self.clbit0], [], condition=None) self.dag.apply_operation_back(Measure(), [self.qubit1, self.clbit1], [], condition=None) out_edges = self.dag.edges(self.dag.output_map.values()) self.assertEqual(list(out_edges), []) in_edges = self.dag.edges(self.dag.input_map.values()) # number of edges for input nodes should be the same as number of wires self.assertEqual(len(list(in_edges)), 5)
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.nodes_in_topological_order() 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])
def _define(self): """ gate ccx a,b,c { h c; cx b,c; tdg c; cx a,c; t c; cx b,c; tdg c; cx a,c; t b; t c; h c; cx a,b; t a; tdg b; cx a,b;} """ definition = [] q = QuantumRegister(3, "q") rule = [(HGate(), [q[2]], []), (CnotGate(), [q[1], q[2]], []), (TdgGate(), [q[2]], []), (CnotGate(), [q[0], q[2]], []), (TGate(), [q[2]], []), (CnotGate(), [q[1], q[2]], []), (TdgGate(), [q[2]], []), (CnotGate(), [q[0], q[2]], []), (TGate(), [q[1]], []), (TGate(), [q[2]], []), (HGate(), [q[2]], []), (CnotGate(), [q[0], q[1]], []), (TGate(), [q[0]], []), (TdgGate(), [q[1]], []), (CnotGate(), [q[0], q[1]], [])] for inst in rule: definition.append(inst) self.definition = definition
def test_two_q_gates(self): """The method dag.twoQ_gates() returns all 2Q gate nodes""" self.dag.apply_operation_back(HGate(self.qubit0)) self.dag.apply_operation_back(CnotGate(self.qubit0, self.qubit1)) self.dag.apply_operation_back(Barrier((self.qubit0, self.qubit1))) self.dag.apply_operation_back(Reset(self.qubit0)) op_nodes = self.dag.twoQ_gates() self.assertEqual(len(op_nodes), 1) op_node = op_nodes.pop() self.assertIsInstance(op_node["op"], Gate) self.assertEqual(len(op_node['qargs']), 2)
def test_two_q_gates(self): """The method dag.twoQ_gates() returns all 2Q gate nodes""" self.dag.apply_operation_back(HGate(), [self.qubit0], []) self.dag.apply_operation_back(CnotGate(), [self.qubit0, self.qubit1], []) self.dag.apply_operation_back(Barrier(2), [self.qubit0, self.qubit1], []) self.dag.apply_operation_back(Reset(), [self.qubit0], []) op_nodes = self.dag.twoQ_gates() self.assertEqual(len(op_nodes), 1) op_node = op_nodes.pop() self.assertIsInstance(op_node.op, Gate) self.assertEqual(len(op_node.qargs), 2)