예제 #1
0
def ucc(geometry,
        basis="sto-3g",
        multiplicity=1,
        charge=1,
        theta_thresh=1e-7,
        pool=operator_pools.singlet_GSD(),
        spin_adapt=True,
        psi4_filename="psi4_%12.12f" % random.random()):
    # {{{

    molecule = openfermion.hamiltonians.MolecularData(geometry, basis,
                                                      multiplicity)
    molecule.filename = psi4_filename
    molecule = openfermionpsi4.run_psi4(molecule,
                                        run_scf=1,
                                        run_mp2=1,
                                        run_cisd=0,
                                        run_ccsd=0,
                                        run_fci=1,
                                        delete_input=1)
    pool.init(molecule)
    print(" Basis: ", basis)

    print(' HF energy      %20.16f au' % (molecule.hf_energy))
    print(' MP2 energy     %20.16f au' % (molecule.mp2_energy))
    #print(' CISD energy    %20.16f au' %(molecule.cisd_energy))
    #print(' CCSD energy    %20.16f au' %(molecule.ccsd_energy))
    print(' FCI energy     %20.16f au' % (molecule.fci_energy))

    #Build p-h reference and map it to JW transform
    reference_ket = scipy.sparse.csc_matrix(
        openfermion.jw_configuration_state(
            list(range(0, molecule.n_electrons)),
            molecule.n_qubits)).transpose()
    reference_bra = reference_ket.transpose().conj()

    #JW transform Hamiltonian computed classically with OFPsi4
    hamiltonian_op = molecule.get_molecular_hamiltonian()
    hamiltonian = openfermion.transforms.get_sparse_operator(hamiltonian_op)

    #Thetas
    parameters = [0] * pool.n_ops

    pool.generate_SparseMatrix()

    ucc = UCC(hamiltonian, pool.spmat_ops, reference_ket, parameters)

    opt_result = scipy.optimize.minimize(ucc.energy,
                                         parameters,
                                         options={
                                             'gtol': 1e-6,
                                             'disp': True
                                         },
                                         method='BFGS',
                                         callback=ucc.callback)
    print(" Finished: %20.12f" % ucc.curr_energy)
    parameters = opt_result['x']
    for p in parameters:
        print(p)
예제 #2
0
def test():
    r = 1.5
    geometry = [('H', (0,0,1*r)), ('H', (0,0,2*r)), ('H', (0,0,3*r)), ('H', (0,0,4*r))]


    charge = 0
    spin = 0
    basis = 'sto-3g'

    [n_orb, n_a, n_b, h, g, mol, E_nuc, E_scf, C, S] = pyscf_helper.init(geometry,charge,spin,basis)

    print(" n_orb: %4i" %n_orb)
    print(" n_a  : %4i" %n_a)
    print(" n_b  : %4i" %n_b)

    sq_ham = pyscf_helper.SQ_Hamiltonian()
    sq_ham.init(h, g, C, S)
    print(" HF Energy: %12.8f" %(E_nuc + sq_ham.energy_of_determinant(range(n_a),range(n_b))))
    ehf = E_nuc + sq_ham.energy_of_determinant(range(n_a),range(n_b))
    assert(abs(ehf - -1.82913741) < 1e-7)
    fermi_ham  = sq_ham.export_FermionOperator()

    hamiltonian = openfermion.transforms.get_sparse_operator(fermi_ham)

    s2 = vqe_methods.Make_S2(n_orb)

    #build reference configuration
    occupied_list = []
    for i in range(n_a):
        occupied_list.append(i*2)
    for i in range(n_b):
        occupied_list.append(i*2+1)

    print(" Build reference state with %4i alpha and %4i beta electrons" %(n_a,n_b), occupied_list)
    reference_ket = scipy.sparse.csc_matrix(openfermion.jw_configuration_state(occupied_list, 2*n_orb)).transpose()

    [e,v] = scipy.sparse.linalg.eigsh(hamiltonian.real,1,which='SA',v0=reference_ket.todense())
    for ei in range(len(e)):
        S2 = v[:,ei].conj().T.dot(s2.dot(v[:,ei]))
        print(" State %4i: %12.8f au  <S2>: %12.8f" %(ei,e[ei]+E_nuc,S2))
    
    fermi_ham += FermionOperator((),E_nuc)
    pyscf.molden.from_mo(mol, "full.molden", sq_ham.C)

    #   Francesco, change this to singlet_GSD() if you want generalized singles and doubles
    pool = operator_pools.singlet_SD()
    pool.init(n_orb, n_occ_a=n_a, n_occ_b=n_b, n_vir_a=n_orb-n_a, n_vir_b=n_orb-n_b)

    [e,v,params] = vqe_methods.adapt_vqe(fermi_ham, pool, reference_ket, theta_thresh=1e-9)

    print(" Final ADAPT-VQE energy: %12.8f" %e)
    print(" <S^2> of final state  : %12.8f" %(v.conj().T.dot(s2.dot(v))[0,0].real))

    assert(abs(-1.99471290 - e) < 1e-7)
