def test_to_circuit(self, num_qubits): """Test to_circuit method""" samples = 10 num_gates = 10 seed = 700 gates = 'all' for i in range(samples): circ = random_clifford_circuit(num_qubits, num_gates, gates=gates, seed=seed + i) target = Clifford(circ) decomp = target.to_circuit() self.assertIsInstance(decomp, QuantumCircuit) self.assertEqual(decomp.num_qubits, circ.num_qubits) # Convert back to clifford and check it is the same self.assertEqual(Clifford(decomp), target)
def create_cliff1(self): """Creates a simple Clifford.""" qc = QuantumCircuit(3) qc.h(0) qc.cx(0, 1) qc.cx(1, 2) qc.s(2) return Clifford(qc)
def test_reset_single_qubit(self): """Test reset method of a single qubit""" empty_qc = QuantumCircuit(1) for _ in range(self.samples): cliff = Clifford(XGate()) stab = StabilizerState(cliff) value = stab.reset([0]) target = StabilizerState(empty_qc) self.assertEqual(value, target) cliff = Clifford(HGate()) stab = StabilizerState(cliff) value = stab.reset([0]) target = StabilizerState(empty_qc) self.assertEqual(value, target)
def test_is_unitary(self, num_qubits): """Test is_unitary method""" samples = 10 num_gates = 10 seed = 700 gates = 'all' for i in range(samples): circ = random_clifford_circuit(num_qubits, num_gates, gates=gates, seed=seed + i) value = Clifford(circ).is_unitary() self.assertTrue(value) # tests a false clifford cliff = Clifford([[0, 0], [0, 1]], validate=False) value = cliff.is_unitary() self.assertFalse(value)
def test_measure_single_qubit(self): """Test a measurement of a single qubit""" for _ in range(self.samples): cliff = Clifford(XGate()) stab = StabilizerState(cliff) value = stab.measure()[0] self.assertEqual(value, "1") cliff = Clifford(IGate()) stab = StabilizerState(cliff) value = stab.measure()[0] self.assertEqual(value, "0") cliff = Clifford(HGate()) stab = StabilizerState(cliff) value = stab.measure()[0] self.assertIn(value, ["0", "1"])
def test_evolve_clifford2(self, gate, label): """Test evolve method for 2-qubit Clifford gates.""" cliff = Clifford(gate) op = Operator(gate) pauli = Pauli(label) value = Operator(pauli.evolve(cliff)) target = op.adjoint().dot(pauli).dot(op) self.assertEqual(value, target)
def test_append_2_qubit_gate(self, gate_name, qubits): """Tests for append of 2-qubit gate {gate_name} {qubits}.""" targets_cliffords = { "cx [0, 1]": Clifford([[True, True, False, False], [False, True, False, False], [False, False, True, False], [False, False, True, True]]), "cx [1, 0]": Clifford([[True, False, False, False], [True, True, False, False], [False, False, True, True], [False, False, False, True]]), "cz [0, 1]": Clifford([[True, False, False, True], [False, True, True, False], [False, False, True, False], [False, False, False, True]]), "cz [1, 0]": Clifford([[True, False, False, True], [False, True, True, False], [False, False, True, False], [False, False, False, True]]), "swap [0, 1]": Clifford([[False, True, False, False], [True, False, False, False], [False, False, False, True], [False, False, True, False]]), "swap [1, 0]": Clifford([[False, True, False, False], [True, False, False, False], [False, False, False, True], [False, False, True, False]]) } gate_qubits = gate_name + " " + str(qubits) cliff = _append_circuit(Clifford(np.eye(4)), gate_name, qubits) target = targets_cliffords[gate_qubits] self.assertEqual(target, cliff)
def test_2_qubit_identity_relations(self): """Tests identity relations for 2-qubit gates""" for gate_name in ("cx", "cz", "swap"): for qubits in ([0, 1], [1, 0]): with self.subTest(msg=f"append gate {gate_name} {qubits}"): cliff = Clifford(np.eye(4)) cliff1 = cliff.copy() cliff = _append_circuit(cliff, gate_name, qubits) cliff = _append_circuit(cliff, gate_name, qubits) self.assertEqual(cliff, cliff1)
def test_dot_method(self, num_qubits): """Test dot method""" samples = 10 num_gates = 10 seed = 600 gates = 'all' for i in range(samples): circ1 = random_clifford_circuit(num_qubits, num_gates, gates=gates, seed=seed + i) circ2 = random_clifford_circuit(num_qubits, num_gates, gates=gates, seed=seed + samples + i) cliff1 = Clifford(circ1) cliff2 = Clifford(circ2) value = cliff1.dot(cliff2) target = Clifford(circ2.extend(circ1)) self.assertEqual(target, value)
def test_compose_method(self, num_qubits): """Test compose method""" samples = 10 num_gates = 10 seed = 600 gates = "all" for i in range(samples): circ1 = random_clifford_circuit(num_qubits, num_gates, gates=gates, seed=seed + i) circ2 = random_clifford_circuit(num_qubits, num_gates, gates=gates, seed=seed + samples + i) cliff1 = Clifford(circ1) cliff2 = Clifford(circ2) value = cliff1.compose(cliff2) target = Clifford(circ1.compose(circ2)) self.assertEqual(target, value)
def test_compose_subsystem(self, num_qubits_1, num_qubits_2): """Test compose method of subsystems""" samples = 10 num_gates = 10 seed = 600 gates = 'all' for i in range(samples): circ1 = random_clifford_circuit(num_qubits_1, num_gates, gates=gates, seed=seed + i) circ2 = random_clifford_circuit(num_qubits_2, num_gates, gates=gates, seed=seed + samples + i) qargs = sorted(np.random.choice(range(num_qubits_1), num_qubits_2, replace=False)) circ = circ1.copy() circ.append(circ2.to_instruction(), qargs) value = Clifford(circ1).compose(Clifford(circ2), qargs) target = Clifford(circ) self.assertEqual(target, value)
def test_dict_round_trip(self, num_qubits): """Test round trip conversion to and from dict""" num_gates = 10 seed = 655 gates = 'all' circ = random_clifford_circuit(num_qubits, num_gates, gates=gates, seed=seed + num_qubits) target = Clifford(circ) value = Clifford.from_dict(target.to_dict()) self.assertEqual(value, target)
def test_1_qubit_identity_relations(self): """Tests identity relations for 1-qubit gates""" for gate_name in ("x", "y", "z", "h"): with self.subTest(msg='identity for gate %s' % gate_name): cliff = Clifford([[1, 0], [0, 1]]) cliff1 = cliff.copy() cliff = _append_circuit(cliff, gate_name, [0]) cliff = _append_circuit(cliff, gate_name, [0]) self.assertEqual(cliff, cliff1) gates = ['s', 's', 'v'] inv_gates = ['sdg', 'sinv', 'w'] for gate_name, inv_gate in zip(gates, inv_gates): with self.subTest(msg='identity for gate %s' % gate_name): cliff = Clifford([[1, 0], [0, 1]]) cliff1 = cliff.copy() cliff = _append_circuit(cliff, gate_name, [0]) cliff = _append_circuit(cliff, inv_gate, [0]) self.assertEqual(cliff, cliff1)
def test_to_operator_nqubit_gates(self, gates, num_qubits): """Test {num_qubits}-qubit circuit with gates {gates}""" samples = 10 num_gates = 20 seed = 300 for i in range(samples): circ = random_clifford_circuit(num_qubits, num_gates, gates=gates, seed=seed + i) value = Clifford(circ).to_operator() target = Operator(circ) self.assertTrue(target.equiv(value))
def test_clifford_as_operation(self): """Test that we can instantiate an object of class :class:`~qiskit.quantum_info.operators.Clifford` and that it has the expected name, num_qubits and num_clbits. """ num_qubits = 4 qc = QuantumCircuit(4, 0) qc.h(2) qc.cx(0, 1) op = Clifford(qc) self.assertTrue(op.name == "clifford") self.assertTrue(op.num_qubits == num_qubits) self.assertTrue(op.num_clbits == 0)
def test_circuit_to_dag_conversion_and_back(self): """Test that converting a circuit containing Clifford to a DAG and back preserves the Clifford. """ # Create a Clifford cliff_circ = QuantumCircuit(3) cliff_circ.cx(0, 1) cliff_circ.h(0) cliff_circ.s(1) cliff_circ.swap(1, 2) cliff = Clifford(cliff_circ) # Add this Clifford to a Quantum Circuit, and check that it remains a Clifford circ0 = QuantumCircuit(4) circ0.append(cliff, [0, 1, 2]) circ0_cliffords = [ inst for inst, _, _ in circ0.data if isinstance(inst, Clifford) ] circ0_gates = [ inst for inst, _, _ in circ0.data if isinstance(inst, Gate) ] self.assertEqual(len(circ0_cliffords), 1) self.assertEqual(len(circ0_gates), 0) # Check that converting circuit to DAG preserves Clifford. dag0 = circuit_to_dag(circ0) dag0_cliffords = [ node for node in dag0.topological_nodes() if isinstance(node, DAGOpNode) and isinstance(node.op, Clifford) ] self.assertEqual(len(dag0_cliffords), 1) # Check that converted DAG to a circuit also preserves Clifford. circ1 = dag_to_circuit(dag0) circ1_cliffords = [ inst for inst, _, _ in circ1.data if isinstance(inst, Clifford) ] circ1_gates = [ inst for inst, _, _ in circ1.data if isinstance(inst, Gate) ] self.assertEqual(len(circ1_cliffords), 1) self.assertEqual(len(circ1_gates), 0) # However, test that running an unrolling pass on the DAG replaces Clifford # by gates. dag1 = HighLevelSynthesis().run(dag0) dag1_cliffords = [ node for node in dag1.topological_nodes() if isinstance(node, DAGOpNode) and isinstance(node.op, Clifford) ] self.assertEqual(len(dag1_cliffords), 0)
def create_cliff3(self): """Creates a third Clifford which is the composition of the previous two.""" qc = QuantumCircuit(3) qc.h(0) qc.cx(0, 1) qc.cx(1, 2) qc.s(2) qc.cx(0, 1) qc.h(0) qc.h(1) qc.h(2) qc.cx(1, 2) qc.s(2) return Clifford(qc)
def test_transpose(self, num_qubits): """Test transpose method""" samples = 10 num_gates = 1 seed = 500 gates = 'all' for i in range(samples): circ = random_clifford_circuit(num_qubits, num_gates, gates=gates, seed=seed + i) value = Clifford(circ).transpose().to_operator() target = Operator(circ).transpose() self.assertTrue(target.equiv(value))
def test_conjugate(self, num_qubits): """Test conjugate method""" samples = 10 num_gates = 10 seed = 400 gates = "all" for i in range(samples): circ = random_clifford_circuit(num_qubits, num_gates, gates=gates, seed=seed + i) value = Clifford(circ).conjugate().to_operator() target = Operator(circ).conjugate() self.assertTrue(target.equiv(value))
def test_to_dict(self): """Test to_dict method""" with self.subTest(msg="Identity"): cliff = Clifford(np.eye(8)) value = cliff.to_dict() keys_value = set(value.keys()) keys_target = {'destabilizer', 'stabilizer'} self.assertEqual(keys_value, keys_target) stabilizer_value = set(value['stabilizer']) stabilizer_target = {'+IIIZ', '+IIZI', '+IZII', '+ZIII'} self.assertEqual(stabilizer_value, stabilizer_target) destabilizer_value = set(value['destabilizer']) destabilizer_target = {'+IIIX', '+IIXI', '+IXII', '+XIII'} self.assertEqual(destabilizer_value, destabilizer_target) with self.subTest(msg="bell"): qc = QuantumCircuit(2) qc.h(0) qc.cx(0, 1) cliff = Clifford(qc) value = cliff.to_dict() keys_value = set(value.keys()) keys_target = {'destabilizer', 'stabilizer'} self.assertEqual(keys_value, keys_target) stabilizer_value = set(value['stabilizer']) stabilizer_target = {'+XX', '+ZZ'} self.assertEqual(stabilizer_value, stabilizer_target) destabilizer_value = set(value['destabilizer']) destabilizer_target = {'+IZ', '+XI'} self.assertEqual(destabilizer_value, destabilizer_target)
def test_to_dict(self): """Test to_dict method""" with self.subTest(msg="Identity"): cliff = Clifford(np.eye(8)) value = cliff.to_dict() keys_value = set(value.keys()) keys_target = {"destabilizer", "stabilizer"} self.assertEqual(keys_value, keys_target) stabilizer_value = set(value["stabilizer"]) stabilizer_target = {"+IIIZ", "+IIZI", "+IZII", "+ZIII"} self.assertEqual(stabilizer_value, stabilizer_target) destabilizer_value = set(value["destabilizer"]) destabilizer_target = {"+IIIX", "+IIXI", "+IXII", "+XIII"} self.assertEqual(destabilizer_value, destabilizer_target) with self.subTest(msg="bell"): qc = QuantumCircuit(2) qc.h(0) qc.cx(0, 1) cliff = Clifford(qc) value = cliff.to_dict() keys_value = set(value.keys()) keys_target = {"destabilizer", "stabilizer"} self.assertEqual(keys_value, keys_target) stabilizer_value = set(value["stabilizer"]) stabilizer_target = {"+XX", "+ZZ"} self.assertEqual(stabilizer_value, stabilizer_target) destabilizer_value = set(value["destabilizer"]) destabilizer_target = {"+IZ", "+XI"} self.assertEqual(destabilizer_value, destabilizer_target)
def test_expand_method(self, num_qubits_1, num_qubits_2): """Test expand method""" samples = 5 num_gates = 10 seed = 800 gates = 'all' for i in range(samples): circ1 = random_clifford_circuit(num_qubits_1, num_gates, gates=gates, seed=seed + i) circ2 = random_clifford_circuit(num_qubits_2, num_gates, gates=gates, seed=seed + samples + i) cliff1 = Clifford(circ1) cliff2 = Clifford(circ2) value = cliff1.expand(cliff2) circ = QuantumCircuit(num_qubits_1 + num_qubits_2) circ.append(circ1, range(num_qubits_1)) circ.append(circ2, range(num_qubits_1, num_qubits_1 + num_qubits_2)) target = Clifford(circ) self.assertEqual(target, value)
def test_from_label(self): """Test from_label method""" label = 'IXYZHS' CI = Clifford(IGate()) CX = Clifford(XGate()) CY = Clifford(YGate()) CZ = Clifford(ZGate()) CH = Clifford(HGate()) CS = Clifford(SGate()) target = CI.tensor(CX).tensor(CY).tensor(CZ).tensor(CH).tensor(CS) self.assertEqual(Clifford.from_label(label), target)
def test_to_instruction(self, num_qubits): """Test to_instruction method""" samples = 10 num_gates = 10 seed = 800 gates = 'all' for i in range(samples): circ = random_clifford_circuit(num_qubits, num_gates, gates=gates, seed=seed + i) decomp = Clifford(circ).to_instruction() self.assertIsInstance(decomp, Gate) self.assertEqual(decomp.num_qubits, circ.num_qubits) value = Operator(decomp) target = Operator(circ) self.assertTrue(value.equiv(target))
def test_to_matrix(self, num_qubits): """Test to_matrix method""" samples = 10 num_gates = 10 seed = 333 gates = 'all' for i in range(samples): circ = random_clifford_circuit(num_qubits, num_gates, gates=gates, seed=seed + i) mat = Clifford(circ).to_matrix() self.assertIsInstance(mat, np.ndarray) self.assertEqual(mat.shape, 2 * (2**num_qubits, )) value = Operator(mat) target = Operator(circ) self.assertTrue(value.equiv(target))
def test_1_qubit_mult_relations(self): """Tests multiplicity relations for 1-qubit gates""" rels = [ 'x * y = z', 'x * z = y', 'y * z = x', 's * s = z', 'sdg * sdg = z', 'sinv * sinv = z', 'sdg * h = v', 'h * s = w' ] for rel in rels: with self.subTest(msg='relation %s' % rel): split_rel = rel.split() cliff = Clifford([[1, 0], [0, 1]]) cliff1 = cliff.copy() cliff = _append_circuit(cliff, split_rel[0], [0]) cliff = _append_circuit(cliff, split_rel[2], [0]) cliff1 = _append_circuit(cliff1, split_rel[4], [0]) self.assertEqual(cliff, cliff1)
def test_1_qubit_conj_relations(self): """Tests conjugation relations for 1-qubit gates""" rels = [ 'h * x * h = z', 'h * y * h = y', 's * x * sdg = y', 'w * x * v = y', 'w * y * v = z', 'w * z * v = x' ] for rel in rels: with self.subTest(msg='relation %s' % rel): split_rel = rel.split() cliff = Clifford([[1, 0], [0, 1]]) cliff1 = cliff.copy() cliff = _append_circuit(cliff, split_rel[0], [0]) cliff = _append_circuit(cliff, split_rel[2], [0]) cliff = _append_circuit(cliff, split_rel[4], [0]) cliff1 = _append_circuit(cliff1, split_rel[6], [0]) self.assertEqual(cliff, cliff1)
def test_1_qubit_mult_relations(self): """Tests multiplicity relations for 1-qubit gates""" rels = [ "x * y = z", "x * z = y", "y * z = x", "s * s = z", "sdg * sdg = z", "sinv * sinv = z", "sdg * h = v", "h * s = w", ] for rel in rels: with self.subTest(msg="relation %s" % rel): split_rel = rel.split() cliff = Clifford([[1, 0], [0, 1]]) cliff1 = cliff.copy() cliff = _append_circuit(cliff, split_rel[0], [0]) cliff = _append_circuit(cliff, split_rel[2], [0]) cliff1 = _append_circuit(cliff1, split_rel[4], [0]) self.assertEqual(cliff, cliff1)
def test_append_1_qubit_gate(self): """Tests for append of 1-qubit gates""" target_table = { "i": np.array([[[True, False], [False, True]]], dtype=bool), "id": np.array([[[True, False], [False, True]]], dtype=bool), "iden": np.array([[[True, False], [False, True]]], dtype=bool), "x": np.array([[[True, False], [False, True]]], dtype=bool), "y": np.array([[[True, False], [False, True]]], dtype=bool), "z": np.array([[[True, False], [False, True]]], dtype=bool), "h": np.array([[[False, True], [True, False]]], dtype=bool), "s": np.array([[[True, True], [False, True]]], dtype=bool), "sdg": np.array([[[True, True], [False, True]]], dtype=bool), "sinv": np.array([[[True, True], [False, True]]], dtype=bool), "v": np.array([[[True, True], [True, False]]], dtype=bool), "w": np.array([[[False, True], [True, True]]], dtype=bool), } target_phase = { "i": np.array([[False, False]], dtype=bool), "id": np.array([[False, False]], dtype=bool), "iden": np.array([[False, False]], dtype=bool), "x": np.array([[False, True]], dtype=bool), "y": np.array([[True, True]], dtype=bool), "z": np.array([[True, False]], dtype=bool), "h": np.array([[False, False]], dtype=bool), "s": np.array([[False, False]], dtype=bool), "sdg": np.array([[True, False]], dtype=bool), "sinv": np.array([[True, False]], dtype=bool), "v": np.array([[False, False]], dtype=bool), "w": np.array([[False, False]], dtype=bool) } target_stabilizer = { "i": "+Z", "id": "+Z", "iden": "+Z", "x": "-Z", "y": "-Z", "z": "+Z", "h": "+X", "s": "+Z", "sdg": "+Z", "sinv": "+Z", "v": "+X", "w": "+Y", } target_destabilizer = { "i": "+X", "id": "+X", "iden": "+X", "x": "+X", "y": "-X", "z": "-X", "h": "+Z", "s": "+Y", "sdg": "-Y", "sinv": "-Y", "v": "+Y", "w": "+Z", } for gate_name in ("i", "id", "iden", "x", "y", "z", "h", "s", "sdg", "v", "w"): with self.subTest(msg='append gate %s' % gate_name): cliff = Clifford([[1, 0], [0, 1]]) cliff = _append_circuit(cliff, gate_name, [0]) value_table = cliff.table._array value_phase = cliff.table._phase value_stabilizer = cliff.stabilizer.to_labels() value_destabilizer = cliff.destabilizer.to_labels() self.assertTrue( np.all(np.array(value_table == target_table[gate_name]))) self.assertTrue( np.all(np.array(value_phase == target_phase[gate_name]))) self.assertTrue( np.all( np.array(value_stabilizer == [target_stabilizer[gate_name]]))) self.assertTrue( np.all( np.array(value_destabilizer == [target_destabilizer[gate_name]])))