def test_hermiticity(self):
        n_orbitals = 5

        # Real, no spin
        iop = random_interaction_operator(n_orbitals, real=True)
        ferm_op = get_fermion_operator(iop)
        self.assertTrue(is_hermitian(ferm_op))

        # Real, spin
        iop = random_interaction_operator(n_orbitals,
                                          expand_spin=True,
                                          real=True)
        ferm_op = get_fermion_operator(iop)
        self.assertTrue(is_hermitian(ferm_op))

        # Complex, no spin
        iop = random_interaction_operator(n_orbitals, real=False)
        ferm_op = get_fermion_operator(iop)
        self.assertTrue(is_hermitian(ferm_op))

        # Complex, spin
        iop = random_interaction_operator(n_orbitals,
                                          expand_spin=True,
                                          real=False)
        ferm_op = get_fermion_operator(iop)
        self.assertTrue(is_hermitian(ferm_op))
    def test_random_operators_are_reproducible(self):
        op1 = random_diagonal_coulomb_hamiltonian(5, seed=5947)
        op2 = random_diagonal_coulomb_hamiltonian(5, seed=5947)
        numpy.testing.assert_allclose(op1.one_body, op2.one_body)
        numpy.testing.assert_allclose(op1.two_body, op2.two_body)

        op1 = random_interaction_operator(5, seed=8911)
        op2 = random_interaction_operator(5, seed=8911)
        numpy.testing.assert_allclose(op1.one_body_tensor, op2.one_body_tensor)
        numpy.testing.assert_allclose(op1.two_body_tensor, op2.two_body_tensor)

        op1 = random_quadratic_hamiltonian(5, seed=17711)
        op2 = random_quadratic_hamiltonian(5, seed=17711)
        numpy.testing.assert_allclose(op1.combined_hermitian_part,
                                      op2.combined_hermitian_part)
        numpy.testing.assert_allclose(op1.antisymmetric_part,
                                      op2.antisymmetric_part)

        op1 = random_antisymmetric_matrix(5, seed=24074)
        op2 = random_antisymmetric_matrix(5, seed=24074)
        numpy.testing.assert_allclose(op1, op2)

        op1 = random_hermitian_matrix(5, seed=56753)
        op2 = random_hermitian_matrix(5, seed=56753)
        numpy.testing.assert_allclose(op1, op2)

        op1 = random_unitary_matrix(5, seed=56486)
        op2 = random_unitary_matrix(5, seed=56486)
        numpy.testing.assert_allclose(op1, op2)
示例#3
0
    def test_consistency(self):
        """Test consistency with JW for FermionOperators."""
        # Random interaction operator
        n_qubits = 5
        iop = random_interaction_operator(n_qubits, real=False)
        op1 = jordan_wigner(iop)
        op2 = jordan_wigner(get_fermion_operator(iop))

        self.assertEqual(op1, op2)

        # Interaction operator from molecule
        geometry = [('Li', (0., 0., 0.)), ('H', (0., 0., 1.45))]
        basis = 'sto-3g'
        multiplicity = 1

        filename = os.path.join(DATA_DIRECTORY, 'H1-Li1_sto-3g_singlet_1.45')
        molecule = MolecularData(geometry,
                                 basis,
                                 multiplicity,
                                 filename=filename)
        molecule.load()

        iop = molecule.get_molecular_hamiltonian()
        op1 = jordan_wigner(iop)
        op2 = jordan_wigner(get_fermion_operator(iop))

        self.assertEqual(op1, op2)
    def test_symmetry(self):
        n_orbitals = 5

        # Real.
        iop = random_interaction_operator(n_orbitals,
                                          expand_spin=False,
                                          real=True)
        ferm_op = get_fermion_operator(iop)
        self.assertTrue(is_hermitian(ferm_op))
        two_body_coefficients = iop.two_body_tensor
        for p, q, r, s in itertools.product(range(n_orbitals), repeat=4):

            self.assertAlmostEqual(two_body_coefficients[p, q, r, s],
                                   two_body_coefficients[r, q, p, s])

            self.assertAlmostEqual(two_body_coefficients[p, q, r, s],
                                   two_body_coefficients[p, s, r, q])

            self.assertAlmostEqual(two_body_coefficients[p, q, r, s],
                                   two_body_coefficients[s, r, q, p])

            self.assertAlmostEqual(two_body_coefficients[p, q, r, s],
                                   two_body_coefficients[q, p, s, r])

            self.assertAlmostEqual(two_body_coefficients[p, q, r, s],
                                   two_body_coefficients[r, s, p, q])

            self.assertAlmostEqual(two_body_coefficients[p, q, r, s],
                                   two_body_coefficients[s, p, q, r])

            self.assertAlmostEqual(two_body_coefficients[p, q, r, s],
                                   two_body_coefficients[q, r, s, p])
 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))
示例#6
0
def random_interaction_operator_term(
    order: int,
    real: bool = True,
    seed: Optional[int] = None,
) -> 'openfermion.InteractionOperator':
    """Generates a random interaction operator with non-zero coefficients only
    on terms corresponding to the given number of unique orbitals.

    The number of orbitals is equal to the given order.

    Args:
        order: How many unique orbitals the non-zero terms should correspond to.
        real: Whether or not the coefficients should be real. Defaults to True.
        seed: The seed. If None (default), uses np.random.
    """

    n_orbitals = order

    if order > 4:
        return ops.InteractionOperator.zero(order)

    operator = random_interaction_operator(n_orbitals, real=real, seed=seed)
    operator.constant = 0

    for indices in itertools.product(range(n_orbitals), repeat=2):
        if len(set(indices)) != order:
            operator.one_body_tensor[indices] = 0

    for indices in itertools.product(range(n_orbitals), repeat=4):
        if len(set(indices)) != order:
            operator.two_body_tensor[indices] = 0

    return operator
示例#7
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
示例#8
0
 def test_consistency_for_complex_numbers(self):
     """Test consistency with JW for FermionOperators."""
     # Random interaction operator
     n_qubits = 8
     iop = random_interaction_operator(n_qubits, real=False)
     op1 = bravyi_kitaev(iop)
     op2 = bravyi_kitaev(get_fermion_operator(iop))
     self.assertEqual(op1, op2)
 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_ordered(random_operator)
 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())
示例#11
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())
 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, _ 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])
def benchmark_jordan_wigner_sparse(n_qubits):
    """Benchmark the speed at which a FermionOperator is mapped to a matrix.

    Args:
        n_qubits: The number of qubits in the example.

    Returns:
        runtime: The time in seconds that the benchmark took.
    """
    # Initialize a random FermionOperator.
    molecular_operator = random_interaction_operator(n_qubits)
    fermion_operator = get_fermion_operator(molecular_operator)

    # Map to SparseOperator class.
    start_time = time.time()
    _ = jordan_wigner_sparse(fermion_operator)
    runtime = time.time() - start_time
    return runtime
def benchmark_molecular_operator_jordan_wigner(n_qubits):
    """Test speed with which molecular operators transform to qubit operators.

    Args:
        n_qubits: The size of the molecular operator instance. Ideally, we
            would be able to transform to a qubit operator for 50 qubit
            instances in less than a minute. We are way too slow right now.

    Returns:
        runtime: The number of seconds required to make the conversion.
    """
    # Get an instance of InteractionOperator.
    molecular_operator = random_interaction_operator(n_qubits)

    # Convert to a qubit operator.
    start = time.time()
    _ = jordan_wigner(molecular_operator)
    end = time.time()

    # Return runtime.
    runtime = end - start
    return runtime
示例#15
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())