def test_ground_state_particle_nonconserving(self): """Test getting the ground state preparation circuit for a Hamiltonian that does not conserve particle number.""" for n_qubits in self.n_qubits_range: # Initialize a particle-number-conserving Hamiltonian quadratic_hamiltonian = random_quadratic_hamiltonian( n_qubits, False, True) # Compute the true ground state sparse_operator = get_sparse_operator(quadratic_hamiltonian) ground_energy, _ = get_ground_state(sparse_operator) # Obtain the circuit circuit_description, start_orbitals = ( gaussian_state_preparation_circuit(quadratic_hamiltonian)) # Initialize the starting state state = jw_configuration_state(start_orbitals, n_qubits) # Apply the circuit particle_hole_transformation = ( jw_sparse_particle_hole_transformation_last_mode(n_qubits)) for parallel_ops in circuit_description: for op in parallel_ops: if op == 'pht': state = particle_hole_transformation.dot(state) else: i, j, theta, phi = op state = jw_sparse_givens_rotation( i, j, theta, phi, n_qubits).dot(state) # Check that the state obtained using the circuit is a ground state difference = sparse_operator * state - ground_energy * state discrepancy = numpy.amax(numpy.abs(difference)) self.assertAlmostEqual(discrepancy, 0)
def test_non_particle_conserving(self): for n_qubits in self.n_qubits_range: # Initialize a particle-number-conserving Hamiltonian quadratic_hamiltonian = random_quadratic_hamiltonian( n_qubits, False) sparse_operator = get_sparse_operator(quadratic_hamiltonian) # Diagonalize the Hamiltonian using the circuit circuit_description = reversed( quadratic_hamiltonian.diagonalizing_circuit()) particle_hole_transformation = ( jw_sparse_particle_hole_transformation_last_mode(n_qubits)) for parallel_ops in circuit_description: for op in parallel_ops: if op == 'pht': gate = particle_hole_transformation else: i, j, theta, phi = op gate = jw_sparse_givens_rotation( i, j, theta, phi, n_qubits) sparse_operator = ( gate.getH().dot(sparse_operator).dot(gate)) # Check that the result is diagonal diag = scipy.sparse.diags(sparse_operator.diagonal()) difference = sparse_operator - diag discrepancy = 0. if difference.nnz: discrepancy = max(abs(difference.data)) self.assertTrue(discrepancy < EQ_TOLERANCE) # Check that the eigenvalues are in the expected order orbital_energies, constant = ( quadratic_hamiltonian.orbital_energies()) for index in range(2**n_qubits): bitstring = bin(index)[2:].zfill(n_qubits) subset = [j for j in range(n_qubits) if bitstring[j] == '1'] energy = sum([orbital_energies[j] for j in subset]) + constant self.assertAlmostEqual(sparse_operator[index, index], energy)
def test_bad_input(self): with self.assertRaises(ValueError): givens_matrix = jw_sparse_givens_rotation(0, 2, 1., 1., 5) with self.assertRaises(ValueError): givens_matrix = jw_sparse_givens_rotation(4, 5, 1., 1., 5)