def test_measure_split(self): """Test the result of a single qubit split by one measurement""" # Set test circuit self.circuit = ReferenceCircuits.h_measure_h() # Execute result = super().test_run_circuit() actual = result.get_statevector_tree() initial = actual['value'] path_0 = actual['path_0']['value'] path_1 = actual['path_1']['value'] # initial (before measurement) state is 1/sqrt(2)|00> + 1/sqrt(2)|01>, up to a global phase self.assertAlmostEqual((initial[0]), 1 / math.sqrt(2)) self.assertAlmostEqual((initial[1]), 1 / math.sqrt(2)) self.assertEqual(initial[2], 0) self.assertEqual(initial[3], 0) # path 0 state is 1/sqrt(2)|00> + 1/sqrt(2)|01>, up to a global phase self.assertAlmostEqual((path_0[0]), 1 / math.sqrt(2)) self.assertAlmostEqual((path_0[1]), 1 / math.sqrt(2)) self.assertEqual(path_0[2], 0) self.assertEqual(path_0[3], 0) # path 1 state is 1/sqrt(2)|00> - 1/sqrt(2)|01>, up to a global phase self.assertAlmostEqual((path_1[0]), 1 / math.sqrt(2)) self.assertAlmostEqual((path_1[1]), -1 / math.sqrt(2)) self.assertEqual(path_1[2], 0) self.assertEqual(path_1[3], 0)
def test_bell_split(self): """Test the result of a two qubit bell state split by one measurement""" # Set test circuit self.circuit = ReferenceCircuits.bell() # Execute result = super().test_run_circuit() actual = result.get_statevector_tree() initial = actual['value'] path_0 = actual['path_0']['value'] path_1 = actual['path_1']['value'] prob_0 = actual['path_0_probability'] prob_1 = actual['path_1_probability'] # initial (before measurement) state is 1/sqrt(2)|00> + 1/sqrt(2)|11>, up to a global phase self.assertAlmostEqual((initial[0]), 1 / math.sqrt(2)) self.assertAlmostEqual((initial[3]), 1 / math.sqrt(2)) self.assertAlmostEqual((prob_0), 1 / 2) self.assertAlmostEqual((prob_1), 1 / 2) self.assertEqual(initial[1], 0) self.assertEqual(initial[2], 0) # path 0 state is |00>, up to a global phase self.assertAlmostEqual((path_0[0]), 1) self.assertEqual(path_0[1], 0) self.assertEqual(path_0[2], 0) self.assertEqual(path_0[3], 0) # path 1 state is |11>, up to a global phase self.assertAlmostEqual((path_1[3]), 1) self.assertEqual(path_1[0], 0) self.assertEqual(path_1[1], 0) self.assertEqual(path_1[2], 0)
def test_run_circuit(self): """Test final state vector for single circuit run.""" # Set test circuit self.circuit = ReferenceCircuits.bell_no_measure() # Execute result = super().test_run_circuit() actual = result.get_statevector(self.circuit) # state is 1/sqrt(2)|00> + 1/sqrt(2)|11>, up to a global phase self.assertAlmostEqual((abs(actual[0]))**2, 1 / 2) self.assertEqual(actual[1], 0) self.assertEqual(actual[2], 0) self.assertAlmostEqual((abs(actual[3]))**2, 1 / 2)
def test_run_circuit(self): """Test that the simulator works for a circuit without measurements in the middle.""" # Set test circuit self.circuit = ReferenceCircuits.bell_no_measure() # Execute result = super().test_run_circuit() actual = result.get_statevector_tree()['value'] # state is 1/sqrt(2)|00> + 1/sqrt(2)|11>, up to a global phase self.assertAlmostEqual((abs(actual[0]))**2, 1 / 2) self.assertEqual(actual[1], 0) self.assertEqual(actual[2], 0) self.assertAlmostEqual((abs(actual[3]))**2, 1 / 2)
def test_measure_collapse(self): """Test final measurement collapses statevector""" # Set test circuit self.circuit = ReferenceCircuits.bell() # Execute result = super().test_run_circuit() actual = result.get_statevector(self.circuit) # The final state should be EITHER |00> OR |11> diff_00 = np.linalg.norm(np.array([1, 0, 0, 0]) - actual) ** 2 diff_11 = np.linalg.norm(np.array([0, 0, 0, 1]) - actual) ** 2 success = np.allclose([diff_00, diff_11], [0, 2]) or np.allclose([diff_00, diff_11], [2, 0]) # state is 1/sqrt(2)|00> + 1/sqrt(2)|11>, up to a global phase self.assertTrue(success)
class StatevectorSimulatorTest(providers.BackendTestCase): """Test BasicAer statevector simulator.""" backend_cls = StatevectorSimulatorPy circuit = ReferenceCircuits.bell_no_measure() def test_run_circuit(self): """Test final state vector for single circuit run.""" result = super().test_run_circuit() actual = result.get_statevector(self.circuit) # state is 1/sqrt(2)|00> + 1/sqrt(2)|11>, up to a global phase self.assertAlmostEqual((abs(actual[0]))**2, 1 / 2) self.assertEqual(actual[1], 0) self.assertEqual(actual[2], 0) self.assertAlmostEqual((abs(actual[3]))**2, 1 / 2)
class BasicAerUnitarySimulatorPyTest(providers.BackendTestCase): """Test BasicAer unitary simulator.""" backend_cls = UnitarySimulatorPy circuit = ReferenceCircuits.bell_no_measure() def test_basicaer_unitary_simulator_py(self): """Test unitary simulator.""" circuits = self._test_circuits() job = execute(circuits, backend=self.backend) sim_unitaries = [job.result().get_unitary(circ) for circ in circuits] reference_unitaries = self._reference_unitaries() for u_sim, u_ref in zip(sim_unitaries, reference_unitaries): self.assertTrue(matrix_equal(u_sim, u_ref, ignore_phase=True)) def _test_circuits(self): """Return test circuits for unitary simulator""" qr = QuantumRegister(3) cr = ClassicalRegister(3) qc1 = QuantumCircuit(qr, cr) qc2 = QuantumCircuit(qr, cr) qc3 = QuantumCircuit(qr, cr) qc4 = QuantumCircuit(qr, cr) qc5 = QuantumCircuit(qr, cr) # Test circuit 1: HxHxH qc1.h(qr) # Test circuit 2: IxCX qc2.cx(qr[0], qr[1]) # Test circuit 3: CXxY qc3.y(qr[0]) qc3.cx(qr[1], qr[2]) # Test circuit 4: (CX.I).(IxCX).(IxIxX) qc4.h(qr[0]) qc4.cx(qr[0], qr[1]) qc4.cx(qr[1], qr[2]) # Test circuit 5 (X.Z)x(Z.Y)x(Y.X) qc5.x(qr[0]) qc5.y(qr[0]) qc5.y(qr[1]) qc5.z(qr[1]) qc5.z(qr[2]) qc5.x(qr[2]) return [qc1, qc2, qc3, qc4, qc5] def _reference_unitaries(self): """Return reference unitaries for test circuits""" # Gate matrices gate_h = np.array([[1, 1], [1, -1]]) / np.sqrt(2) gate_x = np.array([[0, 1], [1, 0]]) gate_y = np.array([[0, -1j], [1j, 0]]) gate_z = np.array([[1, 0], [0, -1]]) gate_cx = np.array([[1, 0, 0, 0], [0, 0, 0, 1], [0.0, 0, 1, 0], [0, 1, 0, 0]]) # Unitary matrices target_unitary1 = np.kron(np.kron(gate_h, gate_h), gate_h) target_unitary2 = np.kron(np.eye(2), gate_cx) target_unitary3 = np.kron(gate_cx, gate_y) target_unitary4 = np.dot( np.kron(gate_cx, np.eye(2)), np.dot(np.kron(np.eye(2), gate_cx), np.kron(np.eye(4), gate_h)), ) target_unitary5 = np.kron( np.kron(np.dot(gate_x, gate_z), np.dot(gate_z, gate_y)), np.dot(gate_y, gate_x) ) return [target_unitary1, target_unitary2, target_unitary3, target_unitary4, target_unitary5] def test_unitary(self): """Test unitary gate instruction""" num_trials = 10 max_qubits = 3 # Test 1 to max_qubits for random n-qubit unitary gate for i in range(max_qubits): num_qubits = i + 1 unitary_init = Operator(np.eye(2 ** num_qubits)) qr = QuantumRegister(num_qubits, "qr") for _ in range(num_trials): # Create random unitary unitary = random_unitary(2 ** num_qubits) # Compute expected output state unitary_target = unitary.dot(unitary_init) # Simulate output on circuit circuit = QuantumCircuit(qr) circuit.unitary(unitary, qr) job = execute(circuit, self.backend) result = job.result() unitary_out = Operator(result.get_unitary(0)) fidelity = process_fidelity(unitary_target, unitary_out) self.assertGreater(fidelity, 0.999) def test_global_phase(self): """Test global phase for XZH See https://github.com/Qiskit/qiskit-terra/issues/3083""" q = QuantumRegister(1) circuit = QuantumCircuit(q) circuit.h(q[0]) circuit.z(q[0]) circuit.x(q[0]) job = execute(circuit, self.backend) result = job.result() unitary_out = result.get_unitary(circuit) unitary_target = np.array( [[-1 / np.sqrt(2), 1 / np.sqrt(2)], [1 / np.sqrt(2), 1 / np.sqrt(2)]] ) self.assertTrue(np.allclose(unitary_out, unitary_target))
class BasicAerUnitarySimulatorPyTest(providers.BackendTestCase): """Test BasicAer unitary simulator.""" backend_cls = UnitarySimulatorPy circuit = ReferenceCircuits.bell_no_measure() def test_basicaer_unitary_simulator_py(self): """Test unitary simulator.""" circuits = self._test_circuits() job = execute(circuits, backend=self.backend) sim_unitaries = [job.result().get_unitary(circ) for circ in circuits] reference_unitaries = self._reference_unitaries() norms = [ np.trace(np.dot(np.transpose(np.conj(target)), actual)) for target, actual in zip(reference_unitaries, sim_unitaries) ] for norm in norms: self.assertAlmostEqual(norm, 8) def _test_circuits(self): """Return test circuits for unitary simulator""" qr = QuantumRegister(3) cr = ClassicalRegister(3) qc1 = QuantumCircuit(qr, cr) qc2 = QuantumCircuit(qr, cr) qc3 = QuantumCircuit(qr, cr) qc4 = QuantumCircuit(qr, cr) qc5 = QuantumCircuit(qr, cr) # Test circuit 1: HxHxH qc1.h(qr) # Test circuit 2: IxCX qc2.cx(qr[0], qr[1]) # Test circuit 3: CXxY qc3.y(qr[0]) qc3.cx(qr[1], qr[2]) # Test circuit 4: (CX.I).(IxCX).(IxIxX) qc4.h(qr[0]) qc4.cx(qr[0], qr[1]) qc4.cx(qr[1], qr[2]) # Test circuit 5 (X.Z)x(Z.Y)x(Y.X) qc5.x(qr[0]) qc5.y(qr[0]) qc5.y(qr[1]) qc5.z(qr[1]) qc5.z(qr[2]) qc5.x(qr[2]) return [qc1, qc2, qc3, qc4, qc5] def _reference_unitaries(self): """Return reference unitaries for test circuits""" # Gate matrices gate_h = np.array([[1, 1], [1, -1]]) / np.sqrt(2) gate_x = np.array([[0, 1], [1, 0]]) gate_y = np.array([[0, -1j], [1j, 0]]) gate_z = np.array([[1, 0], [0, -1]]) gate_cx = np.array([[1, 0, 0, 0], [0, 0, 0, 1], [0., 0, 1, 0], [0, 1, 0, 0]]) # Unitary matrices target_unitary1 = np.kron(np.kron(gate_h, gate_h), gate_h) target_unitary2 = np.kron(np.eye(2), gate_cx) target_unitary3 = np.kron(gate_cx, gate_y) target_unitary4 = np.dot( np.kron(gate_cx, np.eye(2)), np.dot(np.kron(np.eye(2), gate_cx), np.kron(np.eye(4), gate_h))) target_unitary5 = np.kron( np.kron(np.dot(gate_x, gate_z), np.dot(gate_z, gate_y)), np.dot(gate_y, gate_x)) return [ target_unitary1, target_unitary2, target_unitary3, target_unitary4, target_unitary5 ]
class BasicAerUnitarySimulatorPyTest(providers.BackendTestCase): """Test BasicAer unitary simulator.""" backend_cls = UnitarySimulatorPy circuit = ReferenceCircuits.bell_no_measure() def test_basicaer_unitary_simulator_py(self): """Test unitary simulator.""" circuits = self._test_circuits() job = execute(circuits, backend=self.backend) sim_unitaries = [job.result().get_unitary(circ) for circ in circuits] reference_unitaries = self._reference_unitaries() norms = [ np.trace(np.dot(np.transpose(np.conj(target)), actual)) for target, actual in zip(reference_unitaries, sim_unitaries) ] for norm in norms: self.assertAlmostEqual(norm, 8) def _test_circuits(self): """Return test circuits for unitary simulator""" qr = QuantumRegister(3) cr = ClassicalRegister(3) qc1 = QuantumCircuit(qr, cr) qc2 = QuantumCircuit(qr, cr) qc3 = QuantumCircuit(qr, cr) qc4 = QuantumCircuit(qr, cr) qc5 = QuantumCircuit(qr, cr) # Test circuit 1: HxHxH qc1.h(qr) # Test circuit 2: IxCX qc2.cx(qr[0], qr[1]) # Test circuit 3: CXxY qc3.y(qr[0]) qc3.cx(qr[1], qr[2]) # Test circuit 4: (CX.I).(IxCX).(IxIxX) qc4.h(qr[0]) qc4.cx(qr[0], qr[1]) qc4.cx(qr[1], qr[2]) # Test circuit 5 (X.Z)x(Z.Y)x(Y.X) qc5.x(qr[0]) qc5.y(qr[0]) qc5.y(qr[1]) qc5.z(qr[1]) qc5.z(qr[2]) qc5.x(qr[2]) return [qc1, qc2, qc3, qc4, qc5] def _reference_unitaries(self): """Return reference unitaries for test circuits""" # Gate matrices gate_h = np.array([[1, 1], [1, -1]]) / np.sqrt(2) gate_x = np.array([[0, 1], [1, 0]]) gate_y = np.array([[0, -1j], [1j, 0]]) gate_z = np.array([[1, 0], [0, -1]]) gate_cx = np.array([[1, 0, 0, 0], [0, 0, 0, 1], [0., 0, 1, 0], [0, 1, 0, 0]]) # Unitary matrices target_unitary1 = np.kron(np.kron(gate_h, gate_h), gate_h) target_unitary2 = np.kron(np.eye(2), gate_cx) target_unitary3 = np.kron(gate_cx, gate_y) target_unitary4 = np.dot( np.kron(gate_cx, np.eye(2)), np.dot(np.kron(np.eye(2), gate_cx), np.kron(np.eye(4), gate_h))) target_unitary5 = np.kron( np.kron(np.dot(gate_x, gate_z), np.dot(gate_z, gate_y)), np.dot(gate_y, gate_x)) return [ target_unitary1, target_unitary2, target_unitary3, target_unitary4, target_unitary5 ] def test_unitary(self): """Test unitary gate instruction""" num_trials = 10 max_qubits = 3 # Test 1 to max_qubits for random n-qubit unitary gate for i in range(max_qubits): num_qubits = i + 1 unitary_init = np.eye(2**num_qubits) qr = QuantumRegister(num_qubits, 'qr') for _ in range(num_trials): # Create random unitary unitary = random_unitary(2**num_qubits) # Compute expected output state unitary_target = unitary.data.dot(unitary_init) # Simulate output on circuit circuit = QuantumCircuit(qr) circuit.unitary(unitary, qr) job = execute(circuit, self.backend) result = job.result() unitary_out = result.get_unitary(0) fidelity = process_fidelity(unitary_target, unitary_out) self.assertGreater(fidelity, 0.999)
def test_double_measure_split(self): """Test the result of a single qubit split by two measurements""" # Set test circuit self.circuit = ReferenceCircuits.h_measure_h_double() # Execute result = super().test_run_circuit() actual = result.get_statevector_tree() initial = actual['value'] path_0 = actual['path_0']['value'] path_1 = actual['path_1']['value'] path_00 = actual['path_0']['path_0']['value'] path_01 = actual['path_0']['path_1']['value'] path_10 = actual['path_1']['path_0']['value'] path_11 = actual['path_1']['path_1']['value'] prob_0 = actual['path_0_probability'] prob_1 = actual['path_1_probability'] prob_00 = actual['path_0']['path_0_probability'] prob_01 = actual['path_0']['path_1_probability'] prob_10 = actual['path_1']['path_0_probability'] prob_11 = actual['path_1']['path_1_probability'] # initial (before measurement) state is 1/sqrt(2)|00> + 1/sqrt(2)|01>, up to a global phase self.assertAlmostEqual((initial[0]), 1 / math.sqrt(2)) self.assertAlmostEqual((initial[1]), 1 / math.sqrt(2)) self.assertAlmostEqual((prob_0), 1 / 2) self.assertAlmostEqual((prob_1), 1 / 2) self.assertEqual(initial[2], 0) self.assertEqual(initial[3], 0) # path 0 state is 1/sqrt(2)|00> + 1/sqrt(2)|01>, up to a global phase self.assertAlmostEqual((path_0[0]), 1 / math.sqrt(2)) self.assertAlmostEqual((path_0[1]), 1 / math.sqrt(2)) self.assertAlmostEqual((prob_00), 1 / 2) self.assertAlmostEqual((prob_01), 1 / 2) self.assertEqual(path_0[2], 0) self.assertEqual(path_0[3], 0) # path 1 state is 1/sqrt(2)|00> - 1/sqrt(2)|01>, up to a global phase self.assertAlmostEqual((path_1[0]), 1 / math.sqrt(2)) self.assertAlmostEqual((path_1[1]), -1 / math.sqrt(2)) self.assertAlmostEqual((prob_10), 1 / 2) self.assertAlmostEqual((prob_11), 1 / 2) self.assertEqual(path_1[2], 0) self.assertEqual(path_1[3], 0) # path 00 state |00> up to a global phase self.assertAlmostEqual((path_00[0]), 1) self.assertEqual(path_00[1], 0) self.assertEqual(path_00[2], 0) self.assertEqual(path_00[3], 0) # path 01 state |01> up to a global phase self.assertAlmostEqual((path_01[1]), 1) self.assertEqual(path_01[0], 0) self.assertEqual(path_01[2], 0) self.assertEqual(path_01[3], 0) # path 10 state |00> up to a global phase self.assertAlmostEqual((path_10[0]), 1) self.assertEqual(path_10[1], 0) self.assertEqual(path_10[2], 0) self.assertEqual(path_10[3], 0) # path 01 state -|01> up to a global phase self.assertAlmostEqual((path_11[1]), -1) self.assertEqual(path_11[0], 0) self.assertEqual(path_11[2], 0) self.assertEqual(path_11[3], 0)
def test_double_measure_split_unequal_probability(self): """Test the result of a single qubit split by two measurements, when each measurement has unequal probabilities for the possible outcomes""" # Set test circuit self.circuit = ReferenceCircuits.rx_measure_rx() # Execute result = super().test_run_circuit() actual = result.get_statevector_tree() initial = actual['value'] path_0 = actual['path_0']['value'] path_1 = actual['path_1']['value'] path_00 = actual['path_0']['path_0']['value'] path_01 = actual['path_0']['path_1']['value'] path_10 = actual['path_1']['path_0']['value'] path_11 = actual['path_1']['path_1']['value'] prob_0 = actual['path_0_probability'] prob_1 = actual['path_1_probability'] prob_00 = actual['path_0']['path_0_probability'] prob_01 = actual['path_0']['path_1_probability'] prob_10 = actual['path_1']['path_0_probability'] prob_11 = actual['path_1']['path_1_probability'] # initial (before measurement) state is sqrt(3)/2|00> (- 1/2)j|01>, up to a global phase self.assertAlmostEqual((initial[0]), math.sqrt(3) / 2) self.assertAlmostEqual((initial[1]), -0.5j) self.assertAlmostEqual((prob_0), 3 / 4) self.assertAlmostEqual((prob_1), 1 / 4) self.assertEqual(initial[2], 0) self.assertEqual(initial[3], 0) # path 0 state is 1/sqrt(2)|00> + 1/sqrt(2)|01>, up to a global phase self.assertAlmostEqual((path_0[0]), math.sqrt(3) / 2) self.assertAlmostEqual((path_0[1]), -0.5j) self.assertAlmostEqual((prob_00), 3 / 4) self.assertAlmostEqual((prob_01), 1 / 4) self.assertEqual(path_0[2], 0) self.assertEqual(path_0[3], 0) # path 1 state is 1/sqrt(2)|00> - 1/sqrt(2)|01>, up to a global phase self.assertAlmostEqual((path_1[0]), -0.5) self.assertAlmostEqual((path_1[1]), -1j * (math.sqrt(3) / 2)) self.assertAlmostEqual((prob_10), 1 / 4) self.assertAlmostEqual((prob_11), 3 / 4) self.assertEqual(path_1[2], 0) self.assertEqual(path_1[3], 0) # path 00 state is |00> up to a global phase self.assertAlmostEqual(abs((path_00[0]**2)), 1) self.assertEqual(path_00[1], 0) self.assertEqual(path_00[2], 0) self.assertEqual(path_00[3], 0) # path 01 state is |01> up to a global phase self.assertAlmostEqual(abs((path_01[1]**2)), 1) self.assertEqual(path_01[0], 0) self.assertEqual(path_01[2], 0) self.assertEqual(path_01[3], 0) # path 10 state is |00> up to a global phase self.assertAlmostEqual(abs((path_10[0]**2)), 1) self.assertEqual(path_10[1], 0) self.assertEqual(path_10[2], 0) self.assertEqual(path_10[3], 0) # path 01 state is -|01> up to a global phase self.assertAlmostEqual(abs((path_11[1]**2)), 1) self.assertEqual(path_11[0], 0) self.assertEqual(path_11[2], 0) self.assertEqual(path_11[3], 0)