def test_jordan_wigner_dual_basis_hamiltonian_bad_element(self):
     grid = Grid(dimensions=3, scale=1.0, length=4)
     with self.assertRaises(ValueError):
         jordan_wigner_dual_basis_hamiltonian(grid,
                                              geometry=[('Unobtainium',
                                                         (0, 0, 0))])
 def test_plane_wave_hamiltonian_default_to_jellium_with_no_geometry(self):
     grid = Grid(dimensions=1, scale=1.0, length=4)
     self.assertTrue(plane_wave_hamiltonian(grid) == jellium_model(grid))
Exemplo n.º 3
0
 def test_equality(self):
     eq = EqualsTester(self)
     eq.make_equality_pair(lambda: Grid(dimensions=5, length=3, scale=0.5))
     eq.add_equality_group(Grid(dimensions=4, length=3, scale=0.5))
     eq.add_equality_group(Grid(dimensions=5, length=4, scale=0.5))
     eq.add_equality_group(Grid(dimensions=5, length=3, scale=0.25))
Exemplo n.º 4
0
    def test_momentum_vector(self):
        grid = Grid(dimensions=1, length=3, scale=2. * numpy.pi)
        test_output = [grid.momentum_vector(i)
                       for i in range(grid.length[0])]
        correct_output = [-1., 0, 1.]
        self.assertEqual(correct_output, test_output)

        grid = Grid(dimensions=1, length=2, scale=2. * numpy.pi)
        test_output = [grid.momentum_vector(i)
                       for i in range(grid.length[0])]
        correct_output = [-1., 0.]
        self.assertEqual(correct_output, test_output)

        grid = Grid(dimensions=1, length=11, scale=2. * numpy.pi)
        for i in range(grid.length[0]):
            self.assertAlmostEqual(
                -grid.momentum_vector(i),
                grid.momentum_vector(grid.length[0] - i - 1))

        # Test in 2D.
        grid = Grid(dimensions=2, length=3, scale=2. * numpy.pi)
        test_input = []
        test_output = []
        for i in range(3):
            for j in range(3):
                test_input += [(i, j)]
                test_output += [grid.momentum_vector((i, j))]
        correct_output = numpy.array([[-1, -1], [-1, 0], [-1, 1],
                                      [0, -1], [0, 0], [0, 1],
                                      [1, -1], [1, 0], [1, 1]])
        self.assertAlmostEqual(0., numpy.amax(test_output - correct_output))
Exemplo n.º 5
0
 def test_initialize(self):
     g1 = Grid(dimensions=3, length=3, scale=1.0)
     scale_matrix = numpy.diag([1.0] * 3)
     g2 = Grid(dimensions=3, length=(3, 3, 3), scale=scale_matrix)
     self.assertEqual(g1, g2)
Exemplo n.º 6
0
 def test_no_errors_in_call(self):
     # No exception
     _ = Grid(dimensions=1, length=1, scale=1.0)
     _ = Grid(dimensions=2, length=3, scale=0.01)
     _ = Grid(dimensions=23, length=34, scale=45.0)
 def test_plane_wave_hamiltonian_bad_element(self):
     grid = Grid(dimensions=3, scale=1.0, length=4)
     with self.assertRaises(ValueError):
         plane_wave_hamiltonian(grid, geometry=[('Unobtainium',
                                                 (0, 0, 0))])
 def test_jordan_wigner_dual_basis_hamiltonian_default_to_jellium(self):
     grid = Grid(dimensions=1, scale=1.0, length=4)
     self.assertTrue(jordan_wigner_dual_basis_hamiltonian(grid) ==
                     jordan_wigner(jellium_model(grid, plane_wave=False)))
