Esempio n. 1
0
def test_exponentiate_3cob():
    # testing circuit for 3-terms with change of basis
    generator = PauliTerm("Z", 0, 1.0) * PauliTerm("Y", 1, 1.0) * PauliTerm(
        "X", 2, 1.0)
    para_prog = exponential_map(generator)
    prog = para_prog(1)
    result_prog = Program().inst([
        RX(math.pi / 2.0, 1),
        H(2),
        CNOT(0, 1),
        CNOT(1, 2),
        RZ(2.0, 2),
        CNOT(1, 2),
        CNOT(0, 1),
        RX(-math.pi / 2.0, 1),
        H(2),
    ])
    assert prog == result_prog
Esempio n. 2
0
def construct_ansatz(theta, num_qubits, num_layers):
    '''
    Constructs the ansatz based on the example provided in the new project spec.
    '''
    theta = np.reshape(theta, (num_qubits, num_layers))

    program = Program()

    for l in range(num_layers):
        for q in range(num_qubits): # Assumes qubits are ordered

            program += RX(theta[q, l], q)
            program += RZ(theta[q, l], q)

            if (q + 1) < num_qubits:
                program += CNOT(q, q+1)

    return program
Esempio n. 3
0
def generate_t2_echo_experiments(
        qubits: Sequence[int],
        times: Sequence[float],
        detuning: float = 1e6) -> List[ObservablesExperiment]:
    """
    Return ObservablesExperiments containing programs which constitute a T2 echo experiment to
    measure the T2 echo coherence decay time.

    For each delay time in times a single program will be generated in which all qubits are
    initialized to the minusY state and later simultaneously measured along the Y axis. Unlike in
    the t2_star experiment above there is a 'echo' applied in the middle of the delay in which
    the qubit is rotated by pi radians around the Y axis.

    Similarly to t2_star, if the qubit frequency is perfectly calibrated then the Y expectation
    will oscillate at the given detuning frequency as the qubit is rotated about the Z axis (with
    respect to the lab frame, which by hypothesis matches the natural qubit frame). Unlike in a
    t2_star experiment, even if the qubit frequency is off such that there is some spurious
    rotation about the Z axis during the DELAY, the effect of an ideal echo is to cancel the
    effect of this rotation so that the qubit returns to the initial state minusY before the
    detuning rotation is applied.

    :param qubits: list of qubits to measure.
    :param times: the times at which to measure, given in seconds. Each time is rounded to the
        nearest .1 microseconds.
    :param detuning: The additional detuning frequency about the z axis.
    :return: ObservablesExperiments which can be run to acquire an estimate of T2 for each qubit.
    """
    expts = []
    for t in times:
        half_time = round(t / 2, 7)  # enforce 100ns boundaries
        t = round(t, 7)
        program = Program()
        settings = []
        for q in qubits:
            half_delay = Pragma('DELAY', [q], str(half_time))
            # echo
            program += [half_delay, RY(pi, q), half_delay]
            # apply detuning
            program += RZ(2 * pi * t * detuning, q)
            settings.append(ExperimentSetting(minusY(q), PauliTerm('Y', q)))

        expts.append(ObservablesExperiment(settings, program))

    return expts
Esempio n. 4
0
def parameterized_bitstring_prep(qubits: Sequence[int], reg_name: str, append_measure: bool = False,
                                 in_x_basis: bool = False) -> Program:
    """
    Produces a parameterized program for the given group of qubits, where each qubit is prepared
    in the 0 or 1 state depending on the parameterization specified at run-time.

    See also bitstring_prep which produces a non-parameterized program that prepares
    and measures a single pre-specified bitstring on the given qubits. Parameterization allows
    for a single program to measure each bitstring (specified at run-time) and speeds up
    the collective measurements of all bitstring for a group of qubits. Note that the program
    produced by bitstring_prep does not execute any gates when preparing 0 on a particular qubit
    and executes only one gate to prepare 1; meanwhile, this method produces a program which
    executes three gates for either preparation on each qubit.

    :param qubits: labels of qubits on which some bitstring will be prepared and, perhaps, measured
    :param reg_name: the name of the register that will hold the bitstring parameters.
    :param append_measure: dictates whether to measure the qubits after preparing the bitstring
    :param in_x_basis: if true, prepare the bitstring in the x basis, where plus <==> zero,
        minus <==> one.
    :return: a parameterized program capable of preparing, and optionally measuring, any runtime
        specified bitstring on the given qubits. See estimate_joint_confusion_in_set in
        readout.py for example use.
    """
    program = Program()

    if append_measure:
        ro = program.declare('ro', memory_type='BIT', memory_size=len(qubits))

    bitstr_reg = program.declare(reg_name, memory_type='REAL', memory_size=len(qubits))
    for idx, qubit in enumerate(qubits):
        program += RX(pi / 2, qubit)
        program += RZ(pi * bitstr_reg[idx], qubit)
        program += RX(-pi / 2, qubit)

        # if we are doing logic in X basis, follow each bit preparation with a Hadamard
        # H |0> = |+> and H |1> = |-> where + and - label the X basis vectors.
        if in_x_basis:
            program += H(qubit)

        if append_measure:
            program += MEASURE(qubit, ro[idx])

    return program
