def test_apply_spinful_fermionop(self): """ Make sure the spin-orbital reordering is working by comparing apply operation """ wfn = Wavefunction([[2, 0, 2]]) wfn.set_wfn(strategy='random') wfn.normalize() cirq_wf = to_cirq(wfn).reshape((-1, 1)) op_to_apply = FermionOperator() test_state = copy.deepcopy(wfn) test_state.set_wfn('zero') for p, q, r, s in product(range(2), repeat=4): op = FermionOperator( ((2 * p, 1), (2 * q + 1, 1), (2 * r + 1, 0), (2 * s, 0)), coefficient=numpy.random.randn()) op_to_apply += op + hermitian_conjugated(op) test_state += wfn.apply(op + hermitian_conjugated(op)) opmat = get_sparse_operator(op_to_apply, n_qubits=4).toarray() new_state_cirq = opmat @ cirq_wf # this part is because we need to pass a normalized wavefunction norm_constant = new_state_cirq.conj().T @ new_state_cirq new_state_cirq /= numpy.sqrt(norm_constant) new_state_wfn = from_cirq(new_state_cirq.flatten(), thresh=1.0E-12) new_state_wfn.scale(numpy.sqrt(norm_constant)) self.assertTrue( numpy.allclose(test_state.get_coeff((2, 0)), new_state_wfn.get_coeff((2, 0))))
def test_evolve_spinful_fermionop(self): """ Make sure the spin-orbital reordering is working by comparing time evolution """ wfn = Wavefunction([[2, 0, 2]]) wfn.set_wfn(strategy='random') wfn.normalize() cirq_wf = to_cirq(wfn).reshape((-1, 1)) op_to_apply = FermionOperator() for p, q, r, s in product(range(2), repeat=4): op = FermionOperator( ((2 * p, 1), (2 * q + 1, 1), (2 * r + 1, 0), (2 * s, 0)), coefficient=numpy.random.randn()) op_to_apply += op + hermitian_conjugated(op) opmat = get_sparse_operator(op_to_apply, n_qubits=4).toarray() dt = 0.765 new_state_cirq = scipy.linalg.expm(-1j * dt * opmat) @ cirq_wf new_state_wfn = from_cirq(new_state_cirq.flatten(), thresh=1.0E-12) test_state = wfn.time_evolve(dt, op_to_apply) self.assertTrue( numpy.allclose(test_state.get_coeff((2, 0)), new_state_wfn.get_coeff((2, 0))))
def test_cirq_interop(self): """Check the transition from a line quibit and back. """ work = numpy.random.rand(16).astype(numpy.complex128) norm = numpy.sqrt(numpy.vdot(work, work)) numpy.divide(work, norm, out=work) wfn = fqe.from_cirq(work, thresh=1.0e-7) test = fqe.to_cirq(wfn) self.assertTrue(numpy.allclose(test, work))
def test_fqe_givens(): """Test Givens Rotation evolution for correctness.""" # set up norbs = 4 n_elec = norbs sz = 0 n_qubits = 2 * norbs time = 0.126 fqe_wfn = fqe.Wavefunction([[n_elec, sz, norbs]]) fqe_wfn.set_wfn(strategy="random") ikappa = random_quadratic_hamiltonian( norbs, conserves_particle_number=True, real=False, expand_spin=False, seed=2, ) fqe_ham = RestrictedHamiltonian((ikappa.n_body_tensors[1, 0], )) u = expm(-1j * ikappa.n_body_tensors[1, 0] * time) # time-evolve final_fqe_wfn = fqe_wfn.time_evolve(time, fqe_ham) spin_ham = np.kron(ikappa.n_body_tensors[1, 0], np.eye(2)) assert of.is_hermitian(spin_ham) ikappa_spin = of.InteractionOperator( constant=0, one_body_tensor=spin_ham, two_body_tensor=np.zeros((n_qubits, n_qubits, n_qubits, n_qubits)), ) bigU = expm(-1j * of.get_sparse_operator(ikappa_spin).toarray() * time) initial_wf = fqe.to_cirq(fqe_wfn).reshape((-1, 1)) final_wf = bigU @ initial_wf final_wfn_test = fqe.from_cirq(final_wf.flatten(), 1.0e-12) assert np.allclose(final_fqe_wfn.rdm("i^ j"), final_wfn_test.rdm("i^ j")) assert np.allclose(final_fqe_wfn.rdm("i^ j^ k l"), final_wfn_test.rdm("i^ j^ k l")) final_wfn_test2 = fqe.from_cirq( evolve_wf_givens(initial_wf.copy(), u.copy()).flatten(), 1.0e-12) givens_fqe_wfn = evolve_fqe_givens(fqe_wfn, u.copy()) assert np.allclose(givens_fqe_wfn.rdm("i^ j"), final_wfn_test2.rdm("i^ j")) assert np.allclose(givens_fqe_wfn.rdm("i^ j^ k l"), final_wfn_test2.rdm("i^ j^ k l"))
def test_fermionops_tomatrix_hubbard_model(self): hubbard = fermi_hubbard(1, 4, tunneling=1.0, coulomb=2.0, periodic=False) init_wfn = Wavefunction([[2, 0, 4]]) init_wfn.set_wfn(strategy="random") # This calls fermionops_tomatrix. evolved_wfn = init_wfn.time_evolve(1.0, hubbard) # Check. wfn_cirq = to_cirq(init_wfn) unitary = scipy.linalg.expm(-1j * get_sparse_operator(hubbard)) evolved_wfn_cirq = unitary @ wfn_cirq fidelity = abs( vdot(evolved_wfn, from_cirq(evolved_wfn_cirq, thresh=1e-12)))**2 assert numpy.isclose(fidelity, 1.0)
def test_charge_charge_evolution(): norbs = 4 n_elec = norbs sz = 0 time = 0.126 fqe_wfn = fqe.Wavefunction([[n_elec, sz, norbs]]) fqe_wfn.set_wfn(strategy="random") initial_fqe_wfn = copy.deepcopy(fqe_wfn) initial_wf = fqe.to_cirq(fqe_wfn).reshape((-1, 1)) # time-evolve vij = np.random.random((norbs, norbs)) vij = vij + vij.T final_fqe_wfn = evolve_fqe_diagaonal_coulomb(initial_fqe_wfn, vij, time) test_wfn = evolve_wf_diagonal_coulomb(wf=initial_wf, vij_mat=vij, time=time) test_wfn = fqe.from_cirq(test_wfn.flatten(), 1.0e-12) assert np.allclose(final_fqe_wfn.rdm("i^ j"), test_wfn.rdm("i^ j")) assert np.allclose(final_fqe_wfn.rdm("i^ j^ k l"), test_wfn.rdm("i^ j^ k l"))
charge = 0 multiplicity = 1 molecule = of.MolecularData( geometry=geometry, basis="sto-3g", charge=charge, multiplicity=multiplicity, ) molecule.one_body_integrals = h1e molecule.two_body_integrals = np.einsum("ijlk", -2 * h2e) molecular_hamiltonian = molecule.get_molecular_hamiltonian() molecular_hamiltonian.constant = 0 ham_fop = of.get_fermion_operator(molecular_hamiltonian) ham_mat = of.get_sparse_operator(of.jordan_wigner(ham_fop)).toarray() cirq_ci = fqe.to_cirq(wfn) cirq_ci = cirq_ci.reshape((2**12, 1)) assert np.isclose(cirq_ci.conj().T @ ham_mat @ cirq_ci, ecalc) hf_idx = int("111100000000", 2) hf_idx2 = int("111001000000", 2) hf_vec = np.zeros((2**12, 1)) hf_vec2 = np.zeros((2**12, 1)) hf_vec[hf_idx, 0] = 1.0 hf_vec2[hf_idx2, 0] = 1.0 # scale diagonal so vacuum has non-zero energy ww, vv = davidsonliu(ham_mat + np.eye(ham_mat.shape[0]), 1, guess_vecs=[hf_vec, hf_vec2]) print("full mat DL ", ww.real - 1)