コード例 #1
0
 def test_interaction_operator(self):
     for n_orbitals, real, _ in itertools.product((1, 2, 5), (True, False),
                                                  range(5)):
         operator = random_interaction_operator(n_orbitals, real=real)
         normal_ordered_operator = normal_ordered(operator)
         expected_qubit_operator = jordan_wigner(operator)
         actual_qubit_operator = jordan_wigner(normal_ordered_operator)
         assert expected_qubit_operator == actual_qubit_operator
         two_body_tensor = normal_ordered_operator.two_body_tensor
         n_orbitals = len(two_body_tensor)
         ones = numpy.ones((n_orbitals, ) * 2)
         triu = numpy.triu(ones, 1)
         shape = (n_orbitals**2, 1)
         mask = (triu.reshape(shape) * ones.reshape(shape[::-1]) +
                 ones.reshape(shape) * triu.reshape(shape[::-1])).reshape(
                     (n_orbitals, ) * 4)
         assert numpy.allclose(mask * two_body_tensor,
                               numpy.zeros((n_orbitals, ) * 4))
         for term in normal_ordered_operator:
             order = len(term) // 2
             left_term, right_term = term[:order], term[order:]
             assert all(i[1] == 1 for i in left_term)
             assert all(i[1] == 0 for i in right_term)
             assert left_term == tuple(sorted(left_term, reverse=True))
             assert right_term == tuple(sorted(right_term, reverse=True))
コード例 #2
0
 def test_hermitian_conjugated_interaction_operator(self):
     for n_orbitals, _ in itertools.product((1, 2, 5), range(5)):
         operator = random_interaction_operator(n_orbitals)
         qubit_operator = jordan_wigner(operator)
         conjugate_operator = hermitian_conjugated(operator)
         conjugate_qubit_operator = jordan_wigner(conjugate_operator)
         assert hermitian_conjugated(
             qubit_operator) == conjugate_qubit_operator
コード例 #3
0
 def test_exception(self):
     n_qubits = 6
     random_operator = get_fermion_operator(
         random_interaction_operator(n_qubits))
     bad_term = ((2, 1), (3, 1))
     random_operator += FermionOperator(bad_term)
     with self.assertRaises(OperatorSpecificationError):
         chemist_operator = chemist_ordered(random_operator)
コード例 #4
0
 def test_convert_forward_back(self):
     n_qubits = 6
     random_operator = get_fermion_operator(
         random_interaction_operator(n_qubits))
     chemist_operator = chemist_ordered(random_operator)
     normalized_chemist = normal_ordered(chemist_operator)
     difference = normalized_chemist - normal_ordered(random_operator)
     self.assertAlmostEqual(0., difference.induced_norm())
コード例 #5
0
    def test_one_body_square_decomposition(self):

        # Initialize a random two-body FermionOperator.
        n_qubits = 4
        random_operator = get_fermion_operator(
            random_interaction_operator(n_qubits, seed=17004))

        # Convert to chemist tensor.
        constant, one_body_coefficients, chemist_tensor = (
            get_chemist_two_body_coefficients(random_operator))

        # Perform decomposition.
        eigenvalues, one_body_squares, trunc_error = (
            low_rank_two_body_decomposition(chemist_tensor))

        # Build back two-body component.
        for l in range(n_qubits**2):

            # Get the squared one-body operator.
            one_body_operator = FermionOperator()
            for p, q in itertools.product(range(n_qubits), repeat=2):
                term = ((p, 1), (q, 0))
                coefficient = one_body_squares[l, p, q]
                one_body_operator += FermionOperator(term, coefficient)
            one_body_squared = one_body_operator**2

            # Get the squared one-body operator via one-body decomposition.
            density_density_matrix, basis_transformation_matrix = (
                prepare_one_body_squared_evolution(one_body_squares[l]))
            two_body_operator = FermionOperator()
            for p, q in itertools.product(range(n_qubits), repeat=2):
                term = ((p, 1), (p, 0), (q, 1), (q, 0))
                coefficient = density_density_matrix[p, q]
                two_body_operator += FermionOperator(term, coefficient)

            # Confirm that the rotations diagonalize the one-body squares.
            hopefully_diagonal = basis_transformation_matrix.dot(
                numpy.dot(
                    one_body_squares[l],
                    numpy.transpose(
                        numpy.conjugate(basis_transformation_matrix))))
            diagonal = numpy.diag(hopefully_diagonal)
            difference = hopefully_diagonal - numpy.diag(diagonal)
            self.assertAlmostEqual(0., numpy.amax(numpy.absolute(difference)))
            density_density_alternative = numpy.outer(diagonal, diagonal)
            difference = density_density_alternative - density_density_matrix
            self.assertAlmostEqual(0., numpy.amax(numpy.absolute(difference)))

            # Test spectra.
            one_body_squared_spectrum = eigenspectrum(one_body_squared)
            two_body_spectrum = eigenspectrum(two_body_operator)
            difference = two_body_spectrum - one_body_squared_spectrum
            self.assertAlmostEqual(0., numpy.amax(numpy.absolute(difference)))
