Beispiel #1
0
def _one_q_pauli_prep(label: str, index: int,
                      qubit: QubitDesignator) -> Program:
    """Prepare the index-th eigenstate of the pauli operator given by label."""
    if index not in [0, 1]:
        raise ValueError(f"Bad Pauli index: {index}")

    if label == "X":
        if index == 0:
            return Program(RY(pi / 2, qubit))
        else:
            return Program(RY(-pi / 2, qubit))

    elif label == "Y":
        if index == 0:
            return Program(RX(-pi / 2, qubit))
        else:
            return Program(RX(pi / 2, qubit))

    elif label == "Z":
        if index == 0:
            return Program()
        else:
            return Program(RX(pi, qubit))

    raise ValueError(f"Bad Pauli label: {label}")
Beispiel #2
0
def test_qaoa_unitary():
    wf_true = [
        0.00167784 + 1.00210180e-05 * 1j,
        0.50000000 - 4.99997185e-01 * 1j,
        0.50000000 - 4.99997185e-01 * 1j,
        0.00167784 + 1.00210180e-05 * 1j,
    ]

    prog = Program([
        RY(np.pi / 2, 0),
        RX(np.pi, 0),
        RY(np.pi / 2, 1),
        RX(np.pi, 1),
        CNOT(0, 1),
        RX(-np.pi / 2, 1),
        RY(4.71572463191, 1),
        RX(np.pi / 2, 1),
        CNOT(0, 1),
        RX(-2 * 2.74973750579, 0),
        RX(-2 * 2.74973750579, 1),
    ])

    test_unitary = program_unitary(prog, n_qubits=2)
    wf_test = np.zeros(4)
    wf_test[0] = 1.0
    wf_test = test_unitary.dot(wf_test)
    assert np.allclose(wf_test, wf_true)
Beispiel #3
0
def test_qaoa_circuit():
    wf_true = [
        0.00167784 + 1.00210180e-05 * 1j,
        0.50000000 - 4.99997185e-01 * 1j,
        0.50000000 - 4.99997185e-01 * 1j,
        0.00167784 + 1.00210180e-05 * 1j,
    ]
    prog = Program()
    prog.inst(
        [
            RY(np.pi / 2, 0),
            RX(np.pi, 0),
            RY(np.pi / 2, 1),
            RX(np.pi, 1),
            CNOT(0, 1),
            RX(-np.pi / 2, 1),
            RY(4.71572463191, 1),
            RX(np.pi / 2, 1),
            CNOT(0, 1),
            RX(-2 * 2.74973750579, 0),
            RX(-2 * 2.74973750579, 1),
        ]
    )

    qam = PyQVM(n_qubits=2, quantum_simulator_type=ReferenceWavefunctionSimulator)
    qam.execute(prog)
    wf = qam.wf_simulator.wf
    np.testing.assert_allclose(wf_true, wf, atol=1e-8)
def test_PrepareAndMeasureOnQVM_QubitPlaceholders_nondiag_hamiltonian():
    q1, q2, q3 = QubitPlaceholder(), QubitPlaceholder(), QubitPlaceholder()
    ham = PauliTerm("Y", q1) * PauliTerm("Z", q3)
    ham += PauliTerm("Y", q1) * PauliTerm("Z", q2, -0.3)
    ham += PauliTerm("Y", q1) * PauliTerm("X", q3, 2.0)
    params = [3.0, 0.4, 4.5]

    prepare_ansatz = Program()
    param_register = prepare_ansatz.declare("params",
                                            memory_type="REAL",
                                            memory_size=3)
    prepare_ansatz.inst(RX(param_register[0], q1))
    prepare_ansatz.inst(RY(param_register[1], q2))
    prepare_ansatz.inst(RY(param_register[2], q3))

    def make_memory_map(params):
        return {"params": params}

    qubit_mapping = get_default_qubit_mapping(prepare_ansatz)
    qvm = get_qc("3q-qvm")
    with local_qvm():
        cost_fn = PrepareAndMeasureOnQVM(prepare_ansatz,
                                         make_memory_map,
                                         qvm=qvm,
                                         hamiltonian=ham,
                                         scalar_cost_function=False,
                                         base_numshots=100,
                                         qubit_mapping=qubit_mapping)
        out = cost_fn(params, nshots=10)
        assert np.allclose(out, (0.346, 0.07), rtol=1.1)
