Example #1
0
    def test_model_integration_with_constant(self):
        # Compute Hamiltonian in both momentum and position space.
        length_scale = 0.7

        grid = Grid(dimensions=2, length=3, scale=length_scale)
        spinless = True

        # Include the Madelung constant in the momentum but not the position
        # Hamiltonian.
        momentum_hamiltonian = jellium_model(grid,
                                             spinless,
                                             True,
                                             include_constant=True)
        position_hamiltonian = jellium_model(grid, spinless, False)

        # Diagonalize and confirm the same energy.
        jw_momentum = jordan_wigner(momentum_hamiltonian)
        jw_position = jordan_wigner(position_hamiltonian)
        momentum_spectrum = eigenspectrum(jw_momentum)
        position_spectrum = eigenspectrum(jw_position)

        # Confirm momentum spectrum is shifted 2.8372 / length_scale higher.
        max_difference = numpy.amax(momentum_spectrum - position_spectrum)
        min_difference = numpy.amax(momentum_spectrum - position_spectrum)
        self.assertAlmostEqual(max_difference, 2.8372 / length_scale)
        self.assertAlmostEqual(min_difference, 2.8372 / length_scale)
Example #2
0
    def test_bk_jw_majoranas(self):
        # Check if the Majorana operators have the same spectrum
        # irrespectively of the transform.
        n_qubits = 7

        a = FermionOperator(((1, 0), ))
        a_dag = FermionOperator(((1, 1), ))

        c = a + a_dag
        d = 1j * (a_dag - a)

        c_spins = [jordan_wigner(c), bravyi_kitaev(c)]
        d_spins = [jordan_wigner(d), bravyi_kitaev(d)]

        c_sparse = [
            get_sparse_operator(c_spins[0]),
            get_sparse_operator(c_spins[1])
        ]
        d_sparse = [
            get_sparse_operator(d_spins[0]),
            get_sparse_operator(d_spins[1])
        ]

        c_spectrum = [eigenspectrum(c_spins[0]), eigenspectrum(c_spins[1])]
        d_spectrum = [eigenspectrum(d_spins[0]), eigenspectrum(d_spins[1])]

        self.assertAlmostEqual(
            0., numpy.amax(numpy.absolute(d_spectrum[0] - d_spectrum[1])))
Example #3
0
def get_interaction_rdm(qubit_operator, n_qubits=None):
    """Build an InteractionRDM from measured qubit operators.

    Returns: An InteractionRDM object.
    """
    # Avoid circular import.
    from fermilib.transforms import jordan_wigner
    if n_qubits is None:
        n_qubits = count_qubits(qubit_operator)
    one_rdm = numpy.zeros((n_qubits, ) * 2, dtype=complex)
    two_rdm = numpy.zeros((n_qubits, ) * 4, dtype=complex)

    # One-RDM.
    for i, j in itertools.product(range(n_qubits), repeat=2):
        transformed_operator = jordan_wigner(FermionOperator(((i, 1), (j, 0))))
        for term, coefficient in iteritems(transformed_operator.terms):
            if term in qubit_operator.terms:
                one_rdm[i, j] += coefficient * qubit_operator.terms[term]

    # Two-RDM.
    for i, j, k, l in itertools.product(range(n_qubits), repeat=4):
        transformed_operator = jordan_wigner(
            FermionOperator(((i, 1), (j, 1), (k, 0), (l, 0))))
        for term, coefficient in iteritems(transformed_operator.terms):
            if term in qubit_operator.terms:
                two_rdm[i, j, k, l] += coefficient * qubit_operator.terms[term]

    return InteractionRDM(one_rdm, two_rdm)
