def test_number_sz_restricted_spectra_match_molecule(self): hamiltonian_fop = get_fermion_operator(self.molecular_hamiltonian) sparse_ham_number_sz_preserving = get_number_preserving_sparse_operator( hamiltonian_fop, self.molecule.n_qubits, self.molecule.n_electrons, spin_preserving=True) sparse_ham = get_sparse_operator(hamiltonian_fop, self.molecule.n_qubits) sparse_ham_restricted_number_sz_preserving = jw_sz_restrict_operator( sparse_ham, 0, n_electrons=self.molecule.n_electrons, n_qubits=self.molecule.n_qubits) spectrum_from_new_sparse_method = sparse_eigenspectrum( sparse_ham_number_sz_preserving) spectrum_from_old_sparse_method = sparse_eigenspectrum( sparse_ham_restricted_number_sz_preserving) spectral_deviation = numpy.amax( numpy.absolute(spectrum_from_new_sparse_method - spectrum_from_old_sparse_method)) self.assertAlmostEqual(spectral_deviation, 0.)
def test_number_restricted_spectra_match_hubbard(self): hamiltonian_fop = self.hubbard_hamiltonian sparse_ham_number_preserving = get_number_preserving_sparse_operator( hamiltonian_fop, 8, 4, spin_preserving=False) sparse_ham = get_sparse_operator(hamiltonian_fop, 8) sparse_ham_restricted_number_preserving = jw_number_restrict_operator( sparse_ham, n_electrons=4, n_qubits=8) spectrum_from_new_sparse_method = sparse_eigenspectrum( sparse_ham_number_preserving) spectrum_from_old_sparse_method = sparse_eigenspectrum( sparse_ham_restricted_number_preserving) spectral_deviation = numpy.amax(numpy.absolute( spectrum_from_new_sparse_method - spectrum_from_old_sparse_method)) self.assertAlmostEqual(spectral_deviation, 0.)
def test_apply_constraints(self): # Get norm of original operator. original_norm = 0. for term, coefficient in self.fermion_hamiltonian.terms.items(): if term != (): original_norm += abs(coefficient) # Get modified operator. modified_operator = apply_constraints(self.fermion_hamiltonian, self.n_fermions) modified_operator.compress() # Get norm of modified operator. modified_norm = 0. for term, coefficient in modified_operator.terms.items(): if term != (): modified_norm += abs(coefficient) self.assertTrue(modified_norm < original_norm) # Map both to sparse matrix under Jordan-Wigner. sparse_original = get_sparse_operator(self.fermion_hamiltonian) sparse_modified = get_sparse_operator(modified_operator) # Check spectra. sparse_original = jw_number_restrict_operator(sparse_original, self.n_fermions) sparse_modified = jw_number_restrict_operator(sparse_modified, self.n_fermions) original_spectrum = sparse_eigenspectrum(sparse_original) modified_spectrum = sparse_eigenspectrum(sparse_modified) spectral_deviation = numpy.amax( numpy.absolute(original_spectrum - modified_spectrum)) self.assertAlmostEqual(spectral_deviation, 0.) # Check expectation value. energy, wavefunction = get_ground_state(sparse_original) modified_energy = expectation(sparse_modified, wavefunction) self.assertAlmostEqual(modified_energy, energy) # Test consistency with cvxopt. scipy_operator = apply_constraints(self.fermion_hamiltonian, self.n_fermions, use_scipy=False) # Get norm. scipy_norm = 0. for term, coefficient in scipy_operator.terms.items(): if term != (): scipy_norm += abs(coefficient) self.assertAlmostEqual(scipy_norm, modified_norm)
def eigenspectrum(operator, n_qubits=None): """Compute the eigenspectrum of an operator. WARNING: This function has cubic runtime in dimension of Hilbert space operator, which might be exponential. NOTE: This function does not currently support QuadOperator and BosonOperator. Args: operator: QubitOperator, InteractionOperator, FermionOperator, PolynomialTensor, or InteractionRDM. n_qubits (int): number of qubits/modes in operator. if None, will be counted. Returns: spectrum: dense numpy array of floats giving eigenspectrum. """ if isinstance(operator, (QuadOperator, BosonOperator)): raise TypeError('Operator of invalid type.') from openfermion.transforms import get_sparse_operator from openfermion.utils import sparse_eigenspectrum sparse_operator = get_sparse_operator(operator, n_qubits) spectrum = sparse_eigenspectrum(sparse_operator) return spectrum
def eigenspectrum(operator): """Compute the eigenspectrum of an operator. WARNING: This function has cubic runtime in dimension of Hilbert space operator, which might be exponential. Args: operator: QubitOperator, InteractionOperator, FermionOperator, InteractionTensor, or InteractionRDM. Returns: eigenspectrum: dense numpy array of floats giving eigenspectrum. """ from openfermion.transforms import get_sparse_operator from openfermion.utils import sparse_eigenspectrum sparse_operator = get_sparse_operator(operator) eigenspectrum = sparse_eigenspectrum(sparse_operator) return eigenspectrum
def eigenspectrum(operator, n_qubits=None): """Compute the eigenspectrum of an operator. WARNING: This function has cubic runtime in dimension of Hilbert space operator, which might be exponential. Args: operator: QubitOperator, InteractionOperator, FermionOperator, PolynomialTensor, or InteractionRDM. n_qubits (int): number of qubits/modes in operator. if None, will be counted. Returns: spectrum: dense numpy array of floats giving eigenspectrum. """ from openfermion.transforms import get_sparse_operator from openfermion.utils import sparse_eigenspectrum sparse_operator = get_sparse_operator(operator, n_qubits) spectrum = sparse_eigenspectrum(sparse_operator) return spectrum