コード例 #6
0
    def test_exception(self):

        # Initialize a bad FermionOperator.
        n_qubits = 4
        random_interaction = random_interaction_operator(n_qubits, seed=36229)
        random_fermion = get_fermion_operator(random_interaction)
        bad_term = ((1, 1), (2, 1))
        random_fermion += FermionOperator(bad_term)

        # Check for exception.
        with self.assertRaises(TypeError):
            fo_constant, fo_one_body_coefficients, fo_chemist_tensor = (
                get_chemist_two_body_coefficients(random_fermion))
コード例 #7
0
    def test_operator_consistency_w_spin(self):

        # Initialize a random InteractionOperator and FermionOperator.
        n_orbitals = 3
        n_qubits = 2 * n_orbitals
        random_interaction = random_interaction_operator(n_orbitals,
                                                         expand_spin=True,
                                                         real=False,
                                                         seed=8)
        random_fermion = get_fermion_operator(random_interaction)

        # Convert to chemist ordered tensor.
        one_body_correction, chemist_tensor = \
            get_chemist_two_body_coefficients(
                random_interaction.two_body_tensor, spin_basis=True)

        # Convert output to FermionOperator.
        output_operator = FermionOperator((), random_interaction.constant)

        # Convert one-body.
        one_body_coefficients = (random_interaction.one_body_tensor +
                                 one_body_correction)
        for p, q in itertools.product(range(n_qubits), repeat=2):
            term = ((p, 1), (q, 0))
            coefficient = one_body_coefficients[p, q]
            output_operator += FermionOperator(term, coefficient)

        # Convert two-body.
        for p, q, r, s in itertools.product(range(n_orbitals), repeat=4):
            coefficient = chemist_tensor[p, q, r, s]

            # Mixed spin.
            term = ((2 * p, 1), (2 * q, 0), (2 * r + 1, 1), (2 * s + 1, 0))
            output_operator += FermionOperator(term, coefficient)

            term = ((2 * p + 1, 1), (2 * q + 1, 0), (2 * r, 1), (2 * s, 0))
            output_operator += FermionOperator(term, coefficient)

            # Same spin.
            term = ((2 * p, 1), (2 * q, 0), (2 * r, 1), (2 * s, 0))
            output_operator += FermionOperator(term, coefficient)

            term = ((2 * p + 1, 1), (2 * q + 1, 0), (2 * r + 1, 1), (2 * s + 1,
                                                                     0))
            output_operator += FermionOperator(term, coefficient)

        # Check that difference is small.
        difference = normal_ordered(random_fermion - output_operator)
        self.assertAlmostEqual(0., difference.induced_norm())
コード例 #8
0
 def test_form(self):
     n_qubits = 6
     random_operator = get_fermion_operator(
         random_interaction_operator(n_qubits))
     chemist_operator = chemist_ordered(random_operator)
     for term, coefficient in chemist_operator.terms.items():
         if len(term) == 2 or not len(term):
             pass
         else:
             self.assertTrue(term[0][1])
             self.assertTrue(term[2][1])
             self.assertFalse(term[1][1])
             self.assertFalse(term[3][1])
             self.assertTrue(term[0][0] > term[2][0])
             self.assertTrue(term[1][0] > term[3][0])