예제 #3
0
def old_setup(
    geometry,
    basis="sto-3g",
    multiplicity=1,  #same as george, non-degenerate orbitals
    charge=1,  #doesn't seem to matter in hamiltonian (weird)
    adapt_conver='norm',  #doesn't matter for setup, but looks like daniel used a different method to determine convergence, but only in energy-case
    adapt_thresh=1e-3,  #gradient threshold
    theta_thresh=1e-7,
    adapt_maxiter=200,  #maximum number of iterations
    pool=operator_pools.singlet_GS(
    ),  #generalized singles and doubles as default, though he's not sure if he changed it- nick seems to think that he used GS
    reference='rhf',  #is default in MolecularData anyway
    brueckner=0,  #mattered for psi4 but is 0 as default anyway
    ref_state=None,
    spin_adapt=True,
    fci_nat_orb=0,
    cisd_nat_orb=0,
    hf_stability='none',
    single_vqe=False,  #will be true in our case
    chk_ops=[],
    energy_thresh=1e-6,  #threshold for single_vqe
    fci_overlap=False,
    psi4_filename="psi4_%12.12f" % random.random()):
    # designed to set up the problem in the same way as Daniel, did have to substitute openfermionpyscf for psi4 but shouldn't make a difference
    #still need to investiage versioning for the pool init and singlet GSD methods as these require the current version of MolecularData objects to have:
    # n_orbitals (y)
    # get_n_alpha_electrons (y)
    # get_n_beta_electrons (y)
    # FermionOperator class (y)
    #    requried attributes? (~)
    #
    #
    # hermitian_conjugate function (~)
    # normal_ordered function (~)
    # {{{
    start_time = time.time()
    molecule = openfermion.hamiltonians.MolecularData(geometry, basis,
                                                      multiplicity)

    if cisd_nat_orb == 1:
        cisd = 1
    else:
        cisd = 0
    molecule = openfermionpyscf.run_pyscf(molecule, run_fci=True)
    pool.init(molecule)

    if fci_overlap == False:
        print(" Basis: ", basis)
        print(' HF energy      %20.16f au' % (molecule.hf_energy))
        #print(' MP2 energy     %20.16f au' %(molecule.mp2_energy))
        #print(' CISD energy    %20.16f au' %(molecule.cisd_energy))
        #print(' CCSD energy    %20.16f au' %(molecule.ccsd_energy))
        if brueckner == 1:
            print(' BCCD energy     %20.16f au' % (molecule.bccd_energy))
        if cisd == 1:
            print(' CISD energy     %20.16f au' % (molecule.cisd_energy))
        if reference == 'rhf':
            print(' FCI energy     %20.16f au' % (molecule.fci_energy))

    # if we are going to transform to FCI NOs, it doesn't make sense to transform to CISD NOs
    if cisd_nat_orb == 1 and fci_nat_orb == 0:
        print(' Basis transformed to the CISD natural orbitals')
    if fci_nat_orb == 1:
        print(' Basis transformed to the FCI natural orbitals')

    #Build p-h reference and map it to JW transform
    if ref_state == None:
        ref_state = list(range(0, molecule.n_electrons))

    reference_ket = scipy.sparse.csc_matrix(
        openfermion.jw_configuration_state(ref_state,
                                           molecule.n_qubits)).transpose()
    reference_bra = reference_ket.transpose().conj()

    #JW transform Hamiltonian computed classically with OFPsi4
    hamiltonian_op = molecule.get_molecular_hamiltonian()
    hamiltonian = openfermion.transforms.get_sparse_operator(hamiltonian_op)

    if fci_overlap:
        e, fci_vec = openfermion.get_ground_state(hamiltonian)
        fci_state = scipy.sparse.csc_matrix(fci_vec).transpose()
        index = scipy.sparse.find(reference_ket)[0]
        print(" Basis: ", basis)
        print(' HF energy      %20.16f au' % (molecule.hf_energy))
        if brueckner == 1:
            print(' BCCD energy     %20.16f au' % (molecule.bccd_energy))
        print(' FCI energy     %20.16f au' % e)
        print(' <FCI|HF>       %20.16f' % np.absolute(fci_vec[index]))

    print(' Orbitals')
    print(molecule.canonical_orbitals)
    #Thetas
    parameters = []

    #pool.generate_SparseMatrix()
    pool.gradient_print_thresh = theta_thresh

    ansatz_ops = []  #SQ operator strings in the ansatz
    ansatz_mat = []  #Sparse Matrices for operators in ansatz

    op_indices = []
    parameters = []
    #curr_state = 1.0*reference_ket
    curr_energy = molecule.hf_energy

    molecule = openfermion.transforms.jordan_wigner(hamiltonian_op)

    pool_list = []
    for op in pool.fermi_ops:
        pool_list.append(1j * openfermion.transforms.jordan_wigner(op))

    pool_list = PauliPool().from_openfermion_qubit_operator_list(pool_list)

    qiskit_molecule = openfermion_to_qiskit(molecule)

    return pool_list, qiskit_molecule
