def test_inverse_x(self, num_ctrl_qubits): """test inverting ControlledGate""" cnx = XGate().control(num_ctrl_qubits) inv_cnx = cnx.inverse() result = Operator(cnx).compose(Operator(inv_cnx)) np.testing.assert_array_almost_equal(result.data, np.identity(result.dim[0]))
def test_is_identity(self): """ The is_identity function determines whether a pair of gates forms the identity, when ignoring control qubits. """ seq = [ DAGNode({ 'type': 'op', 'op': XGate().control() }), DAGNode({ 'type': 'op', 'op': XGate().control(2) }) ] self.assertTrue(HoareOptimizer()._is_identity(seq)) seq = [ DAGNode({ 'type': 'op', 'op': RZGate(-pi / 2).control() }), DAGNode({ 'type': 'op', 'op': RZGate(pi / 2).control(2) }) ] self.assertTrue(HoareOptimizer()._is_identity(seq)) seq = [ DAGNode({ 'type': 'op', 'op': CSwapGate() }), DAGNode({ 'type': 'op', 'op': SwapGate() }) ] self.assertTrue(HoareOptimizer()._is_identity(seq)) seq = [ DAGNode({ 'type': 'op', 'op': UnitaryGate([[1, 0], [0, 1j]]).control() }), DAGNode({ 'type': 'op', 'op': UnitaryGate([[1, 0], [0, -1j]]) }) ]
def test_open_controlled_gate(self): """ Test controlled gates with control on '0' """ base_gate = XGate() base_mat = base_gate.to_matrix() num_ctrl_qubits = 3 ctrl_state = 5 cgate = base_gate.control(num_ctrl_qubits, ctrl_state=ctrl_state) target_mat = _compute_control_matrix(base_mat, num_ctrl_qubits, ctrl_state=ctrl_state) self.assertEqual(Operator(cgate), Operator(target_mat)) ctrl_state = None cgate = base_gate.control(num_ctrl_qubits, ctrl_state=ctrl_state) target_mat = _compute_control_matrix(base_mat, num_ctrl_qubits, ctrl_state=ctrl_state) self.assertEqual(Operator(cgate), Operator(target_mat)) ctrl_state = 0 cgate = base_gate.control(num_ctrl_qubits, ctrl_state=ctrl_state) target_mat = _compute_control_matrix(base_mat, num_ctrl_qubits, ctrl_state=ctrl_state) self.assertEqual(Operator(cgate), Operator(target_mat)) ctrl_state = 7 cgate = base_gate.control(num_ctrl_qubits, ctrl_state=ctrl_state) target_mat = _compute_control_matrix(base_mat, num_ctrl_qubits, ctrl_state=ctrl_state) self.assertEqual(Operator(cgate), Operator(target_mat)) ctrl_state = '110' cgate = base_gate.control(num_ctrl_qubits, ctrl_state=ctrl_state) target_mat = _compute_control_matrix(base_mat, num_ctrl_qubits, ctrl_state=ctrl_state) self.assertEqual(Operator(cgate), Operator(target_mat))
def test_multi_control_toffoli_matrix_advanced_dirty_ancillas( self, num_controls): """Test the multi-control Toffoli gate with dirty ancillas (advanced). Based on the test moved here from Aqua: https://github.com/Qiskit/qiskit-aqua/blob/769ca8f/test/aqua/test_mct.py """ q_controls = QuantumRegister(num_controls) q_target = QuantumRegister(1) qc = QuantumCircuit(q_controls, q_target) q_ancillas = None if num_controls <= 4: num_ancillas = 0 else: num_ancillas = 1 q_ancillas = QuantumRegister(num_ancillas) qc.add_register(q_ancillas) qc.mct(q_controls, q_target[0], q_ancillas, mode='advanced') simulated = execute( qc, BasicAer.get_backend('unitary_simulator')).result().get_unitary(qc) if num_ancillas > 0: simulated = simulated[:2**(num_controls + 1), :2**(num_controls + 1)] base = XGate().to_matrix() expected = _compute_control_matrix(base, num_controls) self.assertTrue(matrix_equal(simulated, expected, atol=1e-8))
def test_relative_phase_toffoli_gates(self, num_ctrl_qubits): """Test the relative phase Toffoli gates. This test compares the matrix representation of the relative phase gate classes (i.e. RCCXGate().to_matrix()), the matrix obtained from the unitary simulator, and the exact version of the gate as obtained through `_compute_control_matrix`. """ # get target matrix (w/o relative phase) base_mat = XGate().to_matrix() target_mat = _compute_control_matrix(base_mat, num_ctrl_qubits) # build the matrix for the relative phase toffoli using the unitary simulator circuit = QuantumCircuit(num_ctrl_qubits + 1) if num_ctrl_qubits == 2: circuit.rccx(0, 1, 2) else: # num_ctrl_qubits == 3: circuit.rcccx(0, 1, 2, 3) simulator = BasicAer.get_backend('unitary_simulator') simulated_mat = execute(circuit, simulator).result().get_unitary() # get the matrix representation from the class itself if num_ctrl_qubits == 2: repr_mat = RCCXGate().to_matrix() else: # num_ctrl_qubits == 3: repr_mat = RC3XGate().to_matrix() # test up to phase # note, that all entries may have an individual phase! (as opposed to a global phase) self.assertTrue(matrix_equal(np.abs(simulated_mat), target_mat)) # compare simulated matrix with the matrix representation provided by the class self.assertTrue(matrix_equal(simulated_mat, repr_mat))
def definition(self) -> List: """Return definition in terms of other basic gates. If the gate has open controls, as determined from `self.ctrl_state`, the returned definition is conjugated with X without changing the internal `_definition`. """ if not self._definition: self._define() # pylint: disable=cyclic-import from qiskit.extensions.standard import XGate, CXGate bit_ctrl_state = bin(self.ctrl_state)[2:].zfill(self.num_ctrl_qubits) # hacky way to get register assuming single register if self._definition: qreg = self._definition[0][1][0].register definition = self._definition elif isinstance(self, CXGate): qreg = QuantumRegister(self.num_qubits, 'q') definition = [(self, [qreg[0], qreg[1]], [])] open_rules = [] for qind, val in enumerate(bit_ctrl_state[::-1]): if val == '0': open_rules.append([XGate(), [qreg[qind]], []]) if open_rules: return open_rules + definition + open_rules else: return self._definition
def test_multi_control_toffoli_matrix_clean_ancillas(self, num_controls): """Test the multi-control Toffoli gate with clean ancillas. Based on the test moved here from Aqua: https://github.com/Qiskit/qiskit-aqua/blob/769ca8f/test/aqua/test_mct.py """ # set up circuit q_controls = QuantumRegister(num_controls) q_target = QuantumRegister(1) qc = QuantumCircuit(q_controls, q_target) if num_controls > 2: num_ancillas = num_controls - 2 q_ancillas = QuantumRegister(num_controls) qc.add_register(q_ancillas) else: num_ancillas = 0 q_ancillas = None # apply hadamard on control qubits and toffoli gate qc.mct(q_controls, q_target[0], q_ancillas, mode='basic') # execute the circuit and obtain statevector result backend = BasicAer.get_backend('unitary_simulator') simulated = execute(qc, backend).result().get_unitary(qc) # compare to expectation if num_ancillas > 0: simulated = simulated[:2**(num_controls + 1), :2**(num_controls + 1)] base = XGate().to_matrix() expected = _compute_control_matrix(base, num_controls) self.assertTrue(matrix_equal(simulated, expected))
def correct_error(self): self.qc.h(self.qr[0]) self.qc.h(self.qr[1]) self.qc.h(self.qr[2]) self.qc.cx(self.qr[0], self.qr[1]) self.qc.cx(self.qr[0], self.qr[2]) c2x_gate = XGate().control(2) self.qc.append(c2x_gate, [2, 1, 0])
def test_open_controlled_gate_raises(self): """ Test controlled gates with open controls raises if ctrl_state isn't allowed. """ base_gate = XGate() num_ctrl_qubits = 3 with self.assertRaises(CircuitError): base_gate.control(num_ctrl_qubits, ctrl_state=-1) with self.assertRaises(CircuitError): base_gate.control(num_ctrl_qubits, ctrl_state=2**num_ctrl_qubits) with self.assertRaises(CircuitError): base_gate.control(num_ctrl_qubits, ctrl_state='201')
def test_contains(self): """Verify checking if a inst/qarg/carg tuple is in circuit.data.""" qr = QuantumRegister(2) qc = QuantumCircuit(qr) qc.h(0) self.assertTrue((HGate(), [qr[0]], []) in qc.data) self.assertFalse((HGate(), [qr[1]], []) in qc.data) self.assertFalse((XGate(), [qr[0]], []) in qc.data)
def from_label(cls, label): """Return a tensor product of single-qubit operators. Args: label (string): single-qubit operator string. Returns: Operator: The N-qubit operator. Raises: QiskitError: if the label contains invalid characters, or the length of the label is larger than an explicitly specified num_qubits. Additional Information: The labels correspond to the single-qubit matrices: 'I': [[1, 0], [0, 1]] 'X': [[0, 1], [1, 0]] 'Y': [[0, -1j], [1j, 0]] 'Z': [[1, 0], [0, -1]] 'H': [[1, 1], [1, -1]] / sqrt(2) 'S': [[1, 0], [0 , 1j]] 'T': [[1, 0], [0, (1+1j) / sqrt(2)]] '0': [[1, 0], [0, 0]] '1': [[0, 0], [0, 1]] '+': [[0.5, 0.5], [0.5 , 0.5]] '-': [[0.5, -0.5], [-0.5 , 0.5]] 'r': [[0.5, -0.5j], [0.5j , 0.5]] 'l': [[0.5, 0.5j], [-0.5j , 0.5]] """ # Check label is valid label_mats = { 'I': IGate().to_matrix(), 'X': XGate().to_matrix(), 'Y': YGate().to_matrix(), 'Z': ZGate().to_matrix(), 'H': HGate().to_matrix(), 'S': SGate().to_matrix(), 'T': TGate().to_matrix(), '0': np.array([[1, 0], [0, 0]], dtype=complex), '1': np.array([[0, 0], [0, 1]], dtype=complex), '+': np.array([[0.5, 0.5], [0.5, 0.5]], dtype=complex), '-': np.array([[0.5, -0.5], [-0.5, 0.5]], dtype=complex), 'r': np.array([[0.5, -0.5j], [0.5j, 0.5]], dtype=complex), 'l': np.array([[0.5, 0.5j], [-0.5j, 0.5]], dtype=complex), } if re.match(r'^[IXYZHST01rl\-+]+$', label) is None: raise QiskitError('Label contains invalid characters.') # Initialize an identity matrix and apply each gate num_qubits = len(label) op = Operator(np.eye(2**num_qubits, dtype=complex)) for qubit, char in enumerate(reversed(label)): if char != 'I': op = op.compose(label_mats[char], qargs=[qubit]) return op
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 to_instruction(self): """Convert to Pauli circuit instruction.""" from qiskit.circuit import QuantumCircuit, QuantumRegister from qiskit.extensions.standard import IdGate, XGate, YGate, ZGate gates = {'I': IdGate(), 'X': XGate(), 'Y': YGate(), 'Z': ZGate()} label = self.to_label() n_qubits = self.numberofqubits qreg = QuantumRegister(n_qubits) circuit = QuantumCircuit(qreg, name='Pauli:{}'.format(label)) for i, pauli in enumerate(reversed(label)): circuit.append(gates[pauli], [qreg[i]]) return circuit.to_instruction()
class TestParameterCtrlState(QiskitTestCase): """Test gate equality with ctrl_state parameter.""" @data((RXGate(0.5), CRXGate(0.5)), (RYGate(0.5), CRYGate(0.5)), (RZGate(0.5), CRZGate(0.5)), (XGate(), CXGate()), (YGate(), CYGate()), (ZGate(), CZGate()), (U1Gate(0.5), CU1Gate(0.5)), (SwapGate(), CSwapGate()), (HGate(), CHGate()), (U3Gate(0.1, 0.2, 0.3), CU3Gate(0.1, 0.2, 0.3))) @unpack def test_ctrl_state_one(self, gate, controlled_gate): """Test controlled gates with ctrl_state See https://github.com/Qiskit/qiskit-terra/pull/4025 """ self.assertEqual(gate.control(1, ctrl_state='1'), controlled_gate)
def test_open_controlled_unitary_matrix(self, num_ctrl_qubits): """test open controlled unitary matrix""" # verify truth table num_target_qubits = 2 num_qubits = num_ctrl_qubits + num_target_qubits target_op = Operator(XGate()) for i in range(num_target_qubits - 1): target_op = target_op.tensor(XGate()) for i in range(2**num_qubits): input_bitstring = bin(i)[2:].zfill(num_qubits) input_target = input_bitstring[0:num_target_qubits] input_ctrl = input_bitstring[-num_ctrl_qubits:] phi = Statevector.from_label(input_bitstring) cop = Operator( _compute_control_matrix(target_op.data, num_ctrl_qubits, ctrl_state=input_ctrl)) for j in range(2**num_qubits): output_bitstring = bin(j)[2:].zfill(num_qubits) output_target = output_bitstring[0:num_target_qubits] output_ctrl = output_bitstring[-num_ctrl_qubits:] psi = Statevector.from_label(output_bitstring) cxout = np.dot(phi.data, psi.evolve(cop).data) if input_ctrl == output_ctrl: # flip the target bits cond_output = ''.join( [str(int(not int(a))) for a in input_target]) else: cond_output = input_target if cxout == 1: self.assertTrue((output_ctrl == input_ctrl) and (output_target == cond_output)) else: self.assertTrue(((output_ctrl == input_ctrl) and (output_target != cond_output)) or output_ctrl != input_ctrl)
def test_multi_control_toffoli_matrix_noancilla_dirty_ancillas(self, num_controls): """Test the multi-control Toffoli gate with dirty ancillas (noancilla). Based on the test moved here from Aqua: https://github.com/Qiskit/qiskit-aqua/blob/769ca8f/test/aqua/test_mct.py """ q_controls = QuantumRegister(num_controls) q_target = QuantumRegister(1) qc = QuantumCircuit(q_controls, q_target) qc.mct(q_controls, q_target[0], None, mode='noancilla') simulated = execute(qc, BasicAer.get_backend('unitary_simulator')).result().get_unitary(qc) base = XGate().to_matrix() expected = _compute_control_matrix(base, num_controls) self.assertTrue(matrix_equal(simulated, expected, atol=1e-8))
def random_clifford_circuit(num_qubits, num_gates, gates='all', seed=None): """Generate a pseudo random Clifford circuit.""" if gates == 'all': if num_qubits == 1: gates = ['i', 'x', 'y', 'z', 'h', 's', 'sdg', 'v', 'w'] else: gates = [ 'i', 'x', 'y', 'z', 'h', 's', 'sdg', 'v', 'w', 'cx', 'cz', 'swap' ] instructions = { 'i': (IGate(), 1), 'x': (XGate(), 1), 'y': (YGate(), 1), 'z': (ZGate(), 1), 'h': (HGate(), 1), 's': (SGate(), 1), 'sdg': (SdgGate(), 1), 'v': (VGate(), 1), 'w': (WGate(), 1), 'cx': (CXGate(), 2), 'cz': (CZGate(), 2), 'swap': (SwapGate(), 2) } if isinstance(seed, np.random.RandomState): rng = seed else: rng = np.random.RandomState(seed=seed) samples = rng.choice(gates, num_gates) circ = QuantumCircuit(num_qubits) for name in samples: gate, nqargs = instructions[name] qargs = rng.choice(range(num_qubits), nqargs, replace=False).tolist() circ.append(gate, qargs) return circ
def test_targetsuccessive_identity_advanced_removal(self): """ Should remove target successive identity gates with DIFFERENT sets of control qubits. In this case CCCX(4,5,6,7) & CCX(5,6,7). """ circuit = QuantumCircuit(8) circuit.h(0) circuit.h(1) circuit.h(2) circuit.h(3) circuit.h(4) circuit.h(5) for i in range(3): circuit.cx(i * 2 + 1, i * 2) circuit.cx(3, 5) for i in range(2): circuit.ccx(i * 2, i * 2 + 1, i * 2 + 3) circuit.cx(i * 2 + 3, i * 2 + 2) circuit.ccx(4, 5, 6) for i in range(1, -1, -1): circuit.ccx(i * 2, i * 2 + 1, i * 2 + 3) circuit.cx(3, 5) circuit.cx(5, 6) circuit.cx(3, 5) circuit.x(6) for i in range(2): circuit.ccx(i * 2, i * 2 + 1, i * 2 + 3) for i in range(1, -1, -1): circuit.cx(i * 2 + 3, i * 2 + 2) circuit.ccx(i * 2, i * 2 + 1, i * 2 + 3) circuit.cx(1, 0) circuit.ccx(6, 1, 0) circuit.ccx(0, 1, 3) circuit.ccx(6, 3, 2) circuit.ccx(2, 3, 5) circuit.ccx(6, 5, 4) circuit.append(XGate().control(3), [4, 5, 6, 7], []) for i in range(1, -1, -1): circuit.ccx(i * 2, i * 2 + 1, i * 2 + 3) circuit.cx(3, 5) for i in range(1, 3): circuit.cx(i * 2 + 1, i * 2) circuit.ccx(5, 6, 7) expected = QuantumCircuit(8) expected.h(0) expected.h(1) expected.h(2) expected.h(3) expected.h(4) expected.h(5) for i in range(3): expected.cx(i * 2 + 1, i * 2) expected.cx(3, 5) for i in range(2): expected.ccx(i * 2, i * 2 + 1, i * 2 + 3) expected.cx(i * 2 + 3, i * 2 + 2) expected.ccx(4, 5, 6) for i in range(1, -1, -1): expected.ccx(i * 2, i * 2 + 1, i * 2 + 3) expected.cx(3, 5) expected.cx(5, 6) expected.cx(3, 5) expected.x(6) for i in range(2): expected.ccx(i * 2, i * 2 + 1, i * 2 + 3) for i in range(1, -1, -1): expected.cx(i * 2 + 3, i * 2 + 2) expected.ccx(i * 2, i * 2 + 1, i * 2 + 3) expected.cx(1, 0) expected.ccx(6, 1, 0) expected.ccx(0, 1, 3) expected.ccx(6, 3, 2) expected.ccx(2, 3, 5) expected.ccx(6, 5, 4) for i in range(1, -1, -1): expected.ccx(i * 2, i * 2 + 1, i * 2 + 3) expected.cx(3, 5) for i in range(1, 3): expected.cx(i * 2 + 1, i * 2) stv = Statevector.from_label('0' * circuit.num_qubits) self.assertEqual(stv @ circuit, stv @ expected) pass_ = HoareOptimizer(size=5) result = pass_.run(circuit_to_dag(circuit)) self.assertEqual(result, circuit_to_dag(expected))
def test_controlled_x(self): """Test creation of controlled x gate""" self.assertEqual(XGate().control(), CnotGate())
def _define(self): definition = [] # q = c1, c2, b, anc q = QuantumRegister(self.total_n, "q") # No easy way to inverse other than reverse the order of gates and # invert them. if not self._inverse: rule = [ (PhiADDaGate(self.a, self.n, c1=q[0], c2=q[1]), [q[0], q[1]] + [q[i] for i in range(2, self.n + 2)], []), (PhiADDaGate(self.N, self.n, inverse=True), [q[i] for i in range(2, self.n + 2)], []), (QFTGate(self.n, inverse=True), [q[i] for i in range(2, self.n + 2)], []), (CnotGate(), [q[self.total_n - 2], q[self.total_n - 1]], []), (QFTGate(self.n), [q[i] for i in range(2, self.n + 2)], []), (PhiADDaGate(self.N, self.n, c1=q[self.total_n - 1]), [q[i] for i in range(2, self.n + 2)] + [q[self.total_n - 1]], []), (PhiADDaGate(self.a, self.n, c1=q[0], c2=q[1], inverse=True), [q[0], q[1]] + [q[i] for i in range(2, self.n + 2)], []), (QFTGate(self.n, inverse=True), [q[i] for i in range(2, self.n + 2)], []), (XGate(), [q[self.total_n - 2]], []), (CnotGate(), [q[self.total_n - 2], q[self.total_n - 1]], []), (XGate(), [q[self.total_n - 2]], []), (QFTGate(self.n), [q[i] for i in range(2, self.n + 2)], []), (PhiADDaGate(self.a, self.n, c1=q[0], c2=q[1]), [q[0], q[1]] + [q[i] for i in range(2, self.n + 2)], []), ] else: rule = [ (PhiADDaGate(self.a, self.n, c1=q[0], c2=q[1], inverse=True), [q[0], q[1]] + [q[i] for i in range(2, self.n + 2)], []), (QFTGate(self.n, inverse=True), [q[i] for i in range(2, self.n + 2)], []), (XGate(), [q[self.total_n - 2]], []), (CnotGate(), [q[self.total_n - 2], q[self.total_n - 1]], []), (XGate(), [q[self.total_n - 2]], []), (QFTGate(self.n), [q[i] for i in range(2, self.n + 2)], []), (PhiADDaGate(self.a, self.n, c1=q[0], c2=q[1]), [q[0], q[1]] + [q[i] for i in range(2, self.n + 2)], []), (PhiADDaGate(self.N, self.n, c1=q[self.total_n - 1], inverse=True), [q[i] for i in range(2, self.n + 2)] + [q[self.total_n - 1]], []), (QFTGate(self.n, inverse=True), [q[i] for i in range(2, self.n + 2)], []), (CnotGate(), [q[self.total_n - 2], q[self.total_n - 1]], []), (QFTGate(self.n), [q[i] for i in range(2, self.n + 2)], []), (PhiADDaGate(self.N, self.n), [q[i] for i in range(2, self.n + 2)], []), (PhiADDaGate(self.a, self.n, c1=q[0], c2=q[1], inverse=True), [q[0], q[1]] + [q[i] for i in range(2, self.n + 2)], []), ] for inst in rule: definition.append(inst) self.definition = definition