Esempio n. 5
0
def test_exponentiate():
    one_pauli_term = QubitOperator('X0 Y2 Z3')
    test_program = exponentiate(one_pauli_term)

    true_program = Program().inst([
        H(0),
        RX(np.pi / 2)(2),
        CNOT(0, 2),
        CNOT(2, 3),
        RZ(2.0)(3),
        CNOT(2, 3),
        CNOT(0, 2),
        H(0),
        RX(-np.pi / 2)(2)
    ])

    # pyquil has no program compare object
    # string base comparison might fail
    assert true_program.out() == test_program.out()
Esempio n. 6
0
def test_noisy_RPE(qvm):
    qvm.qam.random_seed = 5
    angles = pi * np.linspace(2 / 9, 2.0 - 2 / 9, 3)
    num_depths = 6  # max depth of 2^(num_depths - 1)
    add_error = .15

    def add_damping_dephasing_noise(prog, T1, T2, gate_time):
        p = Program()
        p.defgate("noise", np.eye(2))
        p.define_noisy_gate("noise", [0],
                            damping_after_dephasing(T1, T2, gate_time))
        for elem in prog:
            p.inst(elem)
            if isinstance(elem, Measurement):
                continue  # skip measurement
            p.inst(("noise", 0))
        return p

    def add_noise_to_experiments(df, t1, t2, p00, p11):
        gate_time = 200 * 10**(-9)
        df["Experiment"] = Series([
            add_damping_dephasing_noise(prog, t1, t2,
                                        gate_time).define_noisy_readout(
                                            0, p00, p11)
            for prog in df["Experiment"].values
        ])

    tolerance = .1
    # scan over each angle and check that RPE correctly predicts the angle to within .1 radians
    for angle in angles:
        RH = Program(RY(-pi / 4, 0)).inst(RZ(angle, 0)).inst(RY(pi / 4, 0))
        experiments = rpe.generate_rpe_experiments(RH,
                                                   num_depths,
                                                   axis=(pi / 4, 0))
        add_noise_to_experiments(experiments, 25 * 10**(-6.), 20 * 10**(-6.),
                                 .92, .87)
        experiments = rpe.acquire_rpe_data(experiments,
                                           qvm,
                                           multiplicative_factor=5.,
                                           additive_error=add_error)
        xs, ys, x_stds, y_stds = rpe.find_expectation_values(experiments)
        phase_estimate = rpe.robust_phase_estimate(xs, ys, x_stds, y_stds)
        assert np.allclose(phase_estimate, angle, atol=tolerance)
Esempio n. 7
0
def test_get_qvm_noise_supported_gates_from_compiler_isa(compiler_isa):
    gates = _get_qvm_noise_supported_gates(compiler_isa)
    for q in [0, 1, 2]:
        for g in [
                I(q),
                RX(np.pi / 2, q),
                RX(-np.pi / 2, q),
                RX(np.pi, q),
                RX(-np.pi, q),
                RZ(THETA, q),
        ]:
            assert g in gates

    assert CZ(0, 1) in gates
    assert CZ(1, 0) in gates
    assert ISWAP(1, 2) in gates
    assert ISWAP(2, 1) in gates
    assert CPHASE(THETA, 2, 0) in gates
    assert CPHASE(THETA, 0, 2) in gates
def test_exponentiate_3cob():
    # testing circuit for 3-terms with change of basis
    q = QubitPlaceholder.register(8)
    generator = PauliTerm("Z", q[0], 1.0) * PauliTerm(
        "Y", q[1], 1.0) * PauliTerm("X", q[2], 1.0)
    para_prog = exponential_map(generator)
    prog = para_prog(1)
    result_prog = Program().inst([
        RX(math.pi / 2.0, q[1]),
        H(q[2]),
        CNOT(q[0], q[1]),
        CNOT(q[1], q[2]),
        RZ(2.0, q[2]),
        CNOT(q[1], q[2]),
        CNOT(q[0], q[1]),
        RX(-math.pi / 2.0, q[1]),
        H(q[2])
    ])
    assert address_qubits(prog) == address_qubits(result_prog)
