Esempio n. 1
0
    def test_singular_values_from_theta_values_for_two_by_two_identity_matrix(
            self):
        """Tests the correct theta values (in the range [0, 1] are measured for the identity matrix.

        These theta values are 0.25 and 0.75, or 0.01 and 0.11 as binary decimals, respectively.

        The identity matrix A = [[1, 0], [0, 1]] has singular value 1 and Froebenius norm sqrt(2). It follows that

                                    sigma / ||A||_F = 1 / sqrt(2)

        Since                       cos(pi * theta) = sigma / ||A||_F,

        we must have                cos(pi * theta) = 1 / sqrt(2),

        which means that theta = - 0.25 or theta = 0.25. After mapping from the interval [-1/2, 1/2] to the interval
        [0, 1] via

                                    theta ----> theta           (if 0 <= theta <= 1 / 2)
                                    theta ----> theta + 1       (if -1 / 2 <= theta < 0)

        (which is what we measure in QSVE), the possible outcomes are thus 0.25 and 0.75. These correspond to binary
        decimals 0.01 and 0.10, respectively.

        This test does QSVE on the identity matrix using 2, 3, 4, 5, and 6 precision qubits for QPE.
        """
        # Define the identity matrix
        matrix = np.identity(2)

        # Create the QSVE instance
        qsve = QSVE(matrix)

        for nprecision_bits in [2, 3, 4, 5, 6]:
            # Get the circuit to perform QSVE with terminal measurements on the QPE register
            circuit = qsve.create_circuit(nprecision_bits=nprecision_bits,
                                          terminal_measurements=True)

            # Run the quantum circuit for QSVE
            sim = BasicAer.get_backend("qasm_simulator")
            job = execute(circuit, sim, shots=10000)

            # Get the output bit strings from QSVE
            res = job.result()
            counts = res.get_counts()
            thetas_binary = np.array(list(counts.keys()))

            # Make sure there are only two measured values
            self.assertEqual(len(thetas_binary), 2)

            # Convert the measured angles to floating point values
            thetas = [
                qsve.binary_decimal_to_float(binary_decimal, big_endian=False)
                for binary_decimal in thetas_binary
            ]
            thetas = [qsve.convert_measured(theta) for theta in thetas]

            # Make sure the theta values are correct
            self.assertEqual(len(thetas), 2)
            self.assertIn(0.25, thetas)
            self.assertIn(-0.25, thetas)
Esempio n. 2
0
    def test_singular_values_two_by_two_three_pi_over_eight_singular_vector2(
            self):
        """Tests computing the singular values of the matrix

                    A = [[cos(3 * pi / 8), 0],
                         [0, sin(3 * pi / 8)]]

        with an input singular vector. Checks that only one singular value is present in the measurement outcome.
        """
        # Define the matrix
        matrix = np.array([[np.cos(3 * np.pi / 8), 0],
                           [0, np.sin(3 * np.pi / 8)]])

        # Do the classical SVD. (Note: We could just access the singular values from the diagonal matrix elements.)
        _, sigmas, _ = np.linalg.svd(matrix)

        # Get the quantum circuit for QSVE
        for nprecision_bits in range(3, 7):
            qsve = QSVE(matrix)
            circuit = qsve.create_circuit(nprecision_bits=nprecision_bits,
                                          init_state_row_and_col=[0, 1, 0, 0],
                                          terminal_measurements=True)

            # Run the quantum circuit for QSVE
            sim = BasicAer.get_backend("qasm_simulator")
            job = execute(circuit, sim, shots=10000)

            # Get the output bit strings from QSVE
            res = job.result()
            counts = res.get_counts()
            thetas_binary = np.array(list(counts.keys()))

            # Convert from the binary strings to theta values
            computed = [
                qsve.convert_measured(qsve.binary_decimal_to_float(bits))
                for bits in thetas_binary
            ]

            # Convert from theta values to singular values
            qsigmas = [
                np.cos(np.pi * theta) for theta in computed if theta > 0
            ]

            # Sort the sigma values for comparison
            sigmas = list(sorted(sigmas))
            qsigmas = list(sorted(qsigmas))

            # Make sure the quantum solution is close to the classical solution
            self.assertTrue(np.allclose(sigmas[1], qsigmas))