예제 #4
0
n_spinorbitals = int(molecule.n_orbitals*2)
print('HF energy      %20.16f au' %(molecule.hf_energy))
print('MP2 energy     %20.16f au' %(molecule.mp2_energy))
print('CISD energy    %20.16f au' %(molecule.cisd_energy))
print('CCSD energy    %20.16f au' %(molecule.ccsd_energy))
print('FCI energy     %20.16f au' %(molecule.fci_energy))

global global_der 
global global_energy  
global global_iter  
global_der = np.array([])
global_energy = 0.0 
global_iter = 0 

#Build p-h reference and map it to JW transform
reference_ket = scipy.sparse.csc_matrix(openfermion.jw_configuration_state(list(range(0,molecule.n_electrons)), molecule.n_qubits)).transpose()
reference_bra = reference_ket.transpose().conj()

#JW transform Hamiltonian computed classically with OFPsi4
tensor_hamiltonian = molecule.get_molecular_hamiltonian()
singles_hamiltonian = tensor_hamiltonian.one_body_tensor
doubles_hamiltonian = tensor_hamiltonian.two_body_tensor
hamiltonian = openfermion.transforms.get_sparse_operator(tensor_hamiltonian)

#Thetas
parameters = []

#Second_quantized operations (not Jordan-Wignered)
SQ_CC_ops = []