Example #4
0
    def test_plane_wave_hamiltonian_integration(self):
        length_set = [3, 4]
        spinless_set = [True, False]
        geometry = [('H', (0, )), ('H', (0.8, ))]
        length_scale = 1.1

        for l in length_set:
            for spinless in spinless_set:
                grid = Grid(dimensions=1, scale=length_scale, length=l)
                h_plane_wave = plane_wave_hamiltonian(grid,
                                                      geometry,
                                                      spinless,
                                                      True,
                                                      include_constant=True)
                h_dual_basis = plane_wave_hamiltonian(grid, geometry, spinless,
                                                      False)
                jw_h_plane_wave = jordan_wigner(h_plane_wave)
                jw_h_dual_basis = jordan_wigner(h_dual_basis)
                h_plane_wave_spectrum = eigenspectrum(jw_h_plane_wave)
                h_dual_basis_spectrum = eigenspectrum(jw_h_dual_basis)

                max_diff = numpy.amax(h_plane_wave_spectrum -
                                      h_dual_basis_spectrum)
                min_diff = numpy.amin(h_plane_wave_spectrum -
                                      h_dual_basis_spectrum)

                self.assertAlmostEqual(max_diff, 2.8372 / length_scale)
                self.assertAlmostEqual(min_diff, 2.8372 / length_scale)
Example #5
0
 def test_identity(self):
     n_qubits = 5
     transmed_i = reverse_jordan_wigner(self.identity, n_qubits)
     expected_i = FermionOperator(())
     self.assertTrue(transmed_i.isclose(expected_i))
     retransmed_i = jordan_wigner(transmed_i)
     self.assertTrue(self.identity.isclose(retransmed_i))
    def test_jordan_wigner_position_jellium(self):
        # Parameters.
        n_dimensions = 2
        grid_length = 3
        length_scale = 1.
        spinless = 1

        # Compute fermionic Hamiltonian.
        fermion_hamiltonian = jellium_model(
            n_dimensions, grid_length, length_scale, spinless, 0)
        qubit_hamiltonian = jordan_wigner(fermion_hamiltonian)

        # Compute Jordan-Wigner Hamiltonian.
        test_hamiltonian = jordan_wigner_position_jellium(
            n_dimensions, grid_length, length_scale, spinless)

        # Make sure Hamiltonians are the same.
        self.assertTrue(test_hamiltonian.isclose(qubit_hamiltonian))

        # Check number of terms.
        n_qubits = count_qubits(qubit_hamiltonian)
        if spinless:
            paper_n_terms = 1 - .5 * n_qubits + 1.5 * (n_qubits ** 2)
        else:
            paper_n_terms = 1 - .5 * n_qubits + n_qubits ** 2

        num_nonzeros = sum(1 for coeff in qubit_hamiltonian.terms.values() if
                           coeff != 0.0)
        self.assertTrue(num_nonzeros <= paper_n_terms)
Example #7
0
    def test_jordan_wigner_dual_basis_jellium(self):
        # Parameters.
        grid = Grid(dimensions=2, length=3, scale=1.)
        spinless = True

        # Compute fermionic Hamiltonian. Include then subtract constant.
        fermion_hamiltonian = dual_basis_jellium_model(grid,
                                                       spinless,
                                                       include_constant=True)
        qubit_hamiltonian = jordan_wigner(fermion_hamiltonian)
        qubit_hamiltonian -= QubitOperator((), 2.8372)

        # Compute Jordan-Wigner Hamiltonian.
        test_hamiltonian = jordan_wigner_dual_basis_jellium(grid, spinless)

        # Make sure Hamiltonians are the same.
        self.assertTrue(test_hamiltonian.isclose(qubit_hamiltonian))

        # Check number of terms.
        n_qubits = count_qubits(qubit_hamiltonian)
        if spinless:
            paper_n_terms = 1 - .5 * n_qubits + 1.5 * (n_qubits**2)

        num_nonzeros = sum(1 for coeff in qubit_hamiltonian.terms.values()
                           if coeff != 0.0)
        self.assertTrue(num_nonzeros <= paper_n_terms)
 def setUp(self):
     self.n_qubits = 5
     self.fermion_term = FermionOperator('1^ 2^ 3 4', -3.17)
     self.fermion_operator = self.fermion_term + hermitian_conjugated(
         self.fermion_term)
     self.qubit_operator = jordan_wigner(self.fermion_operator)
     self.interaction_operator = get_interaction_operator(
         self.fermion_operator)