Beispiel #5
0
    def get_decoupling_sequence(self,
                                gate: Gate,
                                dd_pulse_time: float = None) -> "Program":
        if isinstance(gate, Gate):
            angle = None
            combined_gate = get_combined_gate(
                *get_combined_gate_representation(gate.name, 'Y', gate.params))

            if len(gate.qubits) != 1:
                p = Program(RX(pi, gate.qubits[0]), RX(pi, gate.qubits[1]),
                            RY(pi, gate.qubits[0]), RY(pi, gate.qubits[1]),
                            RX(pi, gate.qubits[0]), RX(pi, gate.qubits[1]))

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

            seq = set_gate_time(p, dd_pulse_time)
            GY = combined_gate(
                angle, *gate.qubits) if angle is not None else combined_gate(
                    *gate.qubits)
            GY = gates_with_time(GY.name, GY.params, GY.qubits)
            GY.dd = False
            seq += GY

            return seq
Beispiel #6
0
def rus(inputs, w, b):
    in_reg = list()
    for i in inputs:
        in_reg.append(i)
    an_reg = list()
    an_reg.append(QubitPlaceholder())
    an_reg.append(QubitPlaceholder())
    # Gates and classical memory preparation
    prep_pq = Program()
    acl_ro = prep_pq.declare('acl_{}_ro'.format(an_reg[0]), 'BIT', 1)
    # Rotation gates
    rot_linear_pq = Program()
    for i in range(len(w)):
        rot_linear_pq += CRY(w[i])(in_reg[i], an_reg[0])
    rot_linear_pq += RY(b, an_reg[0])
    rot_pq = Program()
    rot_pq += rot_linear_pq
    rot_pq += CY(an_reg[0], an_reg[1])
    rot_pq += RZ(-np.pi / 2, an_reg[0])
    rot_pq += rot_linear_pq
    # Ancilla bit measurement
    pq = Program()
    pq += prep_pq
    pq += rot_pq
    pq += MEASURE(an_reg[0], acl_ro)
    # Repeated circuit
    rep_pq = Program()
    # rep_pq += RESET(reg[1])
    rep_pq += RY(-np.pi / 2, an_reg[1])
    rep_pq += rot_pq
    rep_pq += MEASURE(an_reg[0], acl_ro)

    pq.while_do(acl_ro, rep_pq)
    return pq, an_reg[1]
def test_qaoa_density():
    wf_true = [
        0.00167784 + 1.00210180e-05 * 1j,
        0.50000000 - 4.99997185e-01 * 1j,
        0.50000000 - 4.99997185e-01 * 1j,
        0.00167784 + 1.00210180e-05 * 1j,
    ]
    wf_true = np.reshape(np.array(wf_true), (4, 1))
    rho_true = np.dot(wf_true, np.conj(wf_true).T)
    prog = Program()
    prog.inst([
        RY(np.pi / 2, 0),
        RX(np.pi, 0),
        RY(np.pi / 2, 1),
        RX(np.pi, 1),
        CNOT(0, 1),
        RX(-np.pi / 2, 1),
        RY(4.71572463191, 1),
        RX(np.pi / 2, 1),
        CNOT(0, 1),
        RX(-2 * 2.74973750579, 0),
        RX(-2 * 2.74973750579, 1),
    ])

    qam = PyQVM(n_qubits=2,
                quantum_simulator_type=ReferenceDensitySimulator).execute(prog)
    rho = qam.wf_simulator.density
    np.testing.assert_allclose(rho_true, rho, atol=1e-8)