Exemplo n.º 9
0
    def test_coefficients(self):

        # Test that the coefficients post-JW transform are as claimed in paper.
        grid = Grid(dimensions=2, length=3, scale=2.)
        spinless = 1
        n_orbitals = grid.num_points
        n_qubits = (2**(1 - spinless)) * n_orbitals
        volume = grid.volume_scale()

        # Kinetic operator.
        kinetic = dual_basis_kinetic(grid, spinless)
        qubit_kinetic = jordan_wigner(kinetic)

        # Potential operator.
        potential = dual_basis_potential(grid, spinless)
        qubit_potential = jordan_wigner(potential)

        # Check identity.
        identity = tuple()
        kinetic_coefficient = qubit_kinetic.terms[identity]
        potential_coefficient = qubit_potential.terms[identity]

        paper_kinetic_coefficient = 0.
        paper_potential_coefficient = 0.
        for indices in grid.all_points_indices():
            momenta = grid.momentum_vector(indices)
            paper_kinetic_coefficient += float(n_qubits) * momenta.dot(
                momenta) / float(4. * n_orbitals)

            if momenta.any():
                potential_contribution = -numpy.pi * float(n_qubits) / float(
                    2. * momenta.dot(momenta) * volume)
                paper_potential_coefficient += potential_contribution

        self.assertAlmostEqual(kinetic_coefficient, paper_kinetic_coefficient)
        self.assertAlmostEqual(potential_coefficient,
                               paper_potential_coefficient)

        # Check Zp.
        for p in range(n_qubits):
            zp = ((p, 'Z'), )
            kinetic_coefficient = qubit_kinetic.terms[zp]
            potential_coefficient = qubit_potential.terms[zp]

            paper_kinetic_coefficient = 0.
            paper_potential_coefficient = 0.
            for indices in grid.all_points_indices():
                momenta = grid.momentum_vector(indices)
                paper_kinetic_coefficient -= momenta.dot(momenta) / float(
                    4. * n_orbitals)

                if momenta.any():
                    potential_contribution = numpy.pi / float(
                        momenta.dot(momenta) * volume)
                    paper_potential_coefficient += potential_contribution

            self.assertAlmostEqual(kinetic_coefficient,
                                   paper_kinetic_coefficient)
            self.assertAlmostEqual(potential_coefficient,
                                   paper_potential_coefficient)

        # Check Zp Zq.
        if spinless:
            spins = [None]

        for indices_a in grid.all_points_indices():
            for indices_b in grid.all_points_indices():

                potential_coefficient = 0.
                paper_kinetic_coefficient = 0.
                paper_potential_coefficient = 0.

                position_a = grid.position_vector(indices_a)
                position_b = grid.position_vector(indices_b)
                differences = position_b - position_a

                for spin_a in spins:
                    for spin_b in spins:

                        p = grid.orbital_id(indices_a, spin_a)
                        q = grid.orbital_id(indices_b, spin_b)

                        if p == q:
                            continue

                        zpzq = ((min(p, q), 'Z'), (max(p, q), 'Z'))
                        if zpzq in qubit_potential.terms:
                            potential_coefficient = qubit_potential.terms[zpzq]

                        for indices_c in grid.all_points_indices():
                            momenta = grid.momentum_vector(indices_c)

                            if momenta.any():
                                potential_contribution = numpy.pi * numpy.cos(
                                    differences.dot(momenta)) / float(
                                        momenta.dot(momenta) * volume)
                                paper_potential_coefficient += (
                                    potential_contribution)

                        self.assertAlmostEqual(potential_coefficient,
                                               paper_potential_coefficient)