Example #9
0
    def test_zero(self):
        n_qubits = 5
        transmed_i = reverse_jordan_wigner(QubitOperator(), n_qubits)
        expected_i = FermionOperator()
        self.assertTrue(transmed_i.isclose(expected_i))

        retransmed_i = jordan_wigner(transmed_i)
        self.assertTrue(expected_i.isclose(retransmed_i))
Example #10
0
    def test_model_integration(self):

        # Compute Hamiltonian in both momentum and position space.
        grid = Grid(dimensions=2, length=3, scale=1.0)
        spinless = True
        momentum_hamiltonian = jellium_model(grid, spinless, True)
        position_hamiltonian = jellium_model(grid, spinless, False)

        # Diagonalize and confirm the same energy.
        jw_momentum = jordan_wigner(momentum_hamiltonian)
        jw_position = jordan_wigner(position_hamiltonian)
        momentum_spectrum = eigenspectrum(jw_momentum)
        position_spectrum = eigenspectrum(jw_position)

        # Confirm spectra are the same.
        difference = numpy.amax(
            numpy.absolute(momentum_spectrum - position_spectrum))
        self.assertAlmostEqual(difference, 0.)
Example #11
0
    def test_potential_integration(self):

        # Compute potential energy operator in momentum and position space.
        grid = Grid(dimensions=2, length=3, scale=2.)
        spinless = 1
        momentum_potential = plane_wave_potential(grid, spinless)
        position_potential = dual_basis_potential(grid, spinless)

        # Diagonalize and confirm the same energy.
        jw_momentum = jordan_wigner(momentum_potential)
        jw_position = jordan_wigner(position_potential)
        momentum_spectrum = eigenspectrum(jw_momentum)
        position_spectrum = eigenspectrum(jw_position)

        # Confirm spectra are the same.
        difference = numpy.amax(
            numpy.absolute(momentum_spectrum - position_spectrum))
        self.assertAlmostEqual(difference, 0.)
Example #12
0
    def test_kinetic_integration(self):

        # Compute kinetic energy operator in both momentum and position space.
        grid = Grid(dimensions=2, length=2, scale=3.)
        spinless = False
        momentum_kinetic = plane_wave_kinetic(grid, spinless)
        position_kinetic = dual_basis_kinetic(grid, spinless)

        # Diagonalize and confirm the same energy.
        jw_momentum = jordan_wigner(momentum_kinetic)
        jw_position = jordan_wigner(position_kinetic)
        momentum_spectrum = eigenspectrum(jw_momentum)
        position_spectrum = eigenspectrum(jw_position)

        # Confirm spectra are the same.
        difference = numpy.amax(
            numpy.absolute(momentum_spectrum - position_spectrum))
        self.assertAlmostEqual(difference, 0.)
Example #13
0
    def test_get_qubit_expectations(self):
        qubit_operator = jordan_wigner(self.hamiltonian)
        qubit_expectations = self.rdm.get_qubit_expectations(qubit_operator)

        test_energy = qubit_operator.terms[()]
        for qubit_term in qubit_expectations.terms:
            term_coefficient = qubit_operator.terms[qubit_term]
            test_energy += (term_coefficient *
                            qubit_expectations.terms[qubit_term])
        self.assertLess(abs(test_energy - self.cisd_energy), EQ_TOLERANCE)
Example #14
0
    def test_z(self):
        pauli_z = QubitOperator(((2, 'Z'), ))
        transmed_z = reverse_jordan_wigner(pauli_z)

        expected = (FermionOperator(()) + FermionOperator(
            ((2, 1), (2, 0)), -2.))
        self.assertTrue(transmed_z.isclose(expected))

        retransmed_z = jordan_wigner(transmed_z)
        self.assertTrue(pauli_z.isclose(retransmed_z))