Esempio n. 9
0
def test_dagger():
    # these gates are their own inverses
    p = Program().inst(I(0), X(0), Y(0), Z(0),
                       H(0), CNOT(0,1), CCNOT(0,1,2),
                       SWAP(0,1), CSWAP(0,1,2))
    assert p.dagger().out() == 'CSWAP 0 1 2\nSWAP 0 1\n' \
                      'CCNOT 0 1 2\nCNOT 0 1\nH 0\n' \
                      'Z 0\nY 0\nX 0\nI 0\n'

    # these gates require negating a parameter
    p = Program().inst(PHASE(pi, 0), RX(pi, 0), RY(pi, 0),
                       RZ(pi, 0), CPHASE(pi, 0, 1),
                       CPHASE00(pi, 0, 1), CPHASE01(pi, 0, 1),
                       CPHASE10(pi, 0, 1), PSWAP(pi, 0, 1))
    assert p.dagger().out() == 'PSWAP(-3.141592653589793) 0 1\n' \
                               'CPHASE10(-3.141592653589793) 0 1\n' \
                               'CPHASE01(-3.141592653589793) 0 1\n' \
                               'CPHASE00(-3.141592653589793) 0 1\n' \
                               'CPHASE(-3.141592653589793) 0 1\n' \
                               'RZ(-3.141592653589793) 0\n' \
                               'RY(-3.141592653589793) 0\n' \
                               'RX(-3.141592653589793) 0\n' \
                               'PHASE(-3.141592653589793) 0\n'

    # these gates are special cases
    p = Program().inst(S(0), T(0), ISWAP(0, 1))
    assert p.dagger().out() == 'PSWAP(1.5707963267948966) 0 1\n' \
                               'RZ(0.7853981633974483) 0\n' \
                               'PHASE(-1.5707963267948966) 0\n'

    # must invert defined gates
    G = np.array([[0, 1], [0+1j, 0]])
    p = Program().defgate("G", G).inst(("G", 0))
    assert p.dagger().out() == 'DEFGATE G-INV:\n' \
                               '    0.0+-0.0i, 0.0-1.0i\n' \
                               '    1.0+-0.0i, 0.0+-0.0i\n\n' \
                               'G-INV 0\n'

    # can also pass in a list of inverses
    inv_dict = {"G":"J"}
    p = Program().defgate("G", G).inst(("G", 0))
    assert p.dagger(inv_dict=inv_dict).out() == 'J 0\n'
def test_noisy_rpe(qvm):
    qvm.qam.random_seed = 5
    angles = pi * np.linspace(2 / 9, 2.0 - 2 / 9, 3)
    add_error = .15

    def add_damping_dephasing_noise(prog, T1, T2, gate_time):
        p = Program()
        p.defgate("noise", np.eye(2))
        p.define_noisy_gate("noise", [0],
                            damping_after_dephasing(T1, T2, gate_time))
        for elem in prog:
            p.inst(elem)
            if isinstance(elem, Measurement):
                continue  # skip measurement
            p.inst(("noise", 0))
        return p

    def add_noise_to_experiments(df, t1, t2, p00, p11):
        gate_time = 200 * 10**(-9)
        df["Program"] = Series([
            add_damping_dephasing_noise(prog, t1, t2,
                                        gate_time).define_noisy_readout(
                                            0, p00, p11)
            for prog in df["Program"].values
        ])

    tolerance = .1
    # scan over each angle and check that RPE correctly predicts the angle to within .1 radians
    for angle in angles:
        RH = Program(RY(-pi / 4, 0)).inst(RZ(angle, 0)).inst(RY(pi / 4, 0))
        evecs = rpe.bloch_rotation_to_eigenvectors(pi / 4, 0)
        cob = rpe.get_change_of_basis_from_eigvecs(evecs)
        expt = rpe.generate_rpe_experiment(RH, cob, num_depths=7)
        expt = rpe.add_programs_to_rpe_dataframe(qvm, expt)
        add_noise_to_experiments(expt, 25 * 10**(-6.), 20 * 10**(-6.), .92,
                                 .87)
        expt = rpe.acquire_rpe_data(qvm,
                                    expt,
                                    multiplicative_factor=5.,
                                    additive_error=add_error)
        phase_estimate = rpe.robust_phase_estimate(expt)
        assert np.allclose(phase_estimate, angle, atol=tolerance)
