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)
Example #3
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)
Example #7
0
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
        ]
Example #9
0
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)