Beispiel #8
0
    def add_xy_meas_coda_to_program(prog, bit_pos_to_xy_str):
        """
        This method adds a "coda" (tail ending) to prog using data in
        bit_pos_to_xy_str to determine what coda will be.

        Parameters
        ----------
        prog : Program
        bit_pos_to_xy_str : dict[int, str]

        Returns
        -------
        None

        """
        for bit_pos, xy_str in bit_pos_to_xy_str.items():
            if xy_str == 'X':
                # exp(-i*sigy*pi/4)*sigz*exp(i*sigy*pi/4) = sigx
                prog += RY(-np.pi / 2, bit_pos)
            elif xy_str == 'Y':
                # exp(i*sigx*pi/4)*sigz*exp(-i*sigx*pi/4) = sigy
                prog += RX(np.pi / 2, bit_pos)
            else:
                assert False, "Unsupported qbit measurement. '" + \
                            xy_str + "' Should be either 'X' or 'Y'"
Beispiel #9
0
def ansatz(params):
    p = Program()
    for i in range(depth):
        p += CNOT(2, 0)
        for j in range(n_qubits):
            p += Program(RY(params[j], j))
    return p
Beispiel #10
0
 def prep_state_program(self, sample):
     #TODO: Prep a state given classical vector x
     prog = Program()
     for i in range(0, self.n):
         angle = math.pi*sample[i]#/2
         prog.inst(RY(angle, i))
     return prog
def test_pyquil_program():
    """Tests if the Dynamic Decoupling Sequence gives rise to Identity
    operation in PyQuil
    """
    _duration = 5e-6
    _offsets = [0, 1e-6, 2.5e-6, 4e-6, 5e-6]
    _rabi_rotations = [np.pi / 2, np.pi / 2, np.pi, 0, np.pi / 2]
    _azimuthal_angles = [0, 0, np.pi / 2, 0, 0]
    _detuning_rotations = [0, 0, 0, np.pi, 0]

    sequence = DynamicDecouplingSequence(
        duration=_duration,
        offsets=_offsets,
        rabi_rotations=_rabi_rotations,
        azimuthal_angles=_azimuthal_angles,
        detuning_rotations=_detuning_rotations)

    program = convert_dds_to_pyquil_program(sequence, [0], gate_time=1e-6)

    assert len(program) == 13
    assert program[0] == Pragma("PRESERVE_BLOCK")
    assert program[-1] == Pragma("END_PRESERVE_BLOCK")
    assert program[1] == RX(np.pi / 2, 0)
    assert program[2] == I(0)
    assert program[3] == RX(np.pi / 2, 0)
    assert program[4] == I(0)
    assert program[5] == RY(np.pi, 0)
    assert program[6] == I(0)
    assert program[7] == RZ(np.pi, 0)
    assert program[8] == I(0)
    assert program[9] == RX(np.pi / 2, 0)
Beispiel #12
0
def pauli_meas(idx, op):
    r"""
    Generate gate sequence to measure in the eigenbasis of a Pauli operator, assuming
    we are only able to measure in the Z eigenbasis. The available operations are the
    following:

    .. math::

        'X' = \begin{bmatrix}
                0 & \frac{-\pi}{2} \\
                \frac{-\pi}{2} & 0 
            \end{bmatrix}

        'Y' = \begin{bmatrix}
                0 & \frac{-i\pi}{2} \\
                \frac{i\pi}{2} & 0 
            \end{bmatrix}


    and :math:`'Z' = 'I' = \mathbb{I}`.

    :param int idx: the qubit index on which the measurement basis rotation is to be performed.
    :param str op: enumeration ('X', 'Y', 'Z', 'I') representing the axis of the given Pauli matrix

    :return: a `pyquil` Program representing the Pauli matrix projected onto the Z eigenbasis.
    :rtype: Program
    """
    if op == 'X':
        return Program(RY(-np.pi / 2, idx))
    elif op == 'Y':
        return Program(RX(np.pi / 2, idx))
    elif op == 'Z':
        return Program()
    elif op == 'I':
        return Program()