Esempio n. 11
0
def test_lifted_gate_modified():
    test_unitary = lifted_gate(RZ(np.pi / 4, 0).dagger(), 1)
    true_unitary = mat.RZ(-np.pi / 4)
    assert np.allclose(test_unitary, true_unitary)

    test_unitary = lifted_gate(X(0).dagger().controlled(1), 2)
    true_unitary = lifted_gate(CNOT(1, 0), 2)
    other_true = mat.CNOT
    assert np.allclose(test_unitary, true_unitary)
    assert np.allclose(other_true, true_unitary)

    test_unitary = lifted_gate(
        X(1).dagger().controlled(0).dagger().dagger(), 2)
    true_unitary = lifted_gate(CNOT(0, 1), 2)
    assert np.allclose(test_unitary, true_unitary)

    test_unitary = lifted_gate(
        X(0).dagger().controlled(1).dagger().dagger().controlled(2), 3)
    true_unitary = lifted_gate(CCNOT(1, 2, 0), 3)
    other_true = mat.CCNOT
    assert np.allclose(test_unitary, true_unitary)
    assert np.allclose(other_true, true_unitary)

    test_unitary = lifted_gate(
        RY(np.pi / 4, 0).dagger().controlled(2).dagger().dagger(), 3)
    ry_part = lifted_gate(RY(-np.pi / 4, 0), 1)
    zero = np.eye(2)
    zero[1, 1] = 0
    one = np.eye(2)
    one[0, 0] = 0
    true_unitary = np.kron(zero, np.eye(4)) + np.kron(
        one, np.kron(np.eye(2), ry_part))
    assert np.allclose(test_unitary, true_unitary)

    test_unitary = lifted_gate(PHASE(0.0, 1).forked(0, [np.pi]), 2)
    true_unitary = lifted_gate(CZ(0, 1), 2)
    assert np.allclose(test_unitary, true_unitary)

    test_unitary = lifted_gate(
        PHASE(0.0, 2).forked(1, [0.0]).forked(0, [0.0, np.pi]), 3)
    true_unitary = lifted_gate(CZ(1, 2).controlled(0), 3)
    assert np.allclose(test_unitary, true_unitary)
Esempio n. 12
0
def test_exponentiate_3ns():
    # testing circuit for 3-terms non-sequential
    generator = (PauliTerm("Y", 0, 1.0) * PauliTerm("I", 1, 1.0) *
                 PauliTerm("Y", 2, 1.0) * PauliTerm("Y", 3, 1.0))
    para_prog = exponential_map(generator)
    prog = para_prog(1)
    result_prog = Program().inst([
        RX(math.pi / 2.0)(0),
        RX(math.pi / 2.0)(2),
        RX(math.pi / 2.0)(3),
        CNOT(0, 2),
        CNOT(2, 3),
        RZ(2.0)(3),
        CNOT(2, 3),
        CNOT(0, 2),
        RX(-math.pi / 2.0)(0),
        RX(-math.pi / 2.0)(2),
        RX(-math.pi / 2.0)(3)
    ])
    assert prog == result_prog
Esempio n. 13
0
def test_gates_in_isa(isa_dict):
    isa = ISA.from_dict(isa_dict)
    gates = gates_in_isa(isa)
    for q in [0, 1, 2]:
        for g in [
                I(q),
                RX(np.pi / 2, q),
                RX(-np.pi / 2, q),
                RX(np.pi, q),
                RX(-np.pi, q),
                RZ(THETA, q)
        ]:
            assert g in gates

    assert CZ(0, 1) in gates
    assert CZ(1, 0) in gates
    assert ISWAP(1, 2) in gates
    assert ISWAP(2, 1) in gates
    assert CPHASE(THETA, 2, 0) in gates
    assert CPHASE(THETA, 0, 2) in gates
def test_exponentiate_3ns():
    # testing circuit for 3-terms non-sequential
    q = QubitPlaceholder.register(8)
    generator = (PauliTerm("Y", q[0], 1.0) * PauliTerm("I", q[1], 1.0) *
                 PauliTerm("Y", q[2], 1.0) * PauliTerm("Y", q[3], 1.0))
    para_prog = exponential_map(generator)
    prog = para_prog(1)
    result_prog = Program().inst([
        RX(math.pi / 2.0, q[0]),
        RX(math.pi / 2.0, q[2]),
        RX(math.pi / 2.0, q[3]),
        CNOT(q[0], q[2]),
        CNOT(q[2], q[3]),
        RZ(2.0, q[3]),
        CNOT(q[2], q[3]),
        CNOT(q[0], q[2]),
        RX(-math.pi / 2.0, q[0]),
        RX(-math.pi / 2.0, q[2]),
        RX(-math.pi / 2.0, q[3])
    ])
    assert address_qubits(prog) == address_qubits(result_prog)
