def qaoa_ansatz(betas, gammas, h_cost, h_driver): pq = Program() pq += [ exponentiate_commuting_pauli_sum(h_cost)(g) + exponentiate_commuting_pauli_sum(h_driver)(b) for g, b in zip(gammas, betas) ] return pq
def qaoa_ansatz(gammas, betas): """ Function that returns a QAOA ansatz program for a list of angles betas and gammas. len(betas) == len(gammas) == P for a QAOA program of order P. :param list(float) gammas: Angles over which to parameterize the cost Hamiltonian. :param list(float) betas: Angles over which to parameterize the driver Hamiltonian. :return: The QAOA ansatz program. :rtype: Program. """ return Program([exponentiate_commuting_pauli_sum(h_cost)(g) + exponentiate_commuting_pauli_sum(h_driver)(b) \ for g, b in zip(gammas, betas)])
def qaoa_ansatz(gammas, betas): """ 각도 betas와 gammas의 배열로 주어지는 QAOA 가정법(ansatz) 프로그램을 반환하는 함수. 차수(order) P인 QAOA program은 len(betas) == len(gammas) == P를 갖는다. :param list(float) gammas: 비용 해밀토니안을 매개변수화하는 각도값들의 배열. :param list(float) betas: 구동 해밀토니안을 매개변수화하는 각도값들의 배열. :return: QAOA 가정법 프로그램. :rtype: 프로그램. """ return Program([ exponentiate_commuting_pauli_sum(h_cost)(g) + exponentiate_commuting_pauli_sum(h_driver)(b) for g, b in zip(gammas, betas) ])
def test_exponentiate_commuting_pauli_sum(): q = QubitPlaceholder.register(8) pauli_sum = PauliSum( [PauliTerm('Z', q[0], 0.5), PauliTerm('Z', q[1], 0.5)]) prog = Program().inst(RZ(1., q[0])).inst(RZ(1., q[1])) result_prog = exponentiate_commuting_pauli_sum(pauli_sum)(1.) assert address_qubits(prog) == address_qubits(result_prog)
def uccsd_ansatz_circuit(packed_amplitudes, n_orbitals, n_electrons, cq=None): # TODO apply logical re-ordering to Fermionic non-parametric way too! """ This function returns a UCCSD variational ansatz with hard-coded gate angles. The number of orbitals specifies the number of qubits, the number of electrons specifies the initial HF reference state which is assumed was prepared. The packed_amplitudes input defines which gate angles to apply for each CC operation. The list cq is an optional list which specifies the qubit label ordering which is to be assumed. :param list() packed_amplitudes: amplitudes t_ij and t_ijkl of the T_1 and T_2 operators of the UCCSD ansatz :param int n_orbitals: number of *spatial* orbitals :param int n_electrons: number of electrons considered :param list() cq: list of qubit label order :return: circuit which prepares the UCCSD variational ansatz :rtype: Program """ # Fermionic UCCSD uccsd_propagator = normal_ordered( uccsd_singlet_generator(packed_amplitudes, 2 * n_orbitals, n_electrons)) qubit_operator = jordan_wigner(uccsd_propagator) # convert the fermionic propagator to a Pauli spin basis via JW, then convert to a Pyquil compatible PauliSum pyquilpauli = qubitop_to_pyquilpauli(qubit_operator) # re-order logical stuff if necessary if cq is not None: pauli_list = [PauliTerm("I", 0, 0.0)] for term in pyquilpauli.terms: new_term = term # if the QPU has a custom lattice labeling, supplied by user through a list cq, reorder the Pauli labels. if cq is not None: new_term = term.coefficient for pauli in term: new_index = cq[pauli[0]] op = pauli[1] new_term = new_term * PauliTerm(op=op, index=new_index) pauli_list.append(new_term) pyquilpauli = PauliSum(pauli_list) # create a pyquil program which performs the ansatz state preparation with angles unpacked from packed_amplitudes ansatz_prog = Program() # add each term as successive exponentials (1 single Trotter step, not taking into account commutation relations!) for commuting_set in commuting_sets(simplify_pauli_sum(pyquilpauli)): ansatz_prog += exponentiate_commuting_pauli_sum( -1j * PauliSum(commuting_set))(-1.0) return ansatz_prog
def estimateZ(A, B, N, t): absA = LA.norm(np.asarray(A), 1) absB = LA.norm(np.asarray(B), 1) A = 0.5 * (absA + absB) B = 0.5 * (absA - absB) I = PauliTerm("I", 0, coefficient=A) Z = PauliTerm("Z", 0, coefficient=B) H = (I + Z) * PauliTerm("X", 1) exponential = exponentiate_commuting_pauli_sum(H) value = 0 for i in range(N): phi = Program(X(0), H(0)) ro = phi.declare('ro', 'BIT', 1) phi += exponential(t) phi += MEASURE(1, ro[0]) if (wf_sim.wavefunction(phi).amplitudes[0] == 0): value += 1 return math.sqrt(2 * (value / N)) / (t)
def test_exponentiate_commuting_pauli_sum(): pauli_sum = PauliSum([PauliTerm('Z', 0, 0.5), PauliTerm('Z', 1, 0.5)]) prog = Program().inst(RZ(1., 0)).inst(RZ(1., 1)) result_prog = exponentiate_commuting_pauli_sum(pauli_sum)(1.) assert prog == result_prog
def dotProduct(A, B): """ calculate dot product between two boolean vectors of same length """ absA = LA.norm(np.asarray(A), 1) absB = LA.norm(np.asarray(B), 1) a = 0.5 * (absA + absB) b = 0.5 * (absA - absB) I = PauliTerm("I", 0, coefficient=a) Z = PauliTerm("Z", 0, coefficient=b) Hamil = (I + Z) * PauliTerm("X", 1) exponential = exponentiate_commuting_pauli_sum(Hamil) zeros = 0 ones = 0 while (True): #print('while..') phi = Program() phi.inst(X(0)) phi.inst(H(0)) phi.inst(exponential(0.1)) ro = phi.declare('ro', 'BIT', 1) phi += MEASURE(1, ro[0]) if (wf_sim.wavefunction(phi).amplitudes[0] == 0): psi = Program(H(1)) for index in range(len(B)): if B[index] == 1: psi = psi + CNOT(1, index + 2) psi = psi + X(1) for index in range(len(A)): if A[index] == 1: psi = psi + CNOT(1, index + 2) psi = psi + X(0) ancilla = Program(H(2 + len(A))) for index in range((len(B))): ancilla += CSWAP(2 + len(A), index, index + 1) ancilla += H(2 + len(A)) swaptest = phi + psi + ancilla ro2 = swaptest.declare('ro2', 'BIT', 1) swaptest += MEASURE(2 + len(A), ro2[0]) for i in range(2**(3 + len(A))): if (wf_sim.wavefunction(swaptest).amplitudes[i] != 0): if (i < (2**(2 + len(A)))): zeros += 1 else: ones += 1 break print('measure success') print('zeros+ones = ', zeros + ones) if (zeros + ones > 1000): print('zeors and ondes are', zeros, ones) return (zeros - ones) / (zeros + ones) break else: continue else: continue
from pyquil.paulis import ID, sX, sY, sZ from pyquil import * from pyquil.gates import H import pyquil.paulis as pl # Pauli term takes an operator "X", "Y", "Z", or "I"; a qubit to act on, and # an optional coefficient. a = 1 * ID() b = -0.75 * sX(0) * sY(1) * sZ(3) c = (5-2j) * sZ(1) * sX(2) # Construct a sum of Pauli terms. sigma = a + b + c print("sigma = {}".format(sigma)) p = Program() p.inst(pl.exponentiate_commuting_pauli_sum(sigma)) print(p)