Beispiel #13
0
def test_qc_expectation_on_qvm(client_configuration: QCSClientConfiguration, dummy_compiler: DummyCompiler):
    # regression test for https://github.com/rigetti/forest-tutorials/issues/2
    qc = QuantumComputer(name="testy!", qam=QVM(client_configuration=client_configuration), compiler=dummy_compiler)

    p = Program()
    theta = p.declare("theta", "REAL")
    p += RESET()
    p += RY(theta, 0)
    p.wrap_in_numshots_loop(10000)

    sx = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0)), out_operator=sX(0))
    e = Experiment(settings=[sx], program=p)

    thetas = [-np.pi / 2, 0.0, np.pi / 2]
    results = []

    # Verify that multiple calls to qc.experiment with the same experiment backed by a QVM that
    # requires_exectutable does not raise an exception.
    for theta in thetas:
        results.append(qc.experiment(e, memory_map={"theta": [theta]}))

    assert np.isclose(results[0][0].expectation, -1.0, atol=0.01)
    assert np.isclose(results[0][0].std_err, 0)
    assert results[0][0].total_counts == 20000

    # bounds on atol and std_err here are a little loose to try and avoid test flakiness.
    assert np.isclose(results[1][0].expectation, 0.0, atol=0.1)
    assert results[1][0].std_err < 0.01
    assert results[1][0].total_counts == 20000

    assert np.isclose(results[2][0].expectation, 1.0, atol=0.01)
    assert np.isclose(results[2][0].std_err, 0)
    assert results[2][0].total_counts == 20000
def measure_graph_state(graph: nx.Graph, focal_node: int):
    """Given a graph state, measure a focal node and its neighbors with a particular measurement
    angle.

    :param prep_program: Probably the result of :py:func:`create_graph_state`.
    :param qs: List of qubits used in prep_program or anything that can be indexed by the nodes
        in the graph ``graph``.
    :param graph: The graph state graph. This is needed to figure out what the neighbors are
    :param focal_node: The node in the graph to serve as the focus. The focal node is measured
        at an angle and all its neighbors are measured in the Z basis
    :return Program, list of classical offsets into the ``ro`` register.
    """
    program = Program()
    theta = program.declare('theta', 'REAL')
    program += RY(theta, focal_node)

    neighbors = sorted(graph[focal_node])
    ro = program.declare('ro', 'BIT', len(neighbors) + 1)

    program += MEASURE(focal_node, ro[0])
    for i, neighbor in enumerate(neighbors):
        program += MEASURE(neighbor, ro[i + 1])

    classical_addresses = list(range(len(neighbors) + 1))
    return program, classical_addresses
Beispiel #15
0
    def get_parameteric_circuit(self, theta=None, verify=False):
        """
        Constructs a parameterized circuit that returns |00> and |11> with equal probability where the optimal parameter theta
        needs to be determined using Gradient Descent
        This function is also used to return a circuit for a given value of theta in order to verify the final wavefunction

        Parameters:
        -----------
        theta  : Value of the parameter for which a circuit is returned to verify the final wavefunction
        verify : If True, returns a circuit for the given value of theta
        """

        parameteric_program = Program()

        if theta is None:
            theta = parameteric_program.declare("theta", memory_type="REAL")

        parameteric_program.inst(RY(theta, 0))
        parameteric_program.inst(CNOT(0, 1))

        if not verify:
            ro = parameteric_program.declare("ro",
                                             memory_type="BIT",
                                             memory_size=2)
            parameteric_program.inst(MEASURE(0, ro[0]))
            parameteric_program.inst(MEASURE(1, ro[1]))
            parameteric_program.wrap_in_numshots_loop(shots=self.shots)

        return parameteric_program