Exemplo n.º 10
0
    def __init__(self, a=7.72, n=3, n_active_el=2, n_active_orb=4):
        self.a = a
        self.n = n
        self.n_active_el = n_active_el
        self.n_active_orb = n_active_orb
        self.N_units = 4
        self.opt_energy = None
        self.opt_amplitudes = None

        species_a = 'H'
        species_b = 'Li'

        # Construct a fermion Hamiltonian
        grid = Grid(3, self.n, self.a)
        geometry = [(species_a, (0, 0, 0)), (species_a, (0, 0.5, 0.5)),
                    (species_a, (0.5, 0, 0.5)), (species_a, (0.5, 0.5, 0)),
                    (species_b, (0.5, 0.5, 0.5)), (species_b, (0.5, 0, 0)),
                    (species_b, (0, 0.5, 0)), (species_b, (0, 0, 0.5))]
        self.fermion_hamiltonian = plane_wave_hamiltonian(
            grid,
            geometry=geometry,
            spinless=False,
            plane_wave=False,
            include_constant=False,
            e_cutoff=None)

        # Freeze specified orbitals
        n_qubits = 2 * n * n * n
        n_electrons = 4 * 3 + 4 * 1

        # Determine the indices of occupied orbitals to be frozen
        if self.n == 3:
            to_fill = ((1, 1, 1), (0, 1, 1), (2, 1, 1), (1, 0, 1), (1, 2, 1),
                       (1, 1, 0), (1, 1, 2), (0, 0, 1))
        else:
            to_fill = range(n_electrons - self.n_active_el)
        to_fill_ids = []
        for s in to_fill:
            to_fill_ids.append(orbital_id(grid, s, 0))
            to_fill_ids.append(orbital_id(grid, s, 1))
        to_fill_ids = to_fill_ids[0:(n_electrons - self.n_active_el)]
        #print(to_fill_ids)
        #print('# of terms: {}'.format(len(self.fermion_hamiltonian.terms)))
        self.fermion_hamiltonian = freeze_orbitals(self.fermion_hamiltonian,
                                                   to_fill_ids)
        #print('# of terms: {}'.format(len(self.fermion_hamiltonian.terms)))

        # Freeze unoccupied orbitals
        to_freeze_ids = range(self.n_active_orb,
                              n_qubits - (n_electrons - self.n_active_el))
        #print(to_freeze_ids)
        self.fermion_hamiltonian = freeze_orbitals(self.fermion_hamiltonian,
                                                   [], to_freeze_ids)

        print('# of terms: {}'.format(len(self.fermion_hamiltonian.terms)))

        # Construct qubit Hamiltonian
        self.qubit_hamiltonian = jordan_wigner(self.fermion_hamiltonian)

        # Initialize com;iler engine
        self.compiler_engine = uccsd_trotter_engine()
