def test_properties(self): g = Grid(dimensions=2, length=3, scale=5.0) self.assertEqual(g.num_points, 9) self.assertEqual(g.volume_scale(), 25) self.assertEqual(list(g.all_points_indices()), [ (0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2), ])
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)
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)