Beispiel #16
0
def generate_single_depth_experiment(rotation: Program,
                                     depth: int,
                                     exp_type: str,
                                     axis: Tuple = None) -> Program:
    """
    Generate an experiment for a single depth where the type specifies a final measurement of either
    X or Y. The rotation program is repeated depth number of times, and we assume the rotation is
    about the axis (theta, phi).

    :param rotation: the program specifying the gate whose angle of rotation we wish to estimate.
    :param depth: the number of times we apply the rotation in the experiment
    :param exp_type: X or Y, specifying which operator to measure at the end of the experiment
    :param axis: the axis of rotation. If none is specified, axis is assumed to be the Z axis. (rotation should be RZ)
    :return: a program specifying the entire experiment of a single iteration of the RPE protocol in [RPE]
    """
    experiment = Program()
    ro_bit = experiment.declare("ro", "BIT", 1)
    qubit = list(rotation.get_qubits())[0]
    prepare_state(experiment, qubit, axis)
    for _ in range(depth):
        experiment.inst(rotation)
    if axis:
        experiment.inst(RZ(-axis[1], qubit))
        experiment.inst(RY(-axis[0], qubit))
    local_pauli_eig_meas(experiment, exp_type, qubit)
    experiment.measure(qubit, ro_bit)
    return experiment
def prep_state_program(x):
    #TODO: Prep a state given classical vector x
    prog = Program()
    for i in range(0, len(x)):
        angle = math.pi * x[i] / 2
        prog.inst(RY(angle, i))
    return prog
Beispiel #18
0
 def prog(sample):
     p = pq.Program()
     n_features = len(sample)
     for j in range(n_qubits):
         p.inst(RY(np.arcsin(sample[j % n_features]), j))
         p.inst(RZ(np.arccos(sample[j % n_features]**2), j))
     return p
Beispiel #19
0
def rus_single(input, theta):
    reg = list()
    reg.append(input)
    reg.append(QubitPlaceholder())
    reg.append(QubitPlaceholder())
    # Gates and classical memory preparation
    prep_pq = Program()
    prep_pq += dg_cry
    prep_pq += dg_cy
    acl_ro = prep_pq.declare('acl_ro', 'BIT', 1)
    # Rotation gates
    rot_pq = Program()
    rot_pq += CRY(2 * theta)(reg[0], reg[1])
    rot_pq += CY(reg[1], reg[2])
    rot_pq += RZ(-np.pi / 2, reg[1])
    rot_pq += CRY(2 * theta)(reg[0], reg[1])
    # Ancilla bit measurement
    pq = Program()
    pq += prep_pq
    pq += rot_pq
    pq += MEASURE(reg[1], acl_ro)
    # Repeated circuit
    rep_pq = Program()
    # rep_pq += RESET(reg[1])
    rep_pq += RY(-np.pi / 2, reg[2])
    rep_pq += rot_pq
    rep_pq += MEASURE(reg[1], acl_ro)

    pq.while_do(acl_ro, rep_pq)
    return pq, reg[2]
def ansatz(params): 
    qp = Program()
    for i in range(depth):   
		qp.inst(CNOT(1,0))  
        for j in range(n_qubits):
            qp.inst(RY(params[j], j))  
    return qp
 def prep_state_program(self):
     #TODO: Prep a state given classical vector x
     prog = Program()
     sample = prog.declare('sample', memory_type='REAL', memory_size=self.n)
     for i in range(0, self.n):
         angle = math.pi * sample[i] / 2
         prog.inst(RY(angle, i))
     return prog
