def test_phase_estimation(): phase = 0.75 precision = 4 phase_factor = np.exp(1.0j * 2 * np.pi * phase) U = np.array([[phase_factor, 0], [0, -1 * phase_factor]]) trial_prog = phase_estimation(U, precision) result_prog = Program() ro = result_prog.declare('ro', 'BIT', precision) result_prog += [H(i) for i in range(precision)] q_out = range(precision, precision + 1) for i in range(precision): if i > 0: U = np.dot(U, U) cU = controlled(U) name = "CONTROLLED-U{0}".format(2**i) result_prog.defgate(name, cU) result_prog.inst((name, i) + tuple(q_out)) result_prog += inverse_qft(range(precision)) result_prog += [MEASURE(i, ro[i]) for i in range(precision)] assert (trial_prog == result_prog)
def test_simple_inverse_qft(): trial_prog = Program() trial_prog.inst(X(0)) trial_prog = trial_prog + inverse_qft([0]) result_prog = Program().inst([X(0), H(0)]) assert trial_prog == result_prog
def test_simple_inverse_qft(): trial_prog = pq.Program() trial_prog.inst(X(0)) trial_prog = trial_prog + inverse_qft([0]) result_prog = pq.Program().inst([X(0), H(0)]) compare_progs(trial_prog, result_prog)
def test_multi_qubit_qft(): trial_prog = Program() trial_prog.inst(X(0), X(1), X(2)) trial_prog = trial_prog + inverse_qft([0, 1, 2]) result_prog = Program().inst([X(0), X(1), X(2), SWAP(0, 2), H(0), CPHASE(-1.5707963267948966, 0, 1), CPHASE(-0.7853981633974483, 0, 2), H(1), CPHASE(-1.5707963267948966, 1, 2), H(2)]) assert trial_prog == result_prog
def pea_program(ancillary_start, ancillary_num, time, H2_distance, trotter_order): """ Creates a pyquil Program for the phase estimation algorithm (PEA) :param ancillary_start: index of the first ancillary qubit. :param ancillary_num: how many ancillaries to use corresponds to precision in PEA algorithm :param time: t in exp(-iHt), where H is the Hamiltonian :param H2_distance: the distance between to H atoms in H2 molecule :return: a pyquil Program for PEA algorithm """ phase_estimation_program = Program() unitary = exp_hamiltoniantrot_H2(time, H2_distance, trotter_order) phase_estimation_program.inst(create_CRX(), create_CRZ(), create_CH()) Hadamard_ancilaries = Program() for index in range(0, ancillary_num): Hadamard_ancilaries.inst(H(ancillary_start + index)) phase_estimation_program += Hadamard_ancilaries for index in range(0, ancillary_num): cont_first_order = Program() control_program(unitary, cont_first_order, ancillary_start + index) control_unitary = repeat_program(cont_first_order, 2**index) phase_estimation_program += control_unitary ancilary_list = list( range(ancillary_start, ancillary_start + ancillary_num)) inv_qft_prog = inverse_qft(ancilary_list) phase_estimation_program += inv_qft_prog return phase_estimation_program
def phase_estimation(U: np.ndarray, accuracy: int, reg_offset: int = 0) -> Program: """ Generate a circuit for quantum phase estimation. :param U: A unitary matrix. :param accuracy: Number of bits of accuracy desired. :param reg_offset: Where to start writing measurements (default 0). :return: A Quil program to perform phase estimation. """ assert isinstance(accuracy, int) rows, cols = U.shape m = int(log2(rows)) output_qubits = range(0, accuracy) U_qubits = range(accuracy, accuracy + m) p = Program() ro = p.declare('ro', 'BIT', len(output_qubits)) # Hadamard initialization for i in output_qubits: p.inst(H(i)) # Controlled unitaries for i in output_qubits: if i > 0: U = np.dot(U, U) cU = controlled(U) name = "CONTROLLED-U{0}".format(2**i) # define the gate p.defgate(name, cU) # apply it p.inst((name, i) + tuple(U_qubits)) # Compute the QFT p = p + inverse_qft(output_qubits) # Perform the measurements for i in output_qubits: p.measure(i, ro[reg_offset + i]) return p