Exemplo n.º 11
0
    def test_8mode_ffft_with_external_swaps_equal_expectation_values(self):
        n_qubits = 8

        grid = Grid(dimensions=1, length=n_qubits, scale=1.0)
        dual_basis = jellium_model(grid, spinless=True, plane_wave=False)
        ffft_result = normal_ordered(dual_basis)

        # Swap 01234567 to 45670123 for fourier_transform. Additionally,
        # the FFFT's ordering is 04261537, so swap 04261537 to 01234567,
        # and then 01234567 to 45670123.
        swap_mode_list = ([1, 3, 5, 2, 4, 1, 3, 5] +
                          [3, 2, 4, 1, 3, 5, 0, 2, 4, 6, 1, 3, 5, 2, 4, 3])
        for mode in swap_mode_list:
            ffft_result = swap_adjacent_fermionic_modes(ffft_result, mode)
            ffft_result = normal_ordered(ffft_result)

        ffft_result = fourier_transform(ffft_result, grid, spinless=True)
        ffft_result = normal_ordered(ffft_result)

        # After the FFFT, swap 45670123 -> 01234567.
        swap_mode_list = [3, 2, 4, 1, 3, 5, 0, 2, 4, 6, 1, 3, 5, 2, 4, 3]
        for mode in swap_mode_list:
            ffft_result = swap_adjacent_fermionic_modes(ffft_result, mode)
            ffft_result = normal_ordered(ffft_result)

        jw_dual_basis = jordan_wigner(dual_basis)
        jw_plane_wave = jordan_wigner(ffft_result)

        # Do plane wave and dual basis calculations simultaneously.
        pw_engine = MainEngine()
        pw_wavefunction = pw_engine.allocate_qureg(n_qubits)
        db_engine = MainEngine()
        db_wavefunction = db_engine.allocate_qureg(n_qubits)

        pw_engine.flush()
        db_engine.flush()

        # Choose random state.
        state = numpy.zeros(2**n_qubits, dtype=complex)
        for i in range(len(state)):
            state[i] = (random.random() *
                        numpy.exp(1j * 2 * numpy.pi * random.random()))
        state /= numpy.linalg.norm(state)

        # Put randomly chosen state in the registers.
        pw_engine.backend.set_wavefunction(state, pw_wavefunction)
        db_engine.backend.set_wavefunction(state, db_wavefunction)

        prepare_logical_state(pw_wavefunction, i)
        prepare_logical_state(db_wavefunction, i)

        All(H) | [pw_wavefunction[1], pw_wavefunction[3]]
        All(H) | [db_wavefunction[1], db_wavefunction[3]]

        ffft(db_engine, db_wavefunction, n_qubits)
        Ph(3 * numpy.pi / 4) | db_wavefunction[0]

        # Flush the engine and compute expectation values and eigenvalues.
        pw_engine.flush()
        db_engine.flush()

        plane_wave_expectation_value = (
            pw_engine.backend.get_expectation_value(jw_dual_basis,
                                                    pw_wavefunction))
        dual_basis_expectation_value = (
            db_engine.backend.get_expectation_value(jw_plane_wave,
                                                    db_wavefunction))

        All(Measure) | pw_wavefunction
        All(Measure) | db_wavefunction

        self.assertAlmostEqual(plane_wave_expectation_value,
                               dual_basis_expectation_value)
Exemplo n.º 12
0
    def test_plane_wave_period_cutoff(self):
        # TODO: After figuring out the correct formula for period cutoff for
        #     dual basis, change period_cutoff to default, and change
        #     hamiltonian_1 to a real jellium_model for real integration test.
        spinless = True

        # [[spatial dimension, fieldline dimension]]
        dims = [[2, 2], [2, 3], [3, 3]]

        for dim in dims:

            # If dim[0] == 2, get range(2, 4).
            # If dim[0] == 3, get range(2, 3).
            for length in range(2, 6 - dim[0]):
                grid = Grid(dimensions=dim[0], length=length, scale=1.0)
                period_cutoff = grid.volume_scale()**(1. / grid.dimensions)

                hamiltonian_1 = jellium_model(grid,
                                              spinless=spinless,
                                              plane_wave=True,
                                              include_constant=False,
                                              fieldlines=dim[1])
                jw_1 = jordan_wigner(hamiltonian_1)
                spectrum_1 = eigenspectrum(jw_1)

                hamiltonian_2 = jellium_model(grid,
                                              spinless=spinless,
                                              plane_wave=True,
                                              include_constant=False,
                                              e_cutoff=None,
                                              non_periodic=True,
                                              period_cutoff=period_cutoff,
                                              fieldlines=dim[1])
                jw_2 = jordan_wigner(hamiltonian_2)
                spectrum_2 = eigenspectrum(jw_2)

                max_diff = numpy.amax(numpy.absolute(spectrum_1 - spectrum_2))

                # Checks if non-periodic and periodic cases are different.
                self.assertGreater(max_diff, 0.)

                # TODO: This is only for code coverage. Remove after having real
                #     integration test.
                momentum_hamiltonian = jellium_model(
                    grid,
                    spinless=spinless,
                    plane_wave=True,
                    include_constant=False,
                    e_cutoff=None,
                    non_periodic=True,
                    period_cutoff=period_cutoff,
                    fieldlines=dim[1])
                position_hamiltonian = jellium_model(
                    grid,
                    spinless=spinless,
                    plane_wave=False,
                    include_constant=False,
                    e_cutoff=None,
                    non_periodic=True,
                    period_cutoff=period_cutoff,
                    fieldlines=dim[1])

                # Confirm they are Hermitian
                momentum_hamiltonian_operator = (
                    get_sparse_operator(momentum_hamiltonian))
                self.assertTrue(is_hermitian(momentum_hamiltonian_operator))

                position_hamiltonian_operator = (
                    get_sparse_operator(position_hamiltonian))
                self.assertTrue(is_hermitian(position_hamiltonian_operator))

                # Diagonalize.
                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.)