Beispiel #22
0
def test_noisy_rpe(qvm):
    qvm.qam.random_seed = 5
    angles = pi * np.linspace(2 / 9, 2.0 - 2 / 9, 3)
    add_error = .15
    q = 0

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

    def add_noise_to_experiments(expts, t1, t2, p00, p11, q):
        gate_time = 200 * 10**(-9)
        for ex in expts:
            ex.program = add_damping_dephasing_noise(
                ex.program, t1, t2,
                gate_time).define_noisy_readout(q, p00, p11)

    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, q)).inst(RZ(angle, q)).inst(RY(pi / 4, q))
        evecs = rpe.bloch_rotation_to_eigenvectors(pi / 4, q)
        cob_matrix = rpe.get_change_of_basis_from_eigvecs(evecs)
        cob = rpe.change_of_basis_matrix_to_quil(qvm, [q], cob_matrix)
        prep, meas, settings = rpe.all_eigenvector_prep_meas_settings([q], cob)
        expts = rpe.generate_rpe_experiments(RH,
                                             prep,
                                             meas,
                                             settings,
                                             num_depths=7)
        add_noise_to_experiments(expts, 25 * 10**(-6.), 20 * 10**(-6.), .92,
                                 .87, q)
        results = rpe.acquire_rpe_data(qvm,
                                       expts,
                                       multiplicative_factor=5.,
                                       additive_error=add_error)
        phase_estimate = rpe.robust_phase_estimate(results, [q])
        assert np.allclose(phase_estimate, angle, atol=tolerance)
Beispiel #23
0
def pauli_basis_measurements(qubit):
    """
    Generates the Programs required to measure the expectation values of the pauli operators.

    :param qubit: Required argument (so that the caller has a reference).
    """
    pauli_label_meas_progs = [Program(), Program(RY(-np.pi / 2, qubit)), Program(RX(-np.pi / 2, qubit)), Program()]
    return pauli_label_meas_progs
Beispiel #24
0
def local_pauli_eigs_prep(op, qubit):
    """
    Generate all gate sequences to prepare all eigenstates of a (local) Pauli operator, assuming
    we are starting from the ground state.

    :param str op: A string representation of the Pauli operator whose eigenstate we'd like to prepare.
    :param int qubit: The index of the qubit that the preparation is acting on
    :rtype list: A list of programs
    """
    if op == 'X':
        gates = [RY(pi / 2, qubit), RY(-pi / 2, qubit)]
    elif op == 'Y':
        gates = [RX(-pi / 2, qubit), RX(pi / 2, qubit)]
    elif op == 'Z':
        gates = [I(qubit), RX(pi, qubit)]
    else:
        raise ValueError('Unknown gate operation')
    return [Program(gate) for gate in gates]
Beispiel #25
0
def random_local_pauli_eig_prep(prog, op, qubit, random_seed=None):
    """
    Generate gate sequence to prepare a random local eigenstate of a Pauli operator, assuming
    we are starting from the ground state.

    :param Program prog: The `pyquil.quil.Program` object to which preparation pulses will be
     appended
    :param str op: Single character string representing the Pauli operator
     (one of 'I', 'X', 'Y', 'Z')
    :param int qubit: index of Qubit the preparation acts on
    :param int random_seed: A seed to seed the RNG with.
    :return: A string description of the eigenstate prepared.
    """
    # TODO:
    #   + Return only the sign of the Pauli operator (more compact representation)
    #   + When given the identity, prepare random Pauli eigenstate
    #   + replace calls to random with sampling of random integers
    if random_seed is not None:
        seed(random_seed)
    if op == 'X':
        if random() > 0.5:
            gate = RY(pi / 2, qubit)
            descr = '+X'
        else:
            gate = RY(-pi / 2, qubit)
            descr = '-X'
    elif op == 'Y':
        if random() > 0.5:
            gate = RX(-pi / 2, qubit)
            descr = '+Y'
        else:
            gate = RX(pi / 2, qubit)
            descr = '-Y'
    elif op == 'Z':
        if random() > 0.5:
            gate = I(qubit)
            descr = '+Z'
        else:
            gate = RX(pi, qubit)
            descr = '-Z'
    else:
        raise ValueError('Unknown gate operation')
    prog.inst(gate)
    return descr