Esempio n. 15
0
def test_expectations_at_depth(qvm):
    qvm.qam.random_seed = 5
    q = 0
    qubits = (q, )
    expected_outcomes = [1., 0, -1., 0]
    for depth in [0, 1, 2, 3, 4]:
        prep, meas, settings = rpe.all_eigenvector_prep_meas_settings(
            qubits, I(q))
        depth_many_rot = [RZ(pi / 2, q) for _ in range(depth)]
        program = Program(prep) + sum(depth_many_rot,
                                      Program()) + Program(meas)
        expt = ObservablesExperiment(list(settings), program)

        results = list(estimate_observables(qvm, expt))

        for res in results:
            meas_dir = res.setting.observable[q]
            idx = ((depth - 1) if meas_dir == 'Y' else depth) % 4
            expected = expected_outcomes[idx]
            exp = res.expectation
            assert np.allclose(expected, exp, atol=.05)
Esempio n. 16
0
def test_parameterized_single_qubit_state_preparation():
    p = Program()
    alpha = p.declare("preparation_alpha", "REAL", 2)
    beta = p.declare("preparation_beta", "REAL", 2)
    gamma = p.declare("preparation_gamma", "REAL", 2)
    p += RZ(alpha[0], 0)
    p += RX(np.pi / 2, 0)
    p += RZ(beta[0], 0)
    p += RX(-np.pi / 2, 0)
    p += RZ(gamma[0], 0)
    p += RZ(alpha[1], 1)
    p += RX(np.pi / 2, 1)
    p += RZ(beta[1], 1)
    p += RX(-np.pi / 2, 1)
    p += RZ(gamma[1], 1)
    assert parameterized_single_qubit_state_preparation([0, 1]).out() == p.out()
Esempio n. 17
0
def get_random_circuit(qubits, length, two_qubit_gate_portion=0.3):
    p = Program()

    for i in range(int(length / 2)):
        if (len(qubits) > 1) and (random.random() < two_qubit_gate_portion):
            random_gate = CZ(*(random.sample(qubits, 2)))
        else:
            theta = 2 * np.pi * random.random()
            qubit = random.choice(qubits)
            random_gate = random.choice([
                RZ(theta, qubit),
                RX(np.pi / 2, qubit),
                RX(-np.pi / 2, qubit)
            ])

        p.inst(random_gate)

    for gate in reversed(Program(p.out()).instructions):
        p.inst(get_dagger_of_native_gate(gate))

    return Program('PRAGMA PRESERVE_BLOCK') + p + Program(
        'PRAGMA END_PRESERVE_BLOCK')
def generate_single_t2_echo_experiment(qubits: Union[int, List[int]],
                                       time: float,
                                       detuning: float,
                                       n_shots: int = 1000) -> Program:
    """
    Return a T2 echo program in native Quil for a single time point.

    :param qubits: Which qubits to measure.
    :param time: The decay time before measurement.
    :param detuning: The additional detuning frequency about the z axis.
    :param n_shots: The number of shots to average over for the data point.
    :return: A T2 Program.
    """
    program = Program()

    try:
        len(qubits)
    except TypeError:
        qubits = [qubits]

    ro = program.declare('ro', 'BIT', len(qubits))
    for q in qubits:
        # prepare plus state |+>
        program += RX(np.pi / 2, q)
        # wait half of the delay
        program += Pragma('DELAY', [q], str(time / 2))
        # apply an X gate compiled out of RX(90)
        program += RX(np.pi / 2, q)
        program += RX(np.pi / 2, q)
        # wait the other half of the delay
        program += Pragma('DELAY', [q], str(time / 2))
        program += RZ(2 * np.pi * time * detuning, q)
        program += RX(np.pi / 2, q)
    for i in range(len(qubits)):
        program += MEASURE(qubits[i], ro[i])
    program.wrap_in_numshots_loop(n_shots)
    return program
Esempio n. 19
0
def three_POVM(theta0, phi0, theta1, theta2, theta3, theta4, alpha_uii,
               Kraus) -> Program:

    # for the purpose of POVM we choose the most connected qubit (10 in the case) to be the measured one
    ancilla = [11, 17]
    target = 10

    program = Program(RESET())
    # create initial state
    if theta0 != 0:
        program.inst(RY(theta0, target))
    if phi0 != 0:
        program.inst(RZ(phi0, target))

    # 1st AP module
    program.inst(POVM_module_1(theta1, theta2, ancilla, target))

    # 2nd AP module (+ U2, T1, T2, T3)

    program.inst(nCU1('y', alpha_uii, [ancilla[0]], target))
    program.inst(POVM_module_2(theta3, theta4, ancilla, target))

    # Kraus operators
    if Kraus == 1:
        # T2
        program.inst(X(ancilla[1]))
        program.inst(nCU1('y', 2 * np.pi / 3, ancilla, target))
        program.inst(X(ancilla[1]))

        # T3
        program.inst(nCU1('y', 7 * np.pi / 3, ancilla, target))

    # fix paths encodings: 11->01
    program.inst(CNOT(ancilla[1], ancilla[0]))

    return program
