Esempio n. 1
0
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)
Esempio n. 2
0
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
Esempio n. 3
0
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)
Esempio n. 4
0
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
Esempio n. 6
0
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