def ops_pqrs():
예제 #5
0
def test_lexical(geometry,
                 basis="sto-3g",
                 multiplicity=1,
                 charge=1,
                 adapt_conver='norm',
                 adapt_thresh=1e-3,
                 theta_thresh=1e-7,
                 adapt_maxiter=200,
                 pool=operator_pools.singlet_GSD(),
                 spin_adapt=True,
                 psi4_filename="psi4_%12.12f" % random.random()):
    # {{{

    molecule = openfermion.hamiltonians.MolecularData(geometry, basis,
                                                      multiplicity)
    molecule.filename = psi4_filename
    molecule = openfermionpsi4.run_psi4(molecule,
                                        run_scf=1,
                                        run_mp2=1,
                                        run_cisd=0,
                                        run_ccsd=0,
                                        run_fci=1,
                                        delete_input=1)
    pool.init(molecule)
    print(" Basis: ", basis)

    print(' HF energy      %20.16f au' % (molecule.hf_energy))
    print(' MP2 energy     %20.16f au' % (molecule.mp2_energy))
    #print(' CISD energy    %20.16f au' %(molecule.cisd_energy))
    #print(' CCSD energy    %20.16f au' %(molecule.ccsd_energy))
    print(' FCI energy     %20.16f au' % (molecule.fci_energy))

    #Build p-h reference and map it to JW transform
    reference_ket = scipy.sparse.csc_matrix(
        openfermion.jw_configuration_state(
            list(range(0, molecule.n_electrons)),
            molecule.n_qubits)).transpose()
    reference_bra = reference_ket.transpose().conj()

    #JW transform Hamiltonian computed classically with OFPsi4
    hamiltonian_op = molecule.get_molecular_hamiltonian()
    hamiltonian = openfermion.transforms.get_sparse_operator(hamiltonian_op)

    #Thetas
    parameters = []

    pool.generate_SparseMatrix()

    ansatz_ops = []  #SQ operator strings in the ansatz
    ansatz_mat = []  #Sparse Matrices for operators in ansatz

    print(" Start ADAPT-VQE algorithm")
    op_indices = []
    parameters = []
    curr_state = 1.0 * reference_ket

    print(" Now start to grow the ansatz")
    for n_iter in range(0, adapt_maxiter):

        print("\n\n\n")
        print(
            " --------------------------------------------------------------------------"
        )
        print("                         ADAPT-VQE iteration: ", n_iter)
        print(
            " --------------------------------------------------------------------------"
        )
        next_index = None
        next_deriv = 0
        curr_norm = 0

        print(" Check each new operator for coupling")
        next_term = []
        print(" Measure commutators:")
        sig = hamiltonian.dot(curr_state)
        for op_trial in range(pool.n_ops):

            opA = pool.spmat_ops[op_trial]
            com = 2 * (curr_state.transpose().conj().dot(opA.dot(sig))).real
            assert (com.shape == (1, 1))
            com = com[0, 0]
            assert (np.isclose(com.imag, 0))
            com = com.real
            opstring = ""
            for t in pool.fermi_ops[op_trial].terms:
                opstring += str(t)
                break

            if abs(com) > adapt_thresh:
                print(" %4i %40s %12.8f" % (op_trial, opstring, com))

            curr_norm += com * com
            if abs(com) > abs(next_deriv):
                next_deriv = com
                next_index = op_trial

        next_index = n_iter % pool.n_ops
        curr_norm = np.sqrt(curr_norm)

        min_options = {'gtol': theta_thresh, 'disp': False}

        max_of_com = next_deriv
        print(" Norm of <[A,H]> = %12.8f" % curr_norm)
        print(" Max  of <[A,H]> = %12.8f" % max_of_com)

        converged = False
        if adapt_conver == "norm":
            if curr_norm < adapt_thresh:
                converged = True
        else:
            print(" FAIL: Convergence criterion not defined")
            exit()

        if converged:
            print(" Ansatz Growth Converged!")
            print(" Number of operators in ansatz: ", len(ansatz_ops))
            print(" *Finished: %20.12f" % trial_model.curr_energy)
            print(" -----------Final ansatz----------- ")
            print(" %4s %40s %12s" % ("#", "Term", "Coeff"))
            for si in range(len(ansatz_ops)):
                s = ansatz_ops[si]
                opstring = ""
                for t in s.terms:
                    opstring += str(t)
                    break
                print(" %4i %40s %12.8f" % (si, opstring, parameters[si]))
            break

        print(" Add operator %4i" % next_index)
        parameters.insert(0, 0)
        ansatz_ops.insert(0, pool.fermi_ops[next_index])
        ansatz_mat.insert(0, pool.spmat_ops[next_index])

        trial_model = tUCCSD(hamiltonian, ansatz_mat, reference_ket,
                             parameters)

        opt_result = scipy.optimize.minimize(trial_model.energy,
                                             parameters,
                                             jac=trial_model.gradient,
                                             options=min_options,
                                             method='BFGS',
                                             callback=trial_model.callback)

        parameters = list(opt_result['x'])
        curr_state = trial_model.prepare_state(parameters)
        print(" Finished: %20.12f" % trial_model.curr_energy)
        print(" -----------New ansatz----------- ")
        print(" %4s %40s %12s" % ("#", "Term", "Coeff"))
        for si in range(len(ansatz_ops)):
            s = ansatz_ops[si]
            opstring = ""
            for t in s.terms:
                opstring += str(t)
                break
            print(" %4i %40s %12.8f" % (si, opstring, parameters[si]))

    return