Esempio n. 20
0
def get_test_program(measure: bool = False) -> Program:
    PI = float(pi.evalf())
    p = Program()
    p += X(0)
    p += Y(1)
    p += Z(2)
    p += H(3)
    p += S(0)
    p += T(1)
    p += RX(PI / 2, 2)
    p += RY(PI / 2, 3)
    p += RZ(PI / 2, 0)
    p += CZ(0, 1)
    p += CNOT(2, 3)
    p += CCNOT(0, 1, 2)
    p += CPHASE(PI / 4, 2, 1)
    p += SWAP(0, 3)
    if measure:
        ro = p.declare("ro", "BIT", 4)
        p += MEASURE(0, ro[0])
        p += MEASURE(3, ro[1])
        p += MEASURE(2, ro[2])
        p += MEASURE(1, ro[3])
    return p
Esempio n. 21
0
def test_psiref_bar_p2():
    bar = [(0, 1)]
    p = 2
    with patch('grove.pyqaoa.maxcut_qaoa.api', spec=qvm_mod):
        inst = maxcut_qaoa(bar, steps=p)

    param_prog = inst.get_parameterized_program()

    # returns are the rotations correct?
    prog = param_prog([1.2, 3.4, 2.1, 4.5])
    result_prog = Program().inst([
        H(0),
        H(1),
        X(0),
        PHASE(1.05)(0),
        X(0),
        PHASE(1.05)(0),
        CNOT(0, 1),
        RZ(2.1)(1),
        CNOT(0, 1),
        H(0),
        RZ(-2.4)(0),
        H(0),
        H(1),
        RZ(-2.4)(1),
        H(1),
        X(0),
        PHASE(2.25)(0),
        X(0),
        PHASE(2.25)(0),
        CNOT(0, 1),
        RZ(4.5)(1),
        CNOT(0, 1),
        H(0),
        RZ(-6.8)(0),
        H(0),
        H(1),
        RZ(-6.8)(1),
        H(1),
    ])
    assert prog == result_prog
Esempio n. 22
0
    def get_decoupling_sequence(self,
                                gate: Gate,
                                dd_pulse_time: float = None) -> "Program":
        if isinstance(gate, Gate):
            combined_gate = get_combined_gate(
                *get_combined_gate_representation(gate.name, 'X', gate.params))
            if len(gate.qubits) != 1:
                p = Program(RZ(pi, gate.qubits[0]), RZ(pi, gate.qubits[1]),
                            RX(pi, gate.qubits[0]), RX(pi, gate.qubits[1]),
                            RZ(pi, gate.qubits[0]), RZ(pi, gate.qubits[1]))

            else:
                p = Program(RZ(pi, *gate.qubits), RX(pi, *gate.qubits),
                            RZ(pi, *gate.qubits))

            seq = set_gate_time(p, dd_pulse_time)
            GX = combined_gate(*gate.qubits)
            GX = gates_with_time(GX.name, GX.params, GX.qubits)
            GX.dd = False
            seq += GX

        return seq
Esempio n. 23
0
    0.0625 + 0.0j,
    0.0625 + 0.0j,
    0.0625 + 0.0j,
    0.0625 + 0.0j,
    0.0625 + 0.0j,
    0.0625 + 0.0j,
    0.0625 + 0.0j,
    0.0625 + 0.0j,
    0.0625 + 0.0j,
]

HADAMARD_WF = [0.70710678 + 0.0j, 0.70710678 + 0.0j]