コード例 #9
0
    def test_operator_consistency(self):

        # Initialize a random InteractionOperator and FermionOperator.
        n_qubits = 4
        random_interaction = random_interaction_operator(n_qubits,
                                                         real=False,
                                                         seed=34281)
        random_fermion = get_fermion_operator(random_interaction)

        # Convert to chemist ordered tensor.
        io_constant, io_one_body_coefficients, io_chemist_tensor = \
            get_chemist_two_body_coefficients(random_interaction)
        fo_constant, fo_one_body_coefficients, fo_chemist_tensor = \
            get_chemist_two_body_coefficients(random_fermion)

        # Ensure consistency between FermionOperator and InteractionOperator.
        self.assertAlmostEqual(io_constant, fo_constant)

        one_body_difference = numpy.sum(
            numpy.absolute(io_one_body_coefficients -
                           fo_one_body_coefficients))
        self.assertAlmostEqual(0., one_body_difference)

        two_body_difference = numpy.sum(
            numpy.absolute(io_chemist_tensor - fo_chemist_tensor))
        self.assertAlmostEqual(0., two_body_difference)

        # Convert output to FermionOperator.
        output_operator = FermionOperator()
        output_operator += FermionOperator((), fo_constant)

        # Convert one-body.
        for p, q in itertools.product(range(n_qubits), repeat=2):
            term = ((p, 1), (q, 0))
            coefficient = fo_one_body_coefficients[p, q]
            output_operator += FermionOperator(term, coefficient)

        # Convert two-body.
        for p, q, r, s in itertools.product(range(n_qubits), repeat=4):
            term = ((p, 1), (q, 0), (r, 1), (s, 0))
            coefficient = fo_chemist_tensor[p, q, r, s]
            output_operator += FermionOperator(term, coefficient)

        # Check that difference is small.
        difference = normal_ordered(random_fermion - output_operator)
        self.assertAlmostEqual(0., difference.induced_norm())
コード例 #10
0
    def test_operator_consistency(self):

        # Initialize a random two-body FermionOperator.
        n_qubits = 4
        random_operator = get_fermion_operator(
            random_interaction_operator(n_qubits, seed=28644))

        # Convert to chemist tensor.
        constant, one_body_coefficients, chemist_tensor = (
            get_chemist_two_body_coefficients(random_operator))

        # Build back operator constant and one-body components.
        decomposed_operator = FermionOperator((), constant)
        for p, q in itertools.product(range(n_qubits), repeat=2):
            term = ((p, 1), (q, 0))
            coefficient = one_body_coefficients[p, q]
            decomposed_operator += FermionOperator(term, coefficient)

        # Perform decomposition.
        eigenvalues, one_body_squares, trunc_error = (
            low_rank_two_body_decomposition(chemist_tensor))
        self.assertFalse(trunc_error)

        # Check for exception.
        with self.assertRaises(ValueError):
            eigenvalues, one_body_squares, trunc_error = (
                low_rank_two_body_decomposition(chemist_tensor,
                                                truncation_threshold=1.,
                                                final_rank=1))

        # Build back two-body component.
        for l in range(n_qubits**2):
            one_body_operator = FermionOperator()
            for p, q in itertools.product(range(n_qubits), repeat=2):
                term = ((p, 1), (q, 0))
                coefficient = one_body_squares[l, p, q]
                one_body_operator += FermionOperator(term, coefficient)
            decomposed_operator += eigenvalues[l] * (one_body_operator**2)

        # Test for consistency.
        difference = normal_ordered(decomposed_operator - random_operator)
        self.assertAlmostEqual(0., difference.induced_norm())
コード例 #11
0
    def test_random_operator_consistency(self):

        # Initialize a random InteractionOperator and FermionOperator.
        n_orbitals = 3
        n_qubits = 2 * n_orbitals
        random_interaction = random_interaction_operator(n_orbitals,
                                                         expand_spin=True,
                                                         real=True,
                                                         seed=8)
        random_fermion = get_fermion_operator(random_interaction)

        # Decompose.
        eigenvalues, one_body_squares, one_body_correction, error = (
            low_rank_two_body_decomposition(
                random_interaction.two_body_tensor))
        self.assertFalse(error)

        # Build back operator constant and one-body components.
        decomposed_operator = FermionOperator((), random_interaction.constant)
        one_body_coefficients = (random_interaction.one_body_tensor +
                                 one_body_correction)
        for p, q in itertools.product(range(n_qubits), repeat=2):
            term = ((p, 1), (q, 0))
            coefficient = one_body_coefficients[p, q]
            decomposed_operator += FermionOperator(term, coefficient)

        # Build back two-body component.
        for l in range(n_orbitals**2):
            one_body_operator = FermionOperator()
            for p, q in itertools.product(range(n_qubits), repeat=2):
                term = ((p, 1), (q, 0))
                coefficient = one_body_squares[l, p, q]
                one_body_operator += FermionOperator(term, coefficient)
            decomposed_operator += eigenvalues[l] * (one_body_operator**2)

        # Test for consistency.
        difference = normal_ordered(decomposed_operator - random_fermion)
        self.assertAlmostEqual(0., difference.induced_norm())