예제 #6
0
                                    run_mp2=0,
                                    run_cisd=0,
                                    run_ccsd=0,
                                    run_fci=1,
                                    delete_input=0)
#molecule = openfermionpsi4.run_psi4(molecule, run_scf = 1, run_mp2=1, run_cisd=1, run_ccsd = 1, run_fci=1, delete_input=0)
n_spinorbitals = int(molecule.n_orbitals * 2)
print('HF energy      %20.16f au' % (molecule.hf_energy))
#print('MP2 energy     %20.16f au' %(molecule.mp2_energy))
#print('CISD energy    %20.16f au' %(molecule.cisd_energy))
#print('CCSD energy    %20.16f au' %(molecule.ccsd_energy))
print('FCI energy     %20.16f au' % (molecule.fci_energy))

#Build p-h reference and map it to JW transform
reference_ket = scipy.sparse.csc_matrix(
    openfermion.jw_configuration_state(list(range(0, molecule.n_electrons)),
                                       molecule.n_qubits)).transpose()
reference_bra = reference_ket.transpose().conj()
#JW transform Hamiltonian computed classically with OFPsi4
hamiltonian_op = molecule.get_molecular_hamiltonian()
hamiltonian = openfermion.transforms.get_sparse_operator(hamiltonian_op)
print(reference_bra.dot(hamiltonian.dot(reference_ket)))

#print(" Reference energy: %12.8f" %reference_bra.dot(hamiltonian).dot(reference_ket)[0,0].real)

#Thetas
parameters = []

#Second_quantized operations (not Jordan-Wignered)
SQ_CC_ops = []