Example #15
0
    def test_xy(self):
        xy = QubitOperator(((4, 'X'), (5, 'Y')), -2.j)
        transmed_xy = reverse_jordan_wigner(xy)
        retransmed_xy = jordan_wigner(transmed_xy)

        expected1 = -2j * (FermionOperator(((4, 1), ), 1j) - FermionOperator(
            ((4, 0), ), 1j))
        expected2 = (FermionOperator(((5, 1), )) - FermionOperator(((5, 0), )))
        expected = expected1 * expected2

        self.assertTrue(xy.isclose(retransmed_xy))
        self.assertTrue(
            normal_ordered(transmed_xy).isclose(normal_ordered(expected)))
Example #16
0
    def test_bk_jw_number_operator(self):
        # Check if number operator has the same spectrum in both
        # BK and JW representations
        n = number_operator(1, 0)
        jw_n = jordan_wigner(n)
        bk_n = bravyi_kitaev(n)

        # Diagonalize and make sure the spectra are the same.
        jw_spectrum = eigenspectrum(jw_n)
        bk_spectrum = eigenspectrum(bk_n)

        self.assertAlmostEqual(
            0., numpy.amax(numpy.absolute(jw_spectrum - bk_spectrum)))
Example #17
0
    def test_yy(self):
        yy = QubitOperator(((2, 'Y'), (3, 'Y')), 2.)
        transmed_yy = reverse_jordan_wigner(yy)
        retransmed_yy = jordan_wigner(transmed_yy)

        expected1 = -(FermionOperator(((2, 1), ), 2.) + FermionOperator(
            ((2, 0), ), 2.))
        expected2 = (FermionOperator(((3, 1), )) - FermionOperator(((3, 0), )))
        expected = expected1 * expected2

        self.assertTrue(yy.isclose(retransmed_yy))
        self.assertTrue(
            normal_ordered(transmed_yy).isclose(normal_ordered(expected)))
Example #18
0
    def test_kinetic_integration(self):

        # Compute kinetic energy operator in both momentum and position space.
        n_dimensions = 2
        grid_length = 2
        length_scale = 3.
        spinless = 0
        momentum_kinetic = momentum_kinetic_operator(
            n_dimensions, grid_length, length_scale, spinless)
        position_kinetic = position_kinetic_operator(
            n_dimensions, grid_length, length_scale, spinless)

        # Diagonalize and confirm the same energy.
        jw_momentum = jordan_wigner(momentum_kinetic)
        jw_position = jordan_wigner(position_kinetic)
        momentum_spectrum = eigenspectrum(jw_momentum)
        position_spectrum = eigenspectrum(jw_position)

        # Confirm spectra are the same.
        difference = numpy.amax(
            numpy.absolute(momentum_spectrum - position_spectrum))
        self.assertAlmostEqual(difference, 0.)
Example #19
0
    def test_model_integration(self):

        # Compute Hamiltonian in both momentum and position space.
        n_dimensions = 2
        grid_length = 3
        length_scale = 1.
        spinless = 1
        momentum_hamiltonian = jellium_model(
            n_dimensions, grid_length, length_scale, spinless, 1)
        position_hamiltonian = jellium_model(
            n_dimensions, grid_length, length_scale, spinless, 0)

        # Diagonalize and confirm the same energy.
        jw_momentum = jordan_wigner(momentum_hamiltonian)
        jw_position = jordan_wigner(position_hamiltonian)
        momentum_spectrum = eigenspectrum(jw_momentum)
        position_spectrum = eigenspectrum(jw_position)

        # Confirm spectra are the same.
        difference = numpy.amax(
            numpy.absolute(momentum_spectrum - position_spectrum))
        self.assertAlmostEqual(difference, 0.)
