def get_new_operator_list(self, term_list, term_e_list, current_ops,
                              current_circuit):

        kwargs = {'hp': term_list, 'he': term_e_list}
        Ha_max_sq = -10000
        for i, op in enumerate(self._operator_pool.pool):
            new_ha, new_hc = get_Ha_Hc(op, **kwargs)
            new_ha_sq = new_ha**2
            if new_ha_sq > Ha_max_sq:
                Ha_max_sq = new_ha_sq
                Ha_max_index = i
                best_op = op
                best_op_Ha_list = [new_ha]
                best_op_Hc_list = [new_hc]
                best_op_list = [op.print_details()[:op.num_qubits]]
            if new_ha_sq == Ha_max_sq:
                Ha_max_sq = new_ha_sq
                Ha_max_index = i
                best_op = op
                best_op_Ha_list.append(new_ha)
                best_op_Hc_list.append(new_hc)
                best_op_list.append(op.print_details()[:op.num_qubits])

        pool_copy = deepcopy(self._operator_pool)
        op_list = []
        for op in self._operator_pool.pool:
            if op.print_details()[:op.num_qubits] not in best_op_list:
                op_list.append(op.print_details()[:op.num_qubits])

        self._operator_pool = PauliPool.from_pauli_strings(op_list)

        grads, max_grad, evals = self._compute_gradients(current_circuit)
        self._coms = None
        max_grad = -100000
        print('good grads')
        for i, grad in enumerate(grads):
            print('grad', grad[0])
            print('max grad', max_grad)
            if abs(grad[0]) > max_grad:
                max_grad = abs(grad[0])
                index = i
        new_op = self._operator_pool.pool[i]

        self._operator_pool = PauliPool.from_pauli_strings(best_op_list)
        grads, max_grad, evals = self._compute_gradients(current_circuit)
        print('bad grads')
        for i, grad in enumerate(grads):
            print(grad[0])

        self._operator_pool = pool_copy

        return current_ops + [new_op]
    def get_new_operator_list(self, term_list, term_e_list, current_ops,
                              current_circuit):

        kwargs = {'hp': term_list, 'he': term_e_list}
        Ha_max_sq = -10000
        for i, op in enumerate(self._operator_pool.pool):
            if op.print_details()[:op.num_qubits] != current_ops[
                    -1].print_details()[:op.num_qubits]:
                new_ha, new_hc = get_Ha_Hc(op, **kwargs)
                new_ha_sq = new_ha**2
                if new_ha_sq > Ha_max_sq:
                    Ha_max_sq = new_ha_sq
                    Ha_max_index = i
                    best_op = op
                    best_op_Ha_list = [new_ha]
                    best_op_Hc_list = [new_hc]
                    best_op_list = [op.print_details()[:op.num_qubits]]
                if new_ha_sq == Ha_max_sq:
                    Ha_max_sq = new_ha_sq
                    Ha_max_index = i
                    best_op = op
                    best_op_Ha_list.append(new_ha)
                    best_op_Hc_list.append(new_hc)
                    best_op_list.append(op.print_details()[:op.num_qubits])
        pool_copy = deepcopy(self._operator_pool)

        self._operator_pool = PauliPool.from_pauli_strings(best_op_list)

        grads, max_grad, evals = self._compute_gradients(current_circuit)
        self._coms = None
        min_energy = 10000
        for i, grad in enumerate(grads):
            energy = best_op_Hc_list[i] - np.sqrt(best_op_Ha_list[i]**2 +
                                                  (grad[0]**2) / 4)
            if energy < min_energy:
                min_energy = energy
                index = i

        new_op = self._operator_pool.pool[i]

        self._operator_pool = pool_copy

        return current_ops + [new_op]
Beispiel #3
0
	#else:
	#	conn = 2
	#seed = []
	#pool = []
	#print('connectivity', conn)
	#while not pool:
	#	seed = []
	#	for i in range(0,num_qubits):
	#		seed.append(str(np.random.randint(0,4)))
	#	seed = create_term(seed, num_qubits)
	#	pool = ConjectureBasedSubset(conn, seed)
	#print(seed)
	#pool_name = pool[np.random.randint(0,len(pool)-1)]
	#print(pool_name)
	#pool = PauliPool.from_pauli_strings(pool_name)
	pool = PauliPool.from_all_pauli_strings(num_qubits) #all possible pauli strings
	#s1 = SeparableInitialStateReal(qubit_op,superop)
	#sout = s1.initialize(qi)
	#it = s1
	#it = Custom(qubit_op.num_qubits, state = 'uniform')
	#pool = PauliPool.from_pauli_strings(['YXII','IYXI','IIYX','IYIX','IIIY','IIYI'])
	#pool = PauliPool()
	#pool._num_qubits = num_qubits
	#pool._pool = generate_lie_algebra(ham)
	#pool.cast_out_even_y_paulis(True) #more efficient pool
	#pool.cast_out_higher_order_z_strings(True)
	#pool.cast_out_particle_number_violating_strings(True)
	#if enable_adapt and store_in_df:
		#adapt_data_dict['pool_name'].append(pool_name)
	#if enable_roto_2 and store_in_df:
		#adapt_roto_2_data_dict['pool_name'].append(pool_name)
Beispiel #4
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
    #ham = ham + 0.2*(counter+2)*Gen_rand_1_ham(1,num_qubits)
    #dist in distances = np.arange(0.5, 4.0, 0.1) or could do 2A
    #dist = 1.5
    dist = distance[counter]
    ham, num_particles, num_spin_orbitals, shift = get_qubit_op(dist)
    #print(ham.print_details())
    #ham = get_h_4_hamiltonian(counter*0.25 + 0.25, 2, "jw")
    #ham = retrieve_ham(counter)
    qubit_op = ham
    num_qubits = qubit_op.num_qubits

    print('num qubits', qubit_op.num_qubits)
    start = time.time()
    #pool = CompletePauliPool.from_num_qubits(num_qubits)
    #pool = PauliPool.from_all_pauli_strings(num_qubits) #all possible pauli strings
    pool = PauliPool.from_pauli_strings(
        ['YXII', 'IYXI', 'IIYX', 'IYIX', 'IIIY', 'IIYI'])
    #pool = PauliPool()
    #pool._num_qubits = num_qubits
    #pool._pool = generate_lie_algebra(ham)
    #pool.cast_out_even_y_paulis(True) #more efficient pool
    #pool.cast_out_higher_order_z_strings(True)
    #pool.cast_out_particle_number_violating_strings(True)
    gentime = time.time() - start
    print('done generating pool', gentime)
    Exact_result = ExactEigensolver(qubit_op).run()
    Exact_energy_dict['ground energy'].append(Exact_result['energy'])

    if output_to_cmd:
        print("Exact Energy", Exact_result['energy'])
    if output_to_file:
        out_file.write("Exact Energy: {}\n".format(Exact_result['energy']))