alpha_orbs = list(range(int(n_spinorbitals / 2)))
예제 #7
0
    def __init__(self, molecule, **kwargs):
        self.ecp = kwargs.get('ecp', 'False')
        #Associate a Hamiltonian with this system
        self.molecule = molecule
        print(self.ecp)
        if self.ecp == 'False':
            self.hamiltonian = molecule.get_molecular_hamiltonian()
        else:
            core = list(range(0, int(self.ecp)))
            valence = list(range(int(self.ecp), self.n_orbitals))
            self.hamiltonian = molecule.get_molecular_hamiltonian(
                occupied_indices=core, active_indices=valence)

            wfile = open('CASCI.out', 'a')
            print('Hi')
            eigs = ((np.linalg.eigh(self.hamiltonian))[0])
            print(eigs)
            wfile.write(str(sorted(eigs)[0]) + '\n')
            exit()

        self.two_index_hamiltonian = self.hamiltonian.one_body_tensor
        self.four_index_hamiltonian = self.hamiltonian.two_body_tensor
        self.JW_hamiltonian = openfermion.transforms.get_sparse_operator(
            self.hamiltonian)

        #Construct spaces
        self.aoccs = [
            i for i in range(0, self.molecule.n_electrons) if i % 2 == 0
        ]
        self.anoccs = [
            i for i in range(self.molecule.n_electrons,
                             self.molecule.n_orbitals * 2) if i % 2 == 0
        ]
        self.boccs = [
            i for i in range(0, self.molecule.n_electrons) if i % 2 == 1
        ]
        self.bnoccs = [
            i for i in range(self.molecule.n_electrons,
                             self.molecule.n_orbitals * 2) if i % 2 == 1
        ]
        self.alphas = self.aoccs + self.anoccs
        self.betas = self.boccs + self.bnoccs

        #Construct reference ket
        self.HF_ket = scipy.sparse.csc_matrix(
            openfermion.jw_configuration_state(
                list(range(0, molecule.n_electrons)),
                molecule.n_qubits)).transpose()

        #Parse kwargs
        self.include_pqrs = kwargs.get('include_pqrs', 'False')
        self.screen_commutators = kwargs.get('screen_commutators', 'False')
        self.sort = kwargs.get('sort', None)
        self.spin_adapt = kwargs.get('spin_adapt', 'False')

        #Initialize op list
        self.SQ_Singles = []
        self.SQ_Doubles = []
        self.Singles = []
        self.Doubles = []
        self.Full_JW_Ops = []

        #Get unfiltered list
        if self.include_pqrs == 'True':
            self.PQRS()
        else:
            self.IJAB()

        self.Full_Ops = self.Singles + self.Doubles
        self.Full_SQ_Ops = self.SQ_Singles + self.SQ_Doubles

        #Spin adapt
        if self.spin_adapt == 'True':
            print('Spin adapting operators...')
            self.Spin_Adapt()
        print(self.Full_Ops)

        for op in self.Full_SQ_Ops:
            op = openfermion.normal_ordered(op)
            if op.many_body_order() > 0:
                self.Full_JW_Ops.append(
                    (1 / np.sqrt(2)) *
                    openfermion.transforms.get_sparse_operator(
                        op, n_qubits=self.molecule.n_qubits))
        #Apply filters
        if self.screen_commutators == 'True':
            print('Screening by commutators with Hamiltonian (HF ansatz)...')
            self.Screen_Commutators()

        #Apply sorting method
        if self.sort == None:
            print('Operators not sorted!')
            pass
        elif self.sort == 'commutators':
            print('Sorting operators by increasing commutators...')
            self.Sort_Commutators()
        else:
            print('Sorting operators by seed ' + str(self.sort) + '...')
            self.Sort_Random(self.sort)
예제 #8
0
    hamiltonian = openfermion.transforms.get_sparse_operator(fermi_ham)

    s2 = Make_S2(n_orb)

    #build reference configuration
    occupied_list = []
    for i in range(n_a):
        occupied_list.append(i * 2)
    for i in range(n_b):
        occupied_list.append(i * 2 + 1)

    print(
        " Build reference state with %4i alpha and %4i beta electrons" %
        (n_a, n_b), occupied_list)
    reference_ket = scipy.sparse.csc_matrix(
        openfermion.jw_configuration_state(occupied_list,
                                           2 * n_orb)).transpose()

    [e, v] = scipy.sparse.linalg.eigsh(hamiltonian.real,
                                       1,
                                       which='SA',
                                       v0=reference_ket.todense())
    for ei in range(len(e)):
        S2 = v[:, ei].conj().T.dot(s2.dot(v[:, ei]))
        print(" State %4i: %12.8f au  <S2>: %12.8f" % (ei, e[ei] + E_nuc, S2))
    fermi_ham += FermionOperator((), E_nuc)
    pyscf.molden.from_mo(mol, "full.molden", sq_ham.C)

    pool = operator_pools.singlet_SD()
    pool.init(n_orb,
              n_occ_a=n_a,
              n_occ_b=n_b,