Example #20
0
    def test_bk_jw_number_operator_scaled(self):
        # Check if number operator has the same spectrum in both
        # JW and BK representations
        n_qubits = 1
        n = number_operator(n_qubits, 0, coefficient=2)  # eigenspectrum (0,2)
        jw_n = jordan_wigner(n)
        bk_n = bravyi_kitaev(n)

        # Diagonalize and make sure the spectra are the same.
        jw_spectrum = eigenspectrum(jw_n)
        bk_spectrum = eigenspectrum(bk_n)

        self.assertAlmostEqual(
            0., numpy.amax(numpy.absolute(jw_spectrum - bk_spectrum)))
Example #21
0
    def test_bk_jw_hopping_operator(self):
        # Check if the spectrum fits for a single hoppping operator
        n_qubits = 5
        ho = FermionOperator(((1, 1), (4, 0))) + FermionOperator(
            ((4, 1), (1, 0)))
        jw_ho = jordan_wigner(ho)
        bk_ho = bravyi_kitaev(ho)

        # Diagonalize and make sure the spectra are the same.
        jw_spectrum = eigenspectrum(jw_ho)
        bk_spectrum = eigenspectrum(bk_ho)

        self.assertAlmostEqual(
            0., numpy.amax(numpy.absolute(jw_spectrum - bk_spectrum)))
Example #22
0
    def test_xx(self):
        xx = QubitOperator(((3, 'X'), (4, 'X')), 2.)
        transmed_xx = reverse_jordan_wigner(xx)
        retransmed_xx = jordan_wigner(transmed_xx)

        expected1 = (FermionOperator(((3, 1), ), 2.) - FermionOperator(
            ((3, 0), ), 2.))
        expected2 = (FermionOperator(((4, 1), ), 1.) + FermionOperator(
            ((4, 0), ), 1.))
        expected = expected1 * expected2

        self.assertTrue(xx.isclose(retransmed_xx))
        self.assertTrue(
            normal_ordered(transmed_xx).isclose(normal_ordered(expected)))
Example #23
0
    def test_yx(self):
        yx = QubitOperator(((0, 'Y'), (1, 'X')), -0.5)
        transmed_yx = reverse_jordan_wigner(yx)
        retransmed_yx = jordan_wigner(transmed_yx)

        expected1 = 1j * (FermionOperator(((0, 1), )) + FermionOperator(
            ((0, 0), )))
        expected2 = -0.5 * (FermionOperator(((1, 1), )) + FermionOperator(
            ((1, 0), )))
        expected = expected1 * expected2

        self.assertTrue(yx.isclose(retransmed_yx))
        self.assertTrue(
            normal_ordered(transmed_yx).isclose(normal_ordered(expected)))
Example #24
0
    def test_u_operator_integration(self):
        n_dimensions = 1
        length_scale = 1
        grid_length = 3
        spinless_set = [True, False]
        nuclear_charges = numpy.empty((3))
        nuclear_charges[0] = 1
        nuclear_charges[1] = -3
        nuclear_charges[2] = 2
        for spinless in spinless_set:
            u_plane_wave = plane_wave_u_operator(
                n_dimensions, grid_length, length_scale, nuclear_charges,
                spinless)
            u_dual_basis = dual_basis_u_operator(
                n_dimensions, grid_length, length_scale, nuclear_charges,
                spinless)
            jw_u_plane_wave = jordan_wigner(u_plane_wave)
            jw_u_dual_basis = jordan_wigner(u_dual_basis)
            u_plane_wave_spectrum = eigenspectrum(jw_u_plane_wave)
            u_dual_basis_spectrum = eigenspectrum(jw_u_dual_basis)

            diff = numpy.amax(numpy.absolute(
                u_plane_wave_spectrum - u_dual_basis_spectrum))
            self.assertAlmostEqual(diff, 0)
