def test_dag_collect_runs_conditional_in_middle(self): """Test collect_runs with a conditional in the middle of a run.""" h_gate = HGate() h_gate.condition = self.condition self.dag.apply_operation_back(HGate(), [self.qubit0]) self.dag.apply_operation_back( h_gate, [self.qubit0]) self.dag.apply_operation_back(HGate(), [self.qubit0]) collected_runs = self.dag.collect_runs(['h']) # Should return 2 single h gate runs (1 before condition, 1 after) self.assertEqual(len(collected_runs), 2) for run in collected_runs: self.assertEqual(len(run), 1) self.assertEqual(['h'], [x.name for x in run]) self.assertEqual([[self.qubit0]], [x.qargs for x in run])
def test_remove_op_node_longer(self): """Test remove_op_node method in a "longer" dag""" 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]) 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()])
def test_dag_collect_runs_start_with_conditional(self): """Test collect runs with a conditional at the start of the run.""" h_gate = HGate() h_gate.condition = self.condition self.dag.apply_operation_back( h_gate, [self.qubit0]) self.dag.apply_operation_back(HGate(), [self.qubit0]) self.dag.apply_operation_back(HGate(), [self.qubit0]) collected_runs = self.dag.collect_runs(['h']) self.assertEqual(len(collected_runs), 1) run = collected_runs.pop() self.assertEqual(len(run), 2) self.assertEqual(['h', 'h'], [x.name for x in run]) self.assertEqual([[self.qubit0], [self.qubit0]], [x.qargs for x in run])
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], []) 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._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._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]' }), ])) self.assertTrue(rx.is_directed_acyclic_graph(self.dag._multi_graph))
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=CXGate).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(CXGate(), [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_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(CXGate(), [self.qubit2, self.qubit1]) self.dag.apply_operation_back(CXGate(), [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')
def test_topological_op_nodes(self): """The topological_op_nodes() method""" 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], []) 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])
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] x_gate = XGate() x_gate.condition = (creg, 3) dag = DAGCircuit() dag.add_qreg(qreg) dag.add_creg(creg) dag.apply_operation_back(HGate(), [qubit0], []) dag.apply_operation_back(CXGate(), [qubit0, qubit1], []) dag.apply_operation_back(Measure(), [qubit1, clbit1], []) dag.apply_operation_back(x_gate, [qubit1], []) dag.apply_operation_back(Measure(), [qubit0, clbit0], []) dag.apply_operation_back(Measure(), [qubit1, clbit1], []) 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)
def test_get_op_nodes_particular(self): """The method dag.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(CXGate(), [self.qubit0, self.qubit1], []) op_nodes = self.dag.op_nodes(op=HGate) self.assertEqual(len(op_nodes), 2) op_node_1 = op_nodes.pop() op_node_2 = op_nodes.pop() self.assertIsInstance(op_node_1.op, HGate) self.assertIsInstance(op_node_2.op, HGate)
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.predecessors(h_node)))
def _dec_ucg(self): """ Call to create a circuit that implements the uniformly controlled gate. If up_to_diagonal=True, the circuit implements the gate up to a diagonal gate and the diagonal gate is also returned. """ diag = np.ones(2**self.num_qubits).tolist() q = QuantumRegister(self.num_qubits) q_controls = q[1:] q_target = q[0] circuit = QuantumCircuit(q) # If there is no control, we use the ZYZ decomposition if not q_controls: theta, phi, lamb = _DECOMPOSER1Q.angles(self.params[0]) circuit.u3(theta, phi, lamb, q) return circuit, diag # If there is at least one control, first, # we find the single qubit gates of the decomposition. (single_qubit_gates, diag) = self._dec_ucg_help() # Now, it is easy to place the C-NOT gates and some Hadamards and Rz(pi/2) gates # (which are absorbed into the single-qubit unitaries) to get back the full decomposition. for i, gate in enumerate(single_qubit_gates): # Absorb Hadamards and Rz(pi/2) gates if i == 0: squ = HGate().to_matrix().dot(gate) elif i == len(single_qubit_gates) - 1: squ = gate.dot(UCGate._rz(np.pi / 2)).dot(HGate().to_matrix()) else: squ = HGate().to_matrix().dot(gate.dot(UCGate._rz( np.pi / 2))).dot(HGate().to_matrix()) # Add single-qubit gate circuit.squ(squ, q_target) # The number of the control qubit is given by the number of zeros at the end # of the binary representation of (i+1) binary_rep = np.binary_repr(i + 1) num_trailing_zeros = len(binary_rep) - len(binary_rep.rstrip('0')) q_contr_index = num_trailing_zeros # Add C-NOT gate if not i == len(single_qubit_gates) - 1: circuit.cx(q_controls[q_contr_index], q_target) if not self.up_to_diagonal: # Important: the diagonal gate is given in the computational basis of the qubits # q[k-1],...,q[0],q_target (ordered with decreasing significance), # where q[i] are the control qubits and t denotes the target qubit. circuit.diagonal(diag.tolist(), q) return circuit, diag
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_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_front_layer(self): """The method dag.front_layer() returns first layer""" self.dag.apply_operation_back(HGate(), [self.qubit0], []) self.dag.apply_operation_back(CXGate(), [self.qubit0, self.qubit1], []) self.dag.apply_operation_back(Reset(), [self.qubit0], []) op_nodes = self.dag.front_layer() self.assertEqual(len(op_nodes), 1) self.assertIsInstance(op_nodes[0].op, HGate)
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 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(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) self.assertEqual(len(list(self.dag.nodes())), 16) self.assertEqual(len(list(self.dag.edges())), 17)
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(CXGate(), [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 _define_from_label(self): q = QuantumRegister(self.num_qubits, "q") initialize_circuit = QuantumCircuit(q, name="init_def") for qubit, param in enumerate(reversed(self.params)): initialize_circuit.append(Reset(), [q[qubit]]) if param == "1": initialize_circuit.append(XGate(), [q[qubit]]) elif param == "+": initialize_circuit.append(HGate(), [q[qubit]]) elif param == "-": initialize_circuit.append(XGate(), [q[qubit]]) initialize_circuit.append(HGate(), [q[qubit]]) elif param == "r": # |+i> initialize_circuit.append(HGate(), [q[qubit]]) initialize_circuit.append(SGate(), [q[qubit]]) elif param == "l": # |-i> initialize_circuit.append(HGate(), [q[qubit]]) initialize_circuit.append(SdgGate(), [q[qubit]]) return initialize_circuit
def test_two_q_gates(self): """The method dag.two_qubit_ops() returns all 2Q gate operation nodes""" self.dag.apply_operation_back(HGate(), [self.qubit0], []) self.dag.apply_operation_back(CXGate(), [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.two_qubit_ops() 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 _define_from_label(self): q = QuantumRegister(self.num_qubits, 'q') initialize_circuit = QuantumCircuit(q, name='init_def') for qubit, param in enumerate(reversed(self.params)): initialize_circuit.append(Reset(), [q[qubit]]) if param == '1': initialize_circuit.append(XGate(), [q[qubit]]) elif param == '+': initialize_circuit.append(HGate(), [q[qubit]]) elif param == '-': initialize_circuit.append(XGate(), [q[qubit]]) initialize_circuit.append(HGate(), [q[qubit]]) elif param == 'r': # |+i> initialize_circuit.append(HGate(), [q[qubit]]) initialize_circuit.append(SGate(), [q[qubit]]) elif param == 'l': # |-i> initialize_circuit.append(HGate(), [q[qubit]]) initialize_circuit.append(SdgGate(), [q[qubit]]) return initialize_circuit
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_substituting_node_preserves_args_condition(self, inplace): """Verify 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(CXGate(), [qr[1], qr[0]], condition=(cr, 1)) 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, 'cz') 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)
def test_instructionset_c_if_calls_custom_requester(self): """Test that :meth:`.InstructionSet.c_if` calls a custom requester, and uses its output.""" # This isn't expected to be useful to end users, it's more about the principle that you can # control the resolution paths, so future blocking constructs can forbid the method from # accessing certain resources. sentinel_bit = Clbit() sentinel_register = ClassicalRegister(2) def dummy_requester(specifier): """A dummy requester that returns sentinel values.""" if not isinstance(specifier, (int, Clbit, ClassicalRegister)): raise CircuitError return sentinel_bit if isinstance(specifier, (int, Clbit)) else sentinel_register dummy_requester = unittest.mock.MagicMock(wraps=dummy_requester) with self.subTest("calls requester with bit"): dummy_requester.reset_mock() instruction = HGate() instructions = InstructionSet(resource_requester=dummy_requester) instructions.add(instruction, [Qubit()], []) bit = Clbit() instructions.c_if(bit, 0) dummy_requester.assert_called_once_with(bit) self.assertIs(instruction.condition[0], sentinel_bit) with self.subTest("calls requester with index"): dummy_requester.reset_mock() instruction = HGate() instructions = InstructionSet(resource_requester=dummy_requester) instructions.add(instruction, [Qubit()], []) index = 0 instructions.c_if(index, 0) dummy_requester.assert_called_once_with(index) self.assertIs(instruction.condition[0], sentinel_bit) with self.subTest("calls requester with register"): dummy_requester.reset_mock() instruction = HGate() instructions = InstructionSet(resource_requester=dummy_requester) instructions.add(instruction, [Qubit()], []) register = ClassicalRegister(2) instructions.c_if(register, 0) dummy_requester.assert_called_once_with(register) self.assertIs(instruction.condition[0], sentinel_register) with self.subTest("calls requester only once when broadcast"): dummy_requester.reset_mock() instruction_list = [HGate(), HGate(), HGate()] instructions = InstructionSet(resource_requester=dummy_requester) for instruction in instruction_list: instructions.add(instruction, [Qubit()], []) register = ClassicalRegister(2) instructions.c_if(register, 0) dummy_requester.assert_called_once_with(register) for instruction in instruction_list: self.assertIs(instruction.condition[0], sentinel_register)
def test_instructionset_c_if_with_no_requester(self): """Test that using a raw :obj:`.InstructionSet` with no classical-resource resoluer accepts arbitrary :obj:`.Clbit` and `:obj:`.ClassicalRegister` instances, but rejects integers.""" with self.subTest("accepts arbitrary register"): instruction = HGate() instructions = InstructionSet() instructions.add(instruction, [Qubit()], []) register = ClassicalRegister(2) instructions.c_if(register, 0) self.assertIs(instruction.condition[0], register) with self.subTest("accepts arbitrary bit"): instruction = HGate() instructions = InstructionSet() instructions.add(instruction, [Qubit()], []) bit = Clbit() instructions.c_if(bit, 0) self.assertIs(instruction.condition[0], bit) with self.subTest("rejects index"): instruction = HGate() instructions = InstructionSet() instructions.add(instruction, [Qubit()], []) with self.assertRaisesRegex(CircuitError, r"Cannot pass an index as a condition .*"): instructions.c_if(0, 0)
def test_label_type_enforcement(self): """Test instruction label type enforcement.""" with self.subTest("accepts string labels"): instruction = Instruction("h", 1, 0, [], label="label") self.assertEqual(instruction.label, "label") with self.subTest( "raises when a non-string label is provided to constructor"): with self.assertRaisesRegex(TypeError, r"label expects a string or None"): Instruction("h", 1, 0, [], label=0) with self.subTest( "raises when a non-string label is provided to setter"): with self.assertRaisesRegex(TypeError, r"label expects a string or None"): instruction = HGate() instruction.label = 0
def test_dag_nodes_on_wire(self): """Test that listing the gates on a qubit/classical bit gets the correct gates""" self.dag.apply_operation_back(CXGate(), [self.qubit0, self.qubit1], []) self.dag.apply_operation_back(HGate(), [self.qubit0], []) qbit = self.dag.qubits[0] self.assertEqual([0, 10, 11, 1], [i._node_id for i in self.dag.nodes_on_wire(qbit)]) self.assertEqual([10, 11], [i._node_id for i in self.dag.nodes_on_wire(qbit, only_ops=True)]) cbit = self.dag.clbits[0] self.assertEqual([6, 7], [i._node_id for i in self.dag.nodes_on_wire(cbit)]) self.assertEqual([], [i._node_id for i in self.dag.nodes_on_wire(cbit, only_ops=True)]) with self.assertRaises(DAGCircuitError): next(self.dag.nodes_on_wire((qbit.register, 7)))
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.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(CXGate(), [self.qubit0, self.qubit1], []) self.dag.apply_operation_back(XGate(), [self.qubit1], [])
def test_dag_nodes_on_wire_multiple_successors(self): """ Test that if a DAGNode has multiple successors in the DAG along one wire, they are all retrieved in order. This could be the case for a circuit such as q0_0: |0>──■─────────■── ┌─┴─┐┌───┐┌─┴─┐ q0_1: |0>┤ X ├┤ H ├┤ X ├ └───┘└───┘└───┘ Both the 2nd CX gate and the H gate follow the first CX gate in the DAG, so they both must be returned but in the correct order. """ self.dag.apply_operation_back(CXGate(), [self.qubit0, self.qubit1], []) self.dag.apply_operation_back(HGate(), [self.qubit1], []) self.dag.apply_operation_back(CXGate(), [self.qubit0, self.qubit1], []) nodes = self.dag.nodes_on_wire(self.dag.qubits[1], only_ops=True) node_names = [nd.name for nd in nodes] self.assertEqual(node_names, ['cx', 'h', 'cx'])
def test_reverse_opaque(self): """test opaque gates reverse to themselves""" opaque_gate = Gate(name='crz_2', num_qubits=2, params=[0.5]) self.assertEqual(opaque_gate.reverse_ops(), opaque_gate) hgate = HGate() self.assertEqual(hgate.reverse_ops(), hgate)
def test_mirror_opaque(self): """test opaque gates mirror to themselves""" opaque_gate = Gate(name='crz_2', num_qubits=2, params=[0.5]) self.assertEqual(opaque_gate.mirror(), opaque_gate) hgate = HGate() self.assertEqual(hgate.mirror(), hgate)