def test_random_decompose(self): """ Test that random elements are CNOTDihedral and to_circuit, to_instruction, _from_circuit, _is_valid methods """ rng = np.random.default_rng(1234) samples = 10 for num_qubits in range(1, 9): for _ in range(samples): # Test of random_cnotdihedral method elem = random_cnotdihedral(num_qubits, seed=rng) self.assertIsInstance( elem, CNOTDihedral, "Error: random element is not CNOTDihedral") self.assertTrue(elem._is_valid(), "Error: random element is not CNOTDihedral") # Test of to_circuit and _from_circuit methods test_circ = elem.to_circuit() self.assertTrue( test_circ, "Error: cannot decompose a random " "CNOTDihedral element to a circuit", ) test_elem = CNOTDihedral(test_circ) self.assertEqual( elem, test_elem, "Error: decomposed circuit is not equal " "to the original circuit", ) # Test that _is_valid fails if linear part is wrong test_elem.linear = np.zeros((num_qubits, num_qubits)) value = test_elem._is_valid() self.assertFalse( value, "Error: CNOTDihedral _is_valid is not correct.") # Test of to_instruction and _from_circuit methods test_gates = elem.to_instruction() self.assertIsInstance( test_gates, Gate, "Error: cannot decompose a random " "CNOTDihedral element to a Gate", ) self.assertEqual( test_gates.num_qubits, test_circ.num_qubits, "Error: wrong num_qubits in decomposed gates", ) test_elem1 = CNOTDihedral(test_gates) self.assertEqual( elem, test_elem1, "Error: decomposed gates are not equal " "to the original gates", )
def test_conjugate(self): """Test transpose method""" samples = 10 rng = np.random.default_rng(777) for num_qubits in range(1, 5): for _ in range(samples): circ = random_cnotdihedral_circuit(num_qubits, 5 * num_qubits, seed=rng) elem = CNOTDihedral(circ) value = elem.conjugate().to_operator() target = Operator(circ).conjugate() self.assertTrue(target.equiv(value), "Error: conjugate circuit is not the same")
def test_dot_method(self): """Test dot method""" samples = 10 rng = np.random.default_rng(222) for num_qubits in range(1, 6): for _ in range(samples): circ1 = random_cnotdihedral_circuit(num_qubits, 5 * num_qubits, seed=rng) circ2 = random_cnotdihedral_circuit(num_qubits, 5 * num_qubits, seed=rng) elem1 = CNOTDihedral(circ1) elem2 = CNOTDihedral(circ2) value = elem1.dot(elem2) target = CNOTDihedral(circ2.compose(circ1)) self.assertEqual(target, value, "Error: composed circuit is not the same")
def test_init_circuit_decompose(self): """ Test initialization from circuit and to_circuit, to_instruction methods """ rng = np.random.default_rng(1234) samples = 10 for num_qubits in range(1, 9): for _ in range(samples): # Test of to_circuit and _from_circuit methods circ = random_cnotdihedral_circuit(num_qubits, 5 * num_qubits, seed=rng) elem = CNOTDihedral(circ) test_circ = elem.to_circuit() test_elem = CNOTDihedral(test_circ) self.assertEqual( elem, test_elem, "Error: decomposed gates are not equal to the original gates", ) # Test of to_instruction and _from_circuit methods circ = random_cnotdihedral_circuit(num_qubits, 5 * num_qubits, seed=rng) elem = CNOTDihedral(circ) test_circ = elem.to_instruction() test_elem = CNOTDihedral(test_circ) self.assertEqual( elem, test_elem, "Error: decomposed gates are not equal to the original gates", )
def test_barrier_delay_sim(self): """Test barrier and delay instructions can be simulated""" target_circ = QuantumCircuit(2) target_circ.x(0) target_circ.cx(0, 1) target = CNOTDihedral(target_circ) circ = QuantumCircuit(2) circ.x(0) circ.delay(100, 0) circ.barrier([0, 1]) circ.cx(0, 1) value = CNOTDihedral(circ) self.assertEqual(value, target)
def test_to_matrix(self): """Test to_matrix method""" samples = 10 rng = np.random.default_rng(888) for num_qubits in range(1, 5): for _ in range(samples): circ = random_cnotdihedral_circuit(num_qubits, 5 * num_qubits, seed=rng) elem = CNOTDihedral(circ) mat = elem.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), "Error: matrix of the circuit is not the same")
def test_expand_method(self): """Test expand method""" samples = 10 rng = np.random.default_rng(333) for num_qubits_1 in range(1, 5): for num_qubits_2 in range(1, 5): for _ in range(samples): elem1 = random_cnotdihedral(num_qubits_1, seed=rng) elem2 = random_cnotdihedral(num_qubits_2, seed=rng) circ1 = elem1.to_instruction() circ2 = elem2.to_instruction() value = elem2.expand(elem1) circ = QuantumCircuit(num_qubits_1 + num_qubits_2) qargs = list(range(num_qubits_1)) for instr, qregs, _ in circ1.definition: new_qubits = [ qargs[circ1.definition.qubits.index(tup)] for tup in qregs ] circ.append(instr, new_qubits) qargs = list( range(num_qubits_1, num_qubits_1 + num_qubits_2)) for instr, qregs, _ in circ2.definition: new_qubits = [ qargs[circ2.definition.qubits.index(tup)] for tup in qregs ] circ.append(instr, new_qubits) target = CNOTDihedral(circ) self.assertEqual(target, value, "Error: expand circuit is not the same")
def test_init_from_pauli(self): """Test initialization from Pauli""" samples = 10 rng = np.random.default_rng(999) for num_qubits in range(1, 5): for _ in range(samples): pauli = random.random_pauli(num_qubits, seed=rng) elem = CNOTDihedral(pauli) value = Operator(pauli) target = Operator(elem) self.assertTrue(value.equiv(target), "Error: Pauli operator is not the same.")
def test_1_qubit_identities(self): """Tests identities for 1-qubit gates""" # T*X*T = X circ1 = QuantumCircuit(1) circ1.t(0) circ1.x(0) circ1.t(0) elem1 = CNOTDihedral(circ1) elem = CNOTDihedral(XGate()) self.assertEqual(elem1, elem, "Error: 1-qubit identity does not hold") # X*T*X = Tdg circ1 = QuantumCircuit(1) circ1.x(0) circ1.t(0) circ1.x(0) elem1 = CNOTDihedral(circ1) elem = CNOTDihedral(TdgGate()) self.assertEqual(elem1, elem, "Error: 1-qubit identity does not hold") # X*Tdg*X = T circ1 = QuantumCircuit(1) circ1.x(0) circ1.tdg(0) circ1.x(0) elem1 = CNOTDihedral(circ1) elem = CNOTDihedral(TGate()) self.assertEqual(elem1, elem, "Error: 1-qubit identity does not hold") # X*S*X = Sdg circ1 = QuantumCircuit(1) circ1.x(0) circ1.s(0) circ1.x(0) elem1 = CNOTDihedral(circ1) elem = CNOTDihedral(SdgGate()) self.assertEqual(elem1, elem, "Error: 1-qubit identity does not hold") # X*Sdg*X = S circ1 = QuantumCircuit(1) circ1.x(0) circ1.sdg(0) circ1.x(0) elem1 = CNOTDihedral(circ1) elem = CNOTDihedral(SGate()) self.assertEqual(elem1, elem, "Error: 1-qubit identity does not hold") # T*X*Tdg = S*X circ1 = QuantumCircuit(1) circ1.t(0) circ1.x(0) circ1.tdg(0) circ2 = QuantumCircuit(1) circ2.s(0) circ2.x(0) elem1 = CNOTDihedral(circ1) elem2 = CNOTDihedral(circ2) self.assertEqual(elem1, elem2, "Error: 1-qubit identity does not hold")
def test_2_qubit_identities(self): """Tests identities for 2-qubit gates""" # SI * CX * SdgI = CX elem = CNOTDihedral(CXGate()) circ1 = QuantumCircuit(2) circ1.s(0) circ1.cx(0, 1) circ1.sdg(0) elem1 = CNOTDihedral(circ1) self.assertEqual(elem, elem1, "Error: 2-qubit CX identity does not hold") # SI * CZ * SdgI = CZ elem = CNOTDihedral(CZGate()) circ1 = QuantumCircuit(2) circ1.s(0) circ1.cz(1, 0) circ1.sdg(0) elem1 = CNOTDihedral(circ1) self.assertEqual(elem, elem1, "Error: 2-qubit CZ identity does not hold") # SWAP = CX01 * CX10 * CX01 = CX10 * CX01 * CX10 elem = CNOTDihedral(SwapGate()) circ1 = QuantumCircuit(2) circ1.cx(0, 1) circ1.cx(1, 0) circ1.cx(0, 1) circ2 = QuantumCircuit(2) circ2.cx(1, 0) circ2.cx(0, 1) circ2.cx(1, 0) elem1 = CNOTDihedral(circ1) elem2 = CNOTDihedral(circ2) self.assertEqual(elem, elem1, "Error: 2-qubit SWAP identity does not hold") self.assertEqual(elem1, elem2, "Error: 2-qubit SWAP identity does not hold") # CS01 = CS10 (symmetric) # # ┌───┐ # q_0: ┤ T ├──■───────────■── # ├───┤┌─┴─┐┌─────┐┌─┴─┐ # q_1: ┤ T ├┤ X ├┤ Tdg ├┤ X ├ # └───┘└───┘└─────┘└───┘ circ1 = QuantumCircuit(2) circ1.t(0) circ1.t(1) circ1.cx(0, 1) circ1.tdg(1) circ1.cx(0, 1) # ┌───┐┌───┐┌─────┐┌───┐ # q_0: ┤ T ├┤ X ├┤ Tdg ├┤ X ├ # ├───┤└─┬─┘└─────┘└─┬─┘ # q_1: ┤ T ├──■───────────■── # └───┘ circ2 = QuantumCircuit(2) circ2.t(1) circ2.t(0) circ2.cx(1, 0) circ2.tdg(0) circ2.cx(1, 0) elem1 = CNOTDihedral(circ1) elem2 = CNOTDihedral(circ2) self.assertEqual(elem1, elem2, "Error: 2-qubit CS identity does not hold") # TI*CS*TdgI = CS # # ┌───┐┌───┐ ┌─────┐ # q_0: ┤ T ├┤ T ├──■───────────■──┤ Tdg ├ # ├───┤└───┘┌─┴─┐┌─────┐┌─┴─┐└─────┘ # q_1: ┤ T ├─────┤ X ├┤ Tdg ├┤ X ├─────── # └───┘ └───┘└─────┘└───┘ circ3 = QuantumCircuit(2) circ3.t(0) circ3.t(0) circ3.t(1) circ3.cx(0, 1) circ3.tdg(1) circ3.cx(0, 1) circ3.tdg(0) elem3 = CNOTDihedral(circ3) self.assertEqual(elem1, elem3, "Error: 2-qubit CS identity does not hold") # IT*CS*ITdg = CS # # ┌───┐ # q_0: ┤ T ├───────■───────────■───────── # ├───┤┌───┐┌─┴─┐┌─────┐┌─┴─┐┌─────┐ # q_1: ┤ T ├┤ T ├┤ X ├┤ Tdg ├┤ X ├┤ Tdg ├ # └───┘└───┘└───┘└─────┘└───┘└─────┘ circ4 = QuantumCircuit(2) circ4.t(1) circ4.t(0) circ4.t(1) circ4.cx(0, 1) circ4.tdg(1) circ4.cx(0, 1) circ4.tdg(1) elem4 = CNOTDihedral(circ4) self.assertEqual(elem1, elem4, "Error: 2-qubit CS identity does not hold") # XX*CS*XX*SS = CS # # ┌───┐┌───┐ ┌───┐┌───┐ # q_0: ┤ X ├┤ T ├──■───────────■──┤ X ├┤ S ├ # ├───┤├───┤┌─┴─┐┌─────┐┌─┴─┐├───┤├───┤ # q_1: ┤ X ├┤ T ├┤ X ├┤ Tdg ├┤ X ├┤ X ├┤ S ├ # └───┘└───┘└───┘└─────┘└───┘└───┘└───┘ circ5 = QuantumCircuit(2) circ5.x(0) circ5.x(1) circ5.t(0) circ5.t(1) circ5.cx(0, 1) circ5.tdg(1) circ5.cx(0, 1) circ5.x(0) circ5.x(1) circ5.s(0) circ5.s(1) elem5 = CNOTDihedral(circ5) self.assertEqual(elem1, elem5, "Error: 2-qubit CS identity does not hold") # CSdg01 = CSdg10 (symmetric) # # ┌─────┐ # q_0: ┤ Tdg ├──■─────────■── # ├─────┤┌─┴─┐┌───┐┌─┴─┐ # q_1: ┤ Tdg ├┤ X ├┤ T ├┤ X ├ # └─────┘└───┘└───┘└───┘ circ1 = QuantumCircuit(2) circ1.tdg(0) circ1.tdg(1) circ1.cx(0, 1) circ1.t(1) circ1.cx(0, 1) # ┌─────┐┌───┐┌───┐┌───┐ # q_0: ┤ Tdg ├┤ X ├┤ T ├┤ X ├ # ├─────┤└─┬─┘└───┘└─┬─┘ # q_1: ┤ Tdg ├──■─────────■── # └─────┘ circ2 = QuantumCircuit(2) circ2.tdg(1) circ2.tdg(0) circ2.cx(1, 0) circ2.t(0) circ2.cx(1, 0) elem1 = CNOTDihedral(circ1) elem2 = CNOTDihedral(circ2) self.assertEqual(elem1, elem2, "Error: 2-qubit CSdg identity does not hold") # XI*CS*XI*ISdg = CSdg # # ┌───┐┌───┐ ┌───┐ # q_0: ┤ X ├┤ T ├──■───────────■───┤ X ├─ # ├───┤└───┘┌─┴─┐┌─────┐┌─┴─┐┌┴───┴┐ # q_1: ┤ T ├─────┤ X ├┤ Tdg ├┤ X ├┤ Sdg ├ # └───┘ └───┘└─────┘└───┘└─────┘ circ3 = QuantumCircuit(2) circ3.x(0) circ3.t(0) circ3.t(1) circ3.cx(0, 1) circ3.tdg(1) circ3.cx(0, 1) circ3.x(0) circ3.sdg(1) elem3 = CNOTDihedral(circ3) self.assertEqual(elem1, elem3, "Error: 2-qubit CSdg identity does not hold") # IX*CS*IX*SdgI = CSdg # # ┌───┐ ┌─────┐ # q_0: ┤ T ├───────■───────────■──┤ Sdg ├ # ├───┤┌───┐┌─┴─┐┌─────┐┌─┴─┐└┬───┬┘ # q_1: ┤ X ├┤ T ├┤ X ├┤ Tdg ├┤ X ├─┤ X ├─ # └───┘└───┘└───┘└─────┘└───┘ └───┘ circ4 = QuantumCircuit(2) circ4.x(1) circ4.t(0) circ4.t(1) circ4.cx(0, 1) circ4.tdg(1) circ4.cx(0, 1) circ4.x(1) circ4.sdg(0) elem4 = CNOTDihedral(circ4) self.assertEqual(elem1, elem4, "Error: 2-qubit CSdg identity does not hold") # relations for CZ # CZ(0,1) = CZ(1,0) elem = CNOTDihedral(CZGate()) circ1 = QuantumCircuit(2) circ1.cz(0, 1) circ2 = QuantumCircuit(2) circ2.cz(1, 0) elem1 = CNOTDihedral(circ1) elem2 = CNOTDihedral(circ2) self.assertEqual(elem, elem1, "Error: 2-qubit CZ identity does not hold") self.assertEqual(elem1, elem2, "Error: 2-qubit CZ identity does not hold") # CZ = CS * CS # # ┌───┐ ┌───┐ # q_0: ┤ T ├──■───────────■──┤ T ├──■───────────■── # ├───┤┌─┴─┐┌─────┐┌─┴─┐├───┤┌─┴─┐┌─────┐┌─┴─┐ # q_1: ┤ T ├┤ X ├┤ Tdg ├┤ X ├┤ T ├┤ X ├┤ Tdg ├┤ X ├ # └───┘└───┘└─────┘└───┘└───┘└───┘└─────┘└───┘ circ3 = QuantumCircuit(2) circ3.t(0) circ3.t(1) circ3.cx(0, 1) circ3.tdg(1) circ3.cx(0, 1) circ3.t(0) circ3.t(1) circ3.cx(0, 1) circ3.tdg(1) circ3.cx(0, 1) elem3 = CNOTDihedral(circ3) self.assertEqual(elem1, elem3, "Error: 2-qubit CZ identity does not hold") # CZ = CSdg * CSdg # # ┌─────┐ ┌─────┐ # q_0: ┤ Tdg ├──■─────────■──┤ Tdg ├──■─────────■── # ├─────┤┌─┴─┐┌───┐┌─┴─┐├─────┤┌─┴─┐┌───┐┌─┴─┐ # q_1: ┤ Tdg ├┤ X ├┤ T ├┤ X ├┤ Tdg ├┤ X ├┤ T ├┤ X ├ # └─────┘└───┘└───┘└───┘└─────┘└───┘└───┘└───┘ circ4 = QuantumCircuit(2) circ4.tdg(0) circ4.tdg(1) circ4.cx(0, 1) circ4.t(1) circ4.cx(0, 1) circ4.tdg(0) circ4.tdg(1) circ4.cx(0, 1) circ4.t(1) circ4.cx(0, 1) elem4 = CNOTDihedral(circ4) self.assertEqual(elem1, elem4, "Error: 2-qubit CZ identity does not hold") # CZ = TdgTdg * CX * T^2I * CX * TdgTdg # # ┌─────┐┌───┐┌───┐┌───┐┌───┐┌─────┐ # q_0: ┤ Tdg ├┤ X ├┤ T ├┤ T ├┤ X ├┤ Tdg ├ # ├─────┤└─┬─┘└───┘└───┘└─┬─┘├─────┤ # q_1: ┤ Tdg ├──■──────────────■──┤ Tdg ├ # └─────┘ └─────┘ circ5 = QuantumCircuit(2) circ5.tdg(0) circ5.tdg(1) circ5.cx(1, 0) circ5.t(0) circ5.t(0) circ5.cx(1, 0) circ5.tdg(0) circ5.tdg(1) elem5 = CNOTDihedral(circ5) self.assertEqual(elem1, elem5, "Error: 2-qubit CZ identity does not hold") # relations for CX circ1 = QuantumCircuit(2) circ1.cx(0, 1) elem1 = CNOTDihedral(circ1) # TI*CX*TdgI = CX # # ┌───┐ ┌─────┐ # q_0: ┤ T ├──■──┤ Tdg ├ # └───┘┌─┴─┐└─────┘ # q_1: ─────┤ X ├─────── # └───┘ circ2 = QuantumCircuit(2) circ2.t(0) circ2.cx(0, 1) circ2.tdg(0) elem2 = CNOTDihedral(circ2) self.assertEqual(elem1, elem2, "Error: 2-qubit CX identity does not hold") # IZ*CX*ZZ = CX # # ┌───┐ # q_0: ───────■──┤ Z ├ # ┌───┐┌─┴─┐├───┤ # q_1: ┤ Z ├┤ X ├┤ Z ├ # └───┘└───┘└───┘ circ3 = QuantumCircuit(2) circ3.z(1) circ3.cx(0, 1) circ3.z(0) circ3.z(1) elem3 = CNOTDihedral(circ3) self.assertEqual(elem1, elem3, "Error: 2-qubit CX identity does not hold") # IX*CX*IX = CX # # q_0: ───────■─────── # ┌───┐┌─┴─┐┌───┐ # q_1: ┤ X ├┤ X ├┤ X ├ # └───┘└───┘└───┘ circ4 = QuantumCircuit(2) circ4.x(1) circ4.cx(0, 1) circ4.x(1) elem4 = CNOTDihedral(circ4) self.assertEqual(elem1, elem4, "Error: 2-qubit CX identity does not hold") # XI*CX*XX = CX # # ┌───┐ ┌───┐ # q_0: ┤ X ├──■──┤ X ├ # └───┘┌─┴─┐├───┤ # q_1: ─────┤ X ├┤ X ├ # └───┘└───┘ circ5 = QuantumCircuit(2) circ5.x(0) circ5.cx(0, 1) circ5.x(0) circ5.x(1) elem5 = CNOTDihedral(circ5) self.assertEqual(elem1, elem5, "Error: 2-qubit CX identity does not hold") # IT*CX01*CX10*TdgI = CX01*CX10 # # ┌───┐ # q_0: ──■──┤ X ├ # ┌─┴─┐└─┬─┘ # q_1: ┤ X ├──■── # └───┘ circ1 = QuantumCircuit(2) circ1.cx(0, 1) circ1.cx(1, 0) # ┌───┐┌─────┐ # q_0: ───────■──┤ X ├┤ Tdg ├ # ┌───┐┌─┴─┐└─┬─┘└─────┘ # q_1: ┤ T ├┤ X ├──■───────── # └───┘└───┘ circ2 = QuantumCircuit(2) circ2.t(1) circ2.cx(0, 1) circ2.cx(1, 0) circ2.tdg(0) elem1 = CNOTDihedral(circ1) elem2 = CNOTDihedral(circ2) self.assertEqual(elem1, elem2, "Error: 2-qubit CX01*CX10 identity does not hold")
def test_2_qubit_identities(self): """Tests identities for 2-qubit gates""" # SI * CX * SdgI = CX elem = CNOTDihedral(CXGate()) circ1 = QuantumCircuit(2) circ1.s(0) circ1.cx(0, 1) circ1.sdg(0) elem1 = CNOTDihedral(circ1) self.assertEqual(elem, elem1, "Error: 2-qubit CX identity does not hold") # SI * CZ * SdgI = CZ elem = CNOTDihedral(CZGate()) circ1 = QuantumCircuit(2) circ1.s(0) circ1.cz(1, 0) circ1.sdg(0) elem1 = CNOTDihedral(circ1) self.assertEqual(elem, elem1, "Error: 2-qubit CZ identity does not hold") # SWAP = CX01 * CX10 * CX01 = CX10 * CX01 * CX10 elem = CNOTDihedral(SwapGate()) circ1 = QuantumCircuit(2) circ1.cx(0, 1) circ1.cx(1, 0) circ1.cx(0, 1) circ2 = QuantumCircuit(2) circ2.cx(1, 0) circ2.cx(0, 1) circ2.cx(1, 0) elem1 = CNOTDihedral(circ1) elem2 = CNOTDihedral(circ2) self.assertEqual(elem, elem1, "Error: 2-qubit SWAP identity does not hold") self.assertEqual(elem1, elem2, "Error: 2-qubit SWAP identity does not hold") # CS01 = CS10 (symmetric) circ1 = QuantumCircuit(2) circ1.t(0) circ1.t(1) circ1.cx(0, 1) circ1.tdg(1) circ1.cx(0, 1) circ2 = QuantumCircuit(2) circ2.t(1) circ2.t(0) circ2.cx(1, 0) circ2.tdg(0) circ2.cx(1, 0) elem1 = CNOTDihedral(circ1) elem2 = CNOTDihedral(circ2) self.assertEqual(elem1, elem2, "Error: 2-qubit CS identity does not hold") # TI*CS*TdgI = CS circ3 = QuantumCircuit(2) circ3.t(0) circ3.t(0) circ3.t(1) circ3.cx(0, 1) circ3.tdg(1) circ3.cx(0, 1) circ3.tdg(0) elem3 = CNOTDihedral(circ3) self.assertEqual(elem1, elem3, "Error: 2-qubit CS identity does not hold") # IT*CS*ITdg = CS circ4 = QuantumCircuit(2) circ4.t(1) circ4.t(0) circ4.t(1) circ4.cx(0, 1) circ4.tdg(1) circ4.cx(0, 1) circ4.tdg(1) elem4 = CNOTDihedral(circ4) self.assertEqual(elem1, elem4, "Error: 2-qubit CS identity does not hold") # XX*CS*XX*SS = CS circ5 = QuantumCircuit(2) circ5.x(0) circ5.x(1) circ5.t(0) circ5.t(1) circ5.cx(0, 1) circ5.tdg(1) circ5.cx(0, 1) circ5.x(0) circ5.x(1) circ5.s(0) circ5.s(1) elem5 = CNOTDihedral(circ5) self.assertEqual(elem1, elem5, "Error: 2-qubit CS identity does not hold") # CSdg01 = CSdg10 (symmetric) circ1 = QuantumCircuit(2) circ1.tdg(0) circ1.tdg(1) circ1.cx(0, 1) circ1.t(1) circ1.cx(0, 1) circ2 = QuantumCircuit(2) circ2.tdg(1) circ2.tdg(0) circ2.cx(1, 0) circ2.t(0) circ2.cx(1, 0) elem1 = CNOTDihedral(circ1) elem2 = CNOTDihedral(circ2) self.assertEqual(elem1, elem2, "Error: 2-qubit CSdg identity does not hold") # XI*CS*XI*ISdg = CSdg circ3 = QuantumCircuit(2) circ3.x(0) circ3.t(0) circ3.t(1) circ3.cx(0, 1) circ3.tdg(1) circ3.cx(0, 1) circ3.x(0) circ3.sdg(1) elem3 = CNOTDihedral(circ3) self.assertEqual(elem1, elem3, "Error: 2-qubit CSdg identity does not hold") # IX*CS*IX*SdgI = CSdg circ4 = QuantumCircuit(2) circ4.x(1) circ4.t(0) circ4.t(1) circ4.cx(0, 1) circ4.tdg(1) circ4.cx(0, 1) circ4.x(1) circ4.sdg(0) elem4 = CNOTDihedral(circ4) self.assertEqual(elem1, elem4, "Error: 2-qubit CSdg identity does not hold") # relations for CZ # CZ(0,1) = CZ(1,0) elem = CNOTDihedral(CZGate()) circ1 = QuantumCircuit(2) circ1.cz(0, 1) circ2 = QuantumCircuit(2) circ2.cz(1, 0) elem1 = CNOTDihedral(circ1) elem2 = CNOTDihedral(circ2) self.assertEqual(elem, elem1, "Error: 2-qubit CZ identity does not hold") self.assertEqual(elem1, elem2, "Error: 2-qubit CZ identity does not hold") # CZ = CS * CS circ3 = QuantumCircuit(2) circ3.t(0) circ3.t(1) circ3.cx(0, 1) circ3.tdg(1) circ3.cx(0, 1) circ3.t(0) circ3.t(1) circ3.cx(0, 1) circ3.tdg(1) circ3.cx(0, 1) elem3 = CNOTDihedral(circ3) self.assertEqual(elem1, elem3, "Error: 2-qubit CZ identity does not hold") # CZ = CSdg * CSdg circ4 = QuantumCircuit(2) circ4.tdg(0) circ4.tdg(1) circ4.cx(0, 1) circ4.t(1) circ4.cx(0, 1) circ4.tdg(0) circ4.tdg(1) circ4.cx(0, 1) circ4.t(1) circ4.cx(0, 1) elem4 = CNOTDihedral(circ4) self.assertEqual(elem1, elem4, "Error: 2-qubit CZ identity does not hold") # CZ = TdgTdg * CX * T^2I * CX * TdgTdg circ5 = QuantumCircuit(2) circ5.tdg(0) circ5.tdg(1) circ5.cx(1, 0) circ5.t(0) circ5.t(0) circ5.cx(1, 0) circ5.tdg(0) circ5.tdg(1) elem5 = CNOTDihedral(circ5) self.assertEqual(elem1, elem5, "Error: 2-qubit CZ identity does not hold") # relations for CX circ1 = QuantumCircuit(2) circ1.cx(0, 1) elem1 = CNOTDihedral(circ1) # TI*CX*TdgI = CX circ2 = QuantumCircuit(2) circ2.t(0) circ2.cx(0, 1) circ2.tdg(0) elem2 = CNOTDihedral(circ2) self.assertEqual(elem1, elem2, "Error: 2-qubit CX identity does not hold") # IZ*CX*ZZ = CX circ3 = QuantumCircuit(2) circ3.z(1) circ3.cx(0, 1) circ3.z(0) circ3.z(1) elem3 = CNOTDihedral(circ3) self.assertEqual(elem1, elem3, "Error: 2-qubit CX identity does not hold") # IX*CX*IX = CX circ4 = QuantumCircuit(2) circ4.x(1) circ4.cx(0, 1) circ4.x(1) elem4 = CNOTDihedral(circ4) self.assertEqual(elem1, elem4, "Error: 2-qubit CX identity does not hold") # XI*CX*XX = CX circ5 = QuantumCircuit(2) circ5.x(0) circ5.cx(0, 1) circ5.x(0) circ5.x(1) elem5 = CNOTDihedral(circ5) self.assertEqual(elem1, elem5, "Error: 2-qubit CX identity does not hold") # IT*CX01*CX10*TdgI = CX01*CX10 circ1 = QuantumCircuit(2) circ1.cx(0, 1) circ1.cx(1, 0) circ2 = QuantumCircuit(2) circ2.t(1) circ2.cx(0, 1) circ2.cx(1, 0) circ2.tdg(0) elem1 = CNOTDihedral(circ1) elem2 = CNOTDihedral(circ2) self.assertEqual(elem1, elem2, "Error: 2-qubit CX01*CX10 identity does not hold")