ARBITRARY_STATE_GEN_INSTRUCTIONS = {
    1: [
        RZ(-1.3778211380875056, 0),
        PHASE(1.3778211380875056, 0),
        H(0),
        RY(-1.5707963267948963, 0),
        RZ(-1.3778211380875056, 0),
    ],
    2: [
        RZ(3.9156492624160952, 0),
        PHASE(-3.9156492624160952, 0),
        H(0),
        RY(-1.334414217642601, 0),
        RZ(-0.51915346851116273, 0),
    ],
    3: [
        RZ(1.1065191340906928, 0),
        PHASE(-1.1065191340906928, 0),
Esempio n. 24
0
def test_trotterize():
    term_one = PauliTerm("X", 0, 1.0)
    term_two = PauliTerm("Z", 0, 1.0)

    with pytest.raises(ValueError):
        trotterize(term_one, term_two, trotter_order=0)
    with pytest.raises(ValueError):
        trotterize(term_one, term_two, trotter_order=5)

    prog, _ = trotterize(term_one, term_one)
    result_prog = Program().inst(
        [H(0), RZ(2.0)(0), H(0),
         H(0), RZ(2.0)(0), H(0)])
    compare_progs(prog, result_prog)

    # trotter_order 1 steps 1
    prog, _ = trotterize(term_one, term_two, trotter_steps=1)
    result_prog = Program().inst([H(0), RZ(2.0)(0), H(0), RZ(2.0)(0)])
    compare_progs(prog, result_prog)

    # trotter_order 1 steps 2
    prog, _ = trotterize(term_one, term_two, trotter_steps=2)
    result_prog = Program().inst([
        H(0),
        RZ(1.0)(0),
        H(0),
        RZ(1.0)(0),
        H(0),
        RZ(1.0)(0),
        H(0),
        RZ(1.0)(0)
    ])
    compare_progs(prog, result_prog)

    # trotter_order 2 steps 1
    prog, _ = trotterize(term_one, term_two, trotter_order=2)
    result_prog = Program().inst(
        [H(0), RZ(1.0)(0),
         H(0), RZ(2.0)(0),
         H(0), RZ(1.0)(0),
         H(0)])
    compare_progs(prog, result_prog)

    # trotter_order 2 steps 2
    prog, _ = trotterize(term_one, term_two, trotter_order=2, trotter_steps=2)
    result_prog = Program().inst([
        H(0),
        RZ(0.5)(0),
        H(0),
        RZ(1.0)(0),
        H(0),
        RZ(0.5)(0),
        H(0),
        H(0),
        RZ(0.5)(0),
        H(0),
        RZ(1.0)(0),
        H(0),
        RZ(0.5)(0),
        H(0)
    ])
    compare_progs(prog, result_prog)

    # trotter_order 3 steps 1
    prog, _ = trotterize(term_one, term_two, trotter_order=3, trotter_steps=1)
    result_prog = Program().inst([
        H(0),
        RZ(14.0 / 24)(0),
        H(0),
        RZ(4.0 / 3.0)(0),
        H(0),
        RZ(1.5)(0),
        H(0),
        RZ(-4.0 / 3.0)(0),
        H(0),
        RZ(-2.0 / 24)(0),
        H(0),
        RZ(2.0)(0)
    ])
    compare_progs(prog, result_prog)
Esempio n. 25
0
def test_exponentiate_prog():
    ham = PauliTerm("Z", 0)
    result_prog = Program(RZ(2.0, 0))
    prog = exponentiate(ham)
    compare_progs(result_prog, prog)
Esempio n. 26
0
def test_exponentiate():
    # test rotation of single qubit
    generator = PauliTerm("Z", 0, 1.0)
    para_prog = exponential_map(generator)
    prog = para_prog(1)
    result_prog = Program().inst(RZ(2.0)(0))
    compare_progs(prog, result_prog)

    # testing general 2-circuit
    generator = PauliTerm("Z", 1, 1.0) * PauliTerm("Z", 0, 1.0)
    para_prog = exponential_map(generator)
    prog = para_prog(1)
    result_prog = Program().inst(CNOT(0, 1)).inst(RZ(2.0)(1)).inst(CNOT(0, 1))
    compare_progs(prog, result_prog)

    # testing change of basis position 0
    generator = PauliTerm("Z", 1, 1.0) * PauliTerm("X", 0, 1.0)
    param_prog = exponential_map(generator)
    prog = param_prog(1)
    result_prog = Program().inst(
        [H(0), CNOT(0, 1), RZ(2.0)(1),
         CNOT(0, 1), H(0)])
    compare_progs(prog, result_prog)

    # testing change of basis position 1
    generator = PauliTerm("X", 1, 1.0) * PauliTerm("Z", 0, 1.0)
    para_prog = exponential_map(generator)
    prog = para_prog(1)
    result_prog = Program().inst(
        [H(1), CNOT(0, 1), RZ(2.0)(1),
         CNOT(0, 1), H(1)])
    compare_progs(prog, result_prog)

    # testing change of basis position 0
    generator = PauliTerm("Z", 1, 1.0) * PauliTerm("Y", 0, 1.0)
    para_prog = exponential_map(generator)
    prog = para_prog(1)
    result_prog = Program().inst([
        RX(math.pi / 2.0)(0),
        CNOT(0, 1),
        RZ(2.0)(1),
        CNOT(0, 1),
        RX(-math.pi / 2)(0)
    ])
    compare_progs(prog, result_prog)

    # testing change of basis position 1
    generator = PauliTerm("Y", 1, 1.0) * PauliTerm("Z", 0, 1.0)
    para_prog = exponential_map(generator)
    prog = para_prog(1)
    result_prog = Program().inst([
        RX(math.pi / 2.0)(1),
        CNOT(0, 1),
        RZ(2.0)(1),
        CNOT(0, 1),
        RX(-math.pi / 2.0)(1)
    ])
    compare_progs(prog, result_prog)

    # testing circuit for 3-terms with change of basis
    generator = PauliTerm("X", 2, 1.0) * PauliTerm("Y", 1, 1.0) * PauliTerm(
        "Z", 0, 1.0)
    para_prog = exponential_map(generator)
    prog = para_prog(1)
    result_prog = Program().inst([
        RX(math.pi / 2.0)(1),
        H(2),
        CNOT(0, 1),
        CNOT(1, 2),
        RZ(2.0)(2),
        CNOT(1, 2),
        CNOT(0, 1),
        RX(-math.pi / 2.0)(1),
        H(2)
    ])
    compare_progs(prog, result_prog)

    # testing circuit for 3-terms non-sequential
    generator = PauliTerm("Y", 3, 1.0) * PauliTerm("Y", 2, 1.0) * PauliTerm(
        "I", 1, 1.0) * PauliTerm("Y", 0, 1.0)
    para_prog = exponential_map(generator)
    prog = para_prog(1)
    result_prog = Program().inst([
        RX(math.pi / 2.0)(0),
        RX(math.pi / 2.0)(2),
        RX(math.pi / 2.0)(3),
        CNOT(0, 2),
        CNOT(2, 3),
        RZ(2.0)(3),
        CNOT(2, 3),
        CNOT(0, 2),
        RX(-math.pi / 2.0)(0),
        RX(-math.pi / 2.0)(2),
        RX(-math.pi / 2.0)(3)
    ])
    compare_progs(prog, result_prog)
 def single_qubit_unitary(self, angles, qubit):
     return RX(angles[0], qubit), RZ(angles[1], qubit), RX(angles[2], qubit)
Esempio n. 28
0
def test_rotations():
    p = Program(RX(0.5, 0), RY(0.1, 1), RZ(1.4, 2))
    assert p.out() == "RX(0.5) 0\nRY(0.1) 1\nRZ(1.4) 2\n"
Esempio n. 29
0
def test_rotations():
    p = Program(RX(0.5)(0), RY(0.1)(1), RZ(1.4)(2))
    assert p.out() == 'RX(0.5) 0\nRY(0.1) 1\nRZ(1.4) 2\n'
Esempio n. 30
0
def test_larger_qaoa_circuit():
    square_qaoa_circuit = [
        H(0),
        H(1),
        H(2),
        H(3),
        X(0),
        PHASE(0.3928244130249029, 0),
        X(0),
        PHASE(0.3928244130249029, 0),
        CNOT(0, 1),
        RZ(0.78564882604980579, 1),
        CNOT(0, 1),
        X(0),
        PHASE(0.3928244130249029, 0),
        X(0),
        PHASE(0.3928244130249029, 0),
        CNOT(0, 3),
        RZ(0.78564882604980579, 3),
        CNOT(0, 3),
        X(0),
        PHASE(0.3928244130249029, 0),
        X(0),
        PHASE(0.3928244130249029, 0),
        CNOT(1, 2),
        RZ(0.78564882604980579, 2),
        CNOT(1, 2),
        X(0),
        PHASE(0.3928244130249029, 0),
        X(0),
        PHASE(0.3928244130249029, 0),
        CNOT(2, 3),
        RZ(0.78564882604980579, 3),
        CNOT(2, 3),
        H(0),
        RZ(-0.77868204192240842, 0),
        H(0),
        H(1),
        RZ(-0.77868204192240842, 1),
        H(1),
        H(2),
        RZ(-0.77868204192240842, 2),
        H(2),
        H(3),
        RZ(-0.77868204192240842, 3),
        H(3),
    ]

    prog = Program(square_qaoa_circuit)
    qam = PyQVM(n_qubits=4, quantum_simulator_type=ReferenceWavefunctionSimulator)
    qam.execute(prog)
    wf = qam.wf_simulator.wf

    wf_true = np.array(
        [
            8.43771693e-05 - 0.1233845 * 1j,
            -1.24927731e-01 + 0.00329533 * 1j,
            -1.24927731e-01 + 0.00329533 * 1j,
            -2.50040954e-01 + 0.12661547 * 1j,
            -1.24927731e-01 + 0.00329533 * 1j,
            -4.99915497e-01 - 0.12363516 * 1j,
            -2.50040954e-01 + 0.12661547 * 1j,
            -1.24927731e-01 + 0.00329533 * 1j,
            -1.24927731e-01 + 0.00329533 * 1j,
            -2.50040954e-01 + 0.12661547 * 1j,
            -4.99915497e-01 - 0.12363516 * 1j,
            -1.24927731e-01 + 0.00329533 * 1j,
            -2.50040954e-01 + 0.12661547 * 1j,
            -1.24927731e-01 + 0.00329533 * 1j,
            -1.24927731e-01 + 0.00329533 * 1j,
            8.43771693e-05 - 0.1233845 * 1j,
        ]
    )

    np.testing.assert_allclose(wf_true, wf)