Exemplo n.º 13
0
    def test_coefficients(self):
        # Test that the coefficients post-JW transform are as claimed in paper.
        spinless = True
        non_periodics = [False, True]

        # [[spatial dimension, fieldline dimension]].
        dims = [[2, 2], [2, 3], [3, 3]]

        # Reference length scale where the 2D Coulomb potential is zero.
        R0 = 1e8

        for dim in dims:

            # If dim[0] == 2, get range(2, 4).
            # If dim[0] == 3, get range(2, 3).
            for length in range(2, 6 - dim[0]):
                for non_periodic in non_periodics:
                    grid = Grid(dimensions=dim[0], length=length, scale=2.)
                    n_orbitals = grid.num_points
                    n_qubits = (2**(1 - spinless)) * n_orbitals
                    volume = grid.volume_scale()
                    period_cutoff = None

                    if non_periodic:
                        period_cutoff = volume**(1. / grid.dimensions)

                    fieldlines = dim[1]

                    # Kinetic operator.
                    kinetic = dual_basis_kinetic(grid, spinless)
                    qubit_kinetic = jordan_wigner(kinetic)

                    # Potential operator.
                    potential = dual_basis_potential(
                        grid,
                        spinless,
                        non_periodic=non_periodic,
                        period_cutoff=period_cutoff,
                        fieldlines=fieldlines)
                    qubit_potential = jordan_wigner(potential)

                    # Check identity.
                    identity = tuple()
                    kinetic_coefficient = qubit_kinetic.terms[identity]
                    potential_coefficient = qubit_potential.terms[identity]

                    paper_kinetic_coefficient = 0.
                    paper_potential_coefficient = 0.
                    for indices in grid.all_points_indices():
                        momenta = grid.momentum_vector(indices)
                        momenta_squared = momenta.dot(momenta)
                        paper_kinetic_coefficient += (float(n_qubits) *
                                                      momenta_squared /
                                                      float(4. * n_orbitals))

                        if momenta.any():
                            potential_contribution = 0.

                            # 3D case.
                            if grid.dimensions == 3:
                                potential_contribution = -(
                                    numpy.pi * float(n_qubits) /
                                    float(2. * momenta_squared * volume))

                                # If non-periodic.
                                if non_periodic:
                                    correction = 1.0 - numpy.cos(
                                        period_cutoff *
                                        numpy.sqrt(momenta_squared))
                                    potential_contribution *= correction

                            # 2D case.
                            elif grid.dimensions == 2:
                                V_nu = 0.

                                # 2D Coulomb potential.
                                if fieldlines == 2:

                                    # If non-periodic.
                                    if non_periodic:
                                        Dkv = period_cutoff * numpy.sqrt(
                                            momenta_squared)
                                        V_nu = (
                                            2. * numpy.pi / momenta_squared *
                                            (Dkv *
                                             numpy.log(R0 / period_cutoff) *
                                             scipy.special.jv(1, Dkv) -
                                             scipy.special.jv(0, Dkv)))

                                    # If periodic.
                                    else:
                                        var1 = 4. / momenta_squared
                                        var2 = 0.25 * momenta_squared

                                        V_nu = 0.5 * numpy.complex128(
                                            mpmath.meijerg([[1., 1.5, 2.], []],
                                                           [[1.5], []], var1) -
                                            mpmath.meijerg(
                                                [[-0.5, 0., 0.], []],
                                                [[-0.5, 0.], [-1.]], var2))

                                # 3D Coulomb potential.
                                elif fieldlines == 3:

                                    # If non-periodic.
                                    if non_periodic:
                                        var = (-0.25 * period_cutoff**2 *
                                               momenta_squared)
                                        V_nu = numpy.complex128(
                                            2 * numpy.pi * period_cutoff *
                                            mpmath.hyp1f2(0.5, 1., 1.5, var))

                                    # If periodic.
                                    else:
                                        V_nu = (2 * numpy.pi /
                                                numpy.sqrt(momenta_squared))

                                potential_contribution = (-float(n_qubits) /
                                                          (8. * volume) * V_nu)

                            paper_potential_coefficient += potential_contribution

                    # Check if coefficients are equal.
                    self.assertAlmostEqual(kinetic_coefficient,
                                           paper_kinetic_coefficient)
                    self.assertAlmostEqual(potential_coefficient,
                                           paper_potential_coefficient)

                    # Check Zp.
                    for p in range(n_qubits):
                        zp = ((p, 'Z'), )
                        kinetic_coefficient = qubit_kinetic.terms[zp]
                        potential_coefficient = qubit_potential.terms[zp]

                        paper_kinetic_coefficient = 0.
                        paper_potential_coefficient = 0.
                        for indices in grid.all_points_indices():
                            momenta = grid.momentum_vector(indices)
                            momenta_squared = momenta.dot(momenta)
                            paper_kinetic_coefficient -= (
                                momenta_squared / float(4. * n_orbitals))

                            if momenta.any():
                                potential_contribution = 0.

                                # 3D case.
                                if grid.dimensions == 3:
                                    potential_contribution = (
                                        numpy.pi /
                                        float(momenta_squared * volume))

                                    # If non-periodic.
                                    if non_periodic:
                                        correction = 1.0 - numpy.cos(
                                            period_cutoff *
                                            numpy.sqrt(momenta_squared))
                                        potential_contribution *= correction

                                # 2D case.
                                elif grid.dimensions == 2:
                                    V_nu = 0.

                                    # 2D Coulomb potential.
                                    if fieldlines == 2:

                                        # If non-periodic.
                                        if non_periodic:
                                            Dkv = period_cutoff * numpy.sqrt(
                                                momenta_squared)
                                            V_nu = (2. * numpy.pi /
                                                    momenta_squared *
                                                    (Dkv * numpy.log(
                                                        R0 / period_cutoff) *
                                                     scipy.special.jv(1, Dkv) -
                                                     scipy.special.jv(0, Dkv)))

                                        # If periodic.
                                        else:
                                            var1 = 4. / momenta_squared
                                            var2 = 0.25 * momenta_squared

                                            V_nu = 0.5 * numpy.complex128(
                                                mpmath.meijerg(
                                                    [[1., 1.5, 2.], []],
                                                    [[1.5], []], var1) -
                                                mpmath.meijerg(
                                                    [[-0.5, 0., 0.], []],
                                                    [[-0.5, 0.], [-1.]], var2))

                                    # 3D Coulomb potential.
                                    elif fieldlines == 3:

                                        # If non-periodic.
                                        if non_periodic:
                                            var = (-0.25 * period_cutoff**2 *
                                                   momenta_squared)
                                            V_nu = numpy.complex128(
                                                2 * numpy.pi * period_cutoff *
                                                mpmath.hyp1f2(
                                                    0.5, 1., 1.5, var))

                                        # If periodic.
                                        else:
                                            V_nu = (
                                                2 * numpy.pi /
                                                numpy.sqrt(momenta_squared))

                                    potential_contribution = (1. /
                                                              (4. * volume) *
                                                              V_nu)

                                paper_potential_coefficient += potential_contribution

                        # Check if coefficients are equal.
                        self.assertAlmostEqual(kinetic_coefficient,
                                               paper_kinetic_coefficient)
                        self.assertAlmostEqual(potential_coefficient,
                                               paper_potential_coefficient)

                    # Check Zp Zq.
                    if spinless:
                        spins = [None]

                    for indices_a in grid.all_points_indices():
                        for indices_b in grid.all_points_indices():

                            potential_coefficient = 0.
                            paper_kinetic_coefficient = 0.
                            paper_potential_coefficient = 0.

                            position_a = grid.position_vector(indices_a)
                            position_b = grid.position_vector(indices_b)
                            differences = position_b - position_a

                            for spin_a in spins:
                                for spin_b in spins:

                                    p = grid.orbital_id(indices_a, spin_a)
                                    q = grid.orbital_id(indices_b, spin_b)

                                    if p == q:
                                        continue

                                    zpzq = ((min(p, q), 'Z'), (max(p, q), 'Z'))
                                    if zpzq in qubit_potential.terms:
                                        potential_coefficient = qubit_potential.terms[
                                            zpzq]

                                    for indices_c in grid.all_points_indices():
                                        momenta = grid.momentum_vector(
                                            indices_c)
                                        momenta_squared = momenta.dot(momenta)

                                        if momenta.any():
                                            potential_contribution = 0.

                                            # 3D case.
                                            if grid.dimensions == 3:
                                                potential_contribution = (
                                                    numpy.pi * numpy.cos(
                                                        differences.dot(
                                                            momenta)) /
                                                    float(momenta_squared *
                                                          volume))

                                                # If non-periodic.
                                                if non_periodic:
                                                    correction = 1.0 - numpy.cos(
                                                        period_cutoff * numpy.
                                                        sqrt(momenta_squared))
                                                    potential_contribution *= correction

                                            # 2D case.
                                            elif grid.dimensions == 2:
                                                V_nu = 0.

                                                # 2D Coulomb potential.
                                                if fieldlines == 2:

                                                    # If non-periodic.
                                                    if non_periodic:
                                                        Dkv = (
                                                            period_cutoff *
                                                            numpy.sqrt(
                                                                momenta_squared
                                                            ))
                                                        V_nu = (
                                                            2. * numpy.pi /
                                                            momenta_squared *
                                                            (Dkv * numpy.log(
                                                                R0 /
                                                                period_cutoff)
                                                             * scipy.special.
                                                             jv(1, Dkv) -
                                                             scipy.special.jv(
                                                                 0, Dkv)))

                                                    # If periodic.
                                                    else:
                                                        var1 = 4. / momenta_squared
                                                        var2 = 0.25 * momenta_squared

                                                        V_nu = 0.5 * numpy.complex128(
                                                            mpmath.meijerg([[
                                                                1., 1.5, 2.
                                                            ], []], [[1.5], []
                                                                     ], var1) -
                                                            mpmath.meijerg([[
                                                                -0.5, 0., 0.
                                                            ], []], [[
                                                                -0.5, 0.
                                                            ], [-1.]], var2))

                                                # 3D Coulomb potential.
                                                elif fieldlines == 3:

                                                    # If non-periodic.
                                                    if non_periodic:
                                                        var = -0.25 * period_cutoff**2 * momenta_squared
                                                        V_nu = numpy.complex128(
                                                            2 * numpy.pi *
                                                            period_cutoff *
                                                            mpmath.hyp1f2(
                                                                0.5, 1., 1.5,
                                                                var))

                                                    # If periodic.
                                                    else:
                                                        V_nu = 2 * numpy.pi / numpy.sqrt(
                                                            momenta_squared)

                                                potential_contribution = (
                                                    numpy.cos(
                                                        differences.dot(
                                                            momenta)) /
                                                    (4. * volume) * V_nu)

                                            paper_potential_coefficient += potential_contribution

                                    # Check if coefficients are equal.
                                    self.assertAlmostEqual(
                                        potential_coefficient,
                                        paper_potential_coefficient)