Beispiel #26
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(-pi) 0 1\n' \
                               'CPHASE10(-pi) 0 1\n' \
                               'CPHASE01(-pi) 0 1\n' \
                               'CPHASE00(-pi) 0 1\n' \
                               'CPHASE(-pi) 0 1\n' \
                               'RZ(-pi) 0\n' \
                               'RY(-pi) 0\n' \
                               'RX(-pi) 0\n' \
                               'PHASE(-pi) 0\n'

    # these gates are special cases
    p = Program().inst(S(0), T(0), ISWAP(0, 1))
    assert p.dagger().out() == 'PSWAP(pi/2) 0 1\n' \
                               'RZ(pi/4) 0\n' \
                               'PHASE(-pi/2) 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, -i\n' \
                               '    1.0, 0.0\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'

    # defined parameterized gates cannot auto generate daggered version https://github.com/rigetticomputing/pyquil/issues/304
    theta = Parameter('theta')
    gparam_matrix = np.array([[quil_cos(theta / 2), -1j * quil_sin(theta / 2)],
                             [-1j * quil_sin(theta / 2), quil_cos(theta / 2)]])
    g_param_def = DefGate('GPARAM', gparam_matrix, [theta])
    p = Program(g_param_def)
    with pytest.raises(TypeError):
        p.dagger()

    # defined parameterized gates should passback parameters https://github.com/rigetticomputing/pyquil/issues/304
    GPARAM = g_param_def.get_constructor()
    p = Program(GPARAM(pi)(1, 2))
    assert p.dagger().out() == 'GPARAM-INV(pi) 1 2\n'
def GiveLogicalErrRate(code_name, noise_model_kraus, num_trials_tot, code,
                       init_state_mode):
    logical_err_rate = 0.0

    # print(code.encoding_program)
    # print(code.decoding_program)

    for trial_id in range(num_trials_tot):
        initial_state_prep = Program()
        inverse_initial_state_prep = Program()
        for qubit_id in range(code.k):
            if init_state_mode == 0:
                bit = np.random.randint(2)
                if bit == 1:
                    initial_state_prep += X(qubit_id)
                    inverse_initial_state_prep += X(qubit_id)
            else:
                z_angle = (2 * np.pi * np.random.rand(1))
                y_angle = (1 * np.pi * np.random.rand(1))
                initial_state_prep += RZ(z_angle[0], qubit_id)
                initial_state_prep += RY(y_angle[0], qubit_id)
                inverse_initial_state_prep += RY(-y_angle[0], qubit_id)
                inverse_initial_state_prep += RZ(-z_angle[0], qubit_id)

        # Don't use I gate anywher else in program
        error_prog = Program()
        for qubit_id in range(code.n):
            error_prog += Program(I(qubit_id))

        kraus_ops = noise_model_kraus
        error_defn = Program()
        for qubit_id in range(code.n):
            error_defn.define_noisy_gate('I', [qubit_id], kraus_ops)
        error_prog = error_defn + error_prog

        num_errors = basic_tests.test_general(code, initial_state_prep,
                                              error_prog, 1,
                                              inverse_initial_state_prep)
        logical_err_rate += num_errors

    logical_err_rate = logical_err_rate / num_trials_tot
    print(code_name, logical_err_rate)
    return logical_err_rate
Beispiel #28
0
def test_rotation_programs():
    """
    Testing the generation of post rotations
    """
    test_term = sZ(0) * sX(20) * sI(100) * sY(5)
    # note: string comparison of programs requires gates to be in the same order
    true_rotation_program = Program().inst(
        [RX(np.pi / 2)(5), RY(-np.pi / 2)(20)])
    test_rotation_program = get_rotation_program(test_term)
    assert true_rotation_program.out() == test_rotation_program.out()
Beispiel #29
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)
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)