Example #25
0
    def test_jordan_wigner_dual_basis_hamiltonian(self):
        grid = Grid(dimensions=2, length=3, scale=1.)
        spinless = True
        geometry = [('H', (0, 0)), ('H', (0.5, 0.8))]

        fermion_hamiltonian = plane_wave_hamiltonian(grid,
                                                     geometry,
                                                     spinless,
                                                     False,
                                                     include_constant=True)
        qubit_hamiltonian = jordan_wigner(fermion_hamiltonian)

        test_hamiltonian = jordan_wigner_dual_basis_hamiltonian(
            grid, geometry, spinless, include_constant=True)
        self.assertTrue(test_hamiltonian.isclose(qubit_hamiltonian))
Example #26
0
    def test_qubit_jw_fermion_integration(self):

        # Initialize a random fermionic operator.
        fermion_operator = FermionOperator(((3, 1), (2, 1), (1, 0), (0, 0)),
                                           -4.3)
        fermion_operator += FermionOperator(((3, 1), (1, 0)), 8.17)
        fermion_operator += 3.2 * FermionOperator()

        # Map to qubits and compare matrix versions.
        qubit_operator = jordan_wigner(fermion_operator)
        qubit_sparse = get_sparse_operator(qubit_operator)
        qubit_spectrum = sparse_eigenspectrum(qubit_sparse)
        fermion_sparse = jordan_wigner_sparse(fermion_operator)
        fermion_spectrum = sparse_eigenspectrum(fermion_sparse)
        self.assertAlmostEqual(
            0., numpy.amax(numpy.absolute(fermion_spectrum - qubit_spectrum)))
Example #27
0
    def test_bk_jw_integration(self):
        # This is a legacy test, which was a minimal failing example when
        # optimization for hermitian operators was used.
        n_qubits = 4

        # Minimal failing example:
        fo = FermionOperator(((3, 1), ))

        jw = jordan_wigner(fo)
        bk = bravyi_kitaev(fo)

        jw_spectrum = eigenspectrum(jw)
        bk_spectrum = eigenspectrum(bk)

        self.assertAlmostEqual(
            0., numpy.amax(numpy.absolute(jw_spectrum - bk_spectrum)))
Example #28
0
    def test_bk_jw_number_operators(self):
        # Check if a number operator has the same spectrum in both
        # JW and BK representations
        n_qubits = 2
        n1 = number_operator(n_qubits, 0)
        n2 = number_operator(n_qubits, 1)
        n = n1 + n2

        jw_n = jordan_wigner(n)
        bk_n = bravyi_kitaev(n)

        # Diagonalize and make sure the spectra are the same.
        jw_spectrum = eigenspectrum(jw_n)
        bk_spectrum = eigenspectrum(bk_n)

        self.assertAlmostEqual(
            0., numpy.amax(numpy.absolute(jw_spectrum - bk_spectrum)))
Example #29
0
    def test_bk_jw_integration_original(self):
        # This is a legacy test, which was an example proposed by Ryan,
        # failing when optimization for hermitian operators was used.
        n_qubits = 5
        fermion_operator = FermionOperator(((3, 1), (2, 1), (1, 0), (0, 0)),
                                           -4.3)
        fermion_operator += FermionOperator(((3, 1), (1, 0)), 8.17)
        fermion_operator += 3.2 * FermionOperator()

        # Map to qubits and compare matrix versions.
        jw_qubit_operator = jordan_wigner(fermion_operator)
        bk_qubit_operator = bravyi_kitaev(fermion_operator)

        # Diagonalize and make sure the spectra are the same.
        jw_spectrum = eigenspectrum(jw_qubit_operator)
        bk_spectrum = eigenspectrum(bk_qubit_operator)
        self.assertAlmostEqual(0., numpy.amax(numpy.absolute(jw_spectrum -
                                                             bk_spectrum)))
Example #30
0
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 = artificial_molecular_operator(n_qubits)

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

    # Return runtime.
    runtime = end - start
    return runtime