def test_uccsd_singlet_builds(self): """Test specific builds of the UCCSD singlet operator""" # Build 1 n_orbitals = 4 n_electrons = 2 n_params = uccsd_singlet_paramsize(n_orbitals, n_electrons) self.assertEqual(n_params, 2) initial_amplitudes = [1., 2.] generator = uccsd_singlet_generator(initial_amplitudes, n_orbitals, n_electrons) test_generator = (FermionOperator("2^ 0", 1.) + FermionOperator("0^ 2", -1.) + FermionOperator("3^ 1", 1.) + FermionOperator("1^ 3", -1.) + FermionOperator("2^ 0 3^ 1", 4.) + FermionOperator("1^ 3 0^ 2", -4.)) self.assertEqual(normal_ordered(test_generator), normal_ordered(generator)) # Build 2 n_orbitals = 6 n_electrons = 2 n_params = uccsd_singlet_paramsize(n_orbitals, n_electrons) self.assertEqual(n_params, 5) initial_amplitudes = numpy.arange(1, n_params + 1, dtype=float) generator = uccsd_singlet_generator(initial_amplitudes, n_orbitals, n_electrons) test_generator = (FermionOperator("2^ 0", 1.) + FermionOperator("0^ 2", -1) + FermionOperator("3^ 1", 1.) + FermionOperator("1^ 3", -1.) + FermionOperator("4^ 0", 2.) + FermionOperator("0^ 4", -2) + FermionOperator("5^ 1", 2.) + FermionOperator("1^ 5", -2.) + FermionOperator("2^ 0 3^ 1", 6.) + FermionOperator("1^ 3 0^ 2", -6.) + FermionOperator("4^ 0 5^ 1", 8.) + FermionOperator("1^ 5 0^ 4", -8.) + FermionOperator("2^ 0 5^ 1", 5.) + FermionOperator("1^ 5 0^ 2", -5.) + FermionOperator("4^ 0 3^ 1", 5.) + FermionOperator("1^ 3 0^ 4", -5.) + FermionOperator("2^ 0 4^ 0", 5.) + FermionOperator("0^ 4 0^ 2", -5.) + FermionOperator("3^ 1 5^ 1", 5.) + FermionOperator("1^ 5 1^ 3", -5.)) self.assertEqual(normal_ordered(test_generator), normal_ordered(generator))
def test_uccsd_singlet_anti_hermitian(self): """Test that the singlet version is anti-Hermitian""" test_orbitals = 8 test_electrons = 4 packed_amplitude_size = uccsd_singlet_paramsize( test_orbitals, test_electrons) packed_amplitudes = randn(int(packed_amplitude_size)) generator = uccsd_singlet_generator(packed_amplitudes, test_orbitals, test_electrons) conj_generator = hermitian_conjugated(generator) self.assertEqual(generator, -1. * conj_generator)
def test_uccsd_singlet_symmetries(self): """Test that the singlet generator has the correct symmetries.""" test_orbitals = 8 test_electrons = 4 packed_amplitude_size = uccsd_singlet_paramsize( test_orbitals, test_electrons) packed_amplitudes = randn(int(packed_amplitude_size)) generator = uccsd_singlet_generator(packed_amplitudes, test_orbitals, test_electrons) # Construct symmetry operators sz = sz_operator(test_orbitals) s_squared = s_squared_operator(test_orbitals) # Check the symmetries comm_sz = normal_ordered(commutator(generator, sz)) comm_s_squared = normal_ordered(commutator(generator, s_squared)) zero = FermionOperator() self.assertEqual(comm_sz, zero) self.assertEqual(comm_s_squared, zero)
def get_energy(packed_amplitudes): fermion_generator = uccsd_singlet_generator(packed_amplitudes, 4, 2) qubit_generator = jordan_wigner(fermion_generator) qubit_generator.compress() circuit = get_circuit(packed_amplitudes, 13) # circuit = Circuit(4) # circuit.X(0) # circuit.X(1) terms = { (): -0.10973055650861605, ((0, 'Z'), ): 0.1698845202255903, ((1, 'Z'), ): 0.1698845202255903, ((2, 'Z'), ): -0.21886306765204747, ((3, 'Z'), ): -0.21886306765204747, ((0, 'Z'), (1, 'Z')): 0.1682119867202592, ((0, 'Z'), (2, 'Z')): 0.12005143070514901, ((0, 'Z'), (3, 'Z')): 0.1654943148544621, ((1, 'Z'), (2, 'Z')): 0.1654943148544621, ((1, 'Z'), (3, 'Z')): 0.12005143070514901, ((2, 'Z'), (3, 'Z')): 0.17395378774871575, ((0, 'X'), (1, 'X'), (2, 'Y'), (3, 'Y')): -0.045442884149313106, ((0, 'X'), (1, 'Y'), (2, 'Y'), (3, 'X')): 0.045442884149313106, ((0, 'Y'), (1, 'X'), (2, 'X'), (3, 'Y')): 0.045442884149313106, ((0, 'Y'), (1, 'Y'), (2, 'X'), (3, 'X')): -0.045442884149313106 } u = converter.circuit_to_unitary(circuit) start_density = np.zeros((2**n_qubits, 2**n_qubits)) start_density[0][0] = 1 end_density = u @ start_density @ u.transpose().conjugate() return sum([ terms[pauli] * get_expectation(pauli, end_density) for pauli in terms ]).real
def test_value_error_bad_amplitudes(self): with self.assertRaises(ValueError): _ = uccsd_singlet_generator([1.], 3, 4)
def test_ucc_h2_singlet(self): geometry = [('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))] basis = 'sto-3g' multiplicity = 1 filename = os.path.join(THIS_DIRECTORY, 'data', 'H2_sto-3g_singlet_0.7414') self.molecule = MolecularData(geometry, basis, multiplicity, filename=filename) self.molecule.load() # Get molecular Hamiltonian. self.molecular_hamiltonian = self.molecule.get_molecular_hamiltonian() # Get FCI RDM. self.fci_rdm = self.molecule.get_molecular_rdm(use_fci=1) # Get explicit coefficients. self.nuclear_repulsion = self.molecular_hamiltonian.constant self.one_body = self.molecular_hamiltonian.one_body_tensor self.two_body = self.molecular_hamiltonian.two_body_tensor # Get fermion Hamiltonian. self.fermion_hamiltonian = normal_ordered( get_fermion_operator(self.molecular_hamiltonian)) # Get qubit Hamiltonian. self.qubit_hamiltonian = jordan_wigner(self.fermion_hamiltonian) # Get the sparse matrix. self.hamiltonian_matrix = get_sparse_operator( self.molecular_hamiltonian) # Test UCCSD for accuracy against FCI using loaded t amplitudes. ucc_operator = uccsd_generator(self.molecule.ccsd_single_amps, self.molecule.ccsd_double_amps) hf_state = jw_hartree_fock_state(self.molecule.n_electrons, count_qubits(self.qubit_hamiltonian)) uccsd_sparse = jordan_wigner_sparse(ucc_operator) uccsd_state = scipy.sparse.linalg.expm_multiply(uccsd_sparse, hf_state) expected_uccsd_energy = expectation(self.hamiltonian_matrix, uccsd_state) self.assertAlmostEqual(expected_uccsd_energy, self.molecule.fci_energy, places=4) print("UCCSD ENERGY: {}".format(expected_uccsd_energy)) # Test CCSD singlet for precise match against FCI using loaded t # amplitudes packed_amplitudes = uccsd_singlet_get_packed_amplitudes( self.molecule.ccsd_single_amps, self.molecule.ccsd_double_amps, self.molecule.n_qubits, self.molecule.n_electrons) ccsd_operator = uccsd_singlet_generator(packed_amplitudes, self.molecule.n_qubits, self.molecule.n_electrons, anti_hermitian=False) ccsd_sparse_r = jordan_wigner_sparse(ccsd_operator) ccsd_sparse_l = jordan_wigner_sparse( -hermitian_conjugated(ccsd_operator)) ccsd_state_r = scipy.sparse.linalg.expm_multiply( ccsd_sparse_r, hf_state) ccsd_state_l = scipy.sparse.linalg.expm_multiply( ccsd_sparse_l, hf_state) expected_ccsd_energy = ccsd_state_l.conjugate().dot( self.hamiltonian_matrix.dot(ccsd_state_r)) self.assertAlmostEqual(expected_ccsd_energy, self.molecule.fci_energy)
def test_exceptions(self): # Pass odd n_qubits to singlet generators with self.assertRaises(ValueError): _ = uccsd_singlet_paramsize(3, 4) with self.assertRaises(ValueError): _ = uccsd_singlet_generator([1.], 3, 4)
qubit_hamiltonian = jordan_wigner(hamiltonian) qubit_hamiltonian.compress() if active_space == False: n_qubits = mol.n_qubits n_electrons = mol.n_electrons else: n_qubits = 2 * n_active_orbitals n_electrons = 2 * n_docc_orbitals # backend = IBMQBackend("ibmqx4") backend = AerBackend() packed_amplitudes = [-4.876143648314624e-05, 0.057384102234558684] fermion_generator = uccsd_singlet_generator(packed_amplitudes, n_qubits, n_electrons) qubit_generator = jordan_wigner(fermion_generator) qubit_generator.compress() alpha_electrons = 1 beta_electrons = 1 #qubit_generator = uccd_general_evolution(packed_amplitudes, alpha_electrons, beta_electrons, n_qubits) circ = Circuit(n_qubits) hf_wavefunction(circ, n_electrons, multiplicity) print (qubit_generator)