コード例 #1
0
ファイル: test_program.py プロジェクト: vishalbelsare/pyquil
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()
コード例 #2
0
def _get_flipped_protoquil_program(program: Program) -> Program:
    """For symmetrization, generate a program where X gates are added before measurement.

    Forest 1.3 is really picky about where the measure instructions happen. It has to be
    at the end!
    """
    program = program.copy()
    to_measure = []
    while len(program) > 0:
        inst = program.instructions[-1]
        if isinstance(inst, Measurement):
            program.pop()
            to_measure.append((inst.qubit, inst.classical_reg))
        else:
            break

    program += Pragma('PRESERVE_BLOCK')
    for qu, addr in to_measure[::-1]:
        program += RX(pi, qu)
    program += Pragma('END_PRESERVE_BLOCK')

    for qu, addr in to_measure[::-1]:
        program += Measurement(qubit=qu, classical_reg=addr)

    return program
コード例 #3
0
ファイル: test_tools.py プロジェクト: zyedmaheen/pyquil
def test_lifted_gate_single_qubit():
    test_unitary = lifted_gate(H(0), 1)
    true_unitary = mat.H
    assert np.allclose(test_unitary, true_unitary)

    test_unitary = lifted_gate(H(0), 5)
    true_unitary = np.kron(np.eye(2**4), mat.H)
    assert np.allclose(test_unitary, true_unitary)

    test_unitary = lifted_gate(RX(0.2, 3), 5)
    true_unitary = np.kron(np.eye(2**1), np.kron(mat.RX(0.2), np.eye(2**3)))
    assert np.allclose(test_unitary, true_unitary)

    test_unitary = lifted_gate(RX(0.5, 4), 5)
    true_unitary = np.kron(np.eye(2**0), np.kron(mat.RX(0.5), np.eye(2**4)))
    assert np.allclose(test_unitary, true_unitary)
コード例 #4
0
def generate_single_rabi_experiment(qubits: Union[int, List[int]],
                                    theta: float,
                                    n_shots: int = 1000) -> Program:
    """
    Return a Rabi program in native Quil rotated through the given angle.

    Rabi oscillations are observed by applying successively larger rotations to the same initial
    state.

    :param qubits: Which qubits to measure.
    :param theta: The angle of the Rabi RX rotation.
    :param n_shots: The number of shots to average over for the data point.
    :return: A Program that rotates through a given angle about the X axis.
    """
    program = Program()

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

    ro = program.declare('ro', 'BIT', len(qubits))
    for q in qubits:
        program += RX(theta, q)
    for i in range(len(qubits)):
        program += MEASURE(qubits[i], ro[i])
    program.wrap_in_numshots_loop(n_shots)
    return program
コード例 #5
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'"
コード例 #6
0
def test_exponentiate_bp1_YZ():
    q = QubitPlaceholder.register(8)
    # testing change of basis position 1
    generator = PauliTerm("Z", q[0], 1.0) * PauliTerm("Y", q[1], 1.0)
    para_prog = exponential_map(generator)
    prog = para_prog(1)
    result_prog = Program().inst(
        [
            RX(math.pi / 2.0, q[1]),
            CNOT(q[0], q[1]),
            RZ(2.0, q[1]),
            CNOT(q[0], q[1]),
            RX(-math.pi / 2.0, q[1]),
        ]
    )
    assert address_qubits(prog) == address_qubits(result_prog)
コード例 #7
0
def test_transform_cirq_circuit_with_explicit_decompose(
    parametric_circuit_with_params: Tuple[cirq.Circuit, cirq.Linspace],
) -> None:
    """test that a user add a custom circuit decomposition function"""

    parametric_circuit, param_resolvers = parametric_circuit_with_params
    parametric_circuit.append(cirq.I(cirq.GridQubit(0, 0)))
    parametric_circuit.append(cirq.I(cirq.GridQubit(0, 1)))
    parametric_circuit.append(
        cirq.measure(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1), key='m'),
    )
    circuit = cirq.protocols.resolve_parameters(parametric_circuit, param_resolvers[1])

    def decompose_operation(operation: cirq.Operation) -> List[cirq.Operation]:
        operations = [operation]
        if isinstance(operation.gate, cirq.MeasurementGate) and operation.gate.num_qubits() == 1:
            operations.append(cirq.I(operation.qubits[0]))
        return operations

    program, _ = transformers.build(
        decompose_operation=decompose_operation,
    )(circuit=circuit)

    assert (
        RX(np.pi / 2, 2) in program.instructions
    ), "executable should contain an RX(pi) 0 instruction"
    assert I(0) in program.instructions, "executable should contain an I(0) instruction"
    assert I(1) in program.instructions, "executable should contain an I(1) instruction"
    assert I(2) in program.instructions, "executable should contain an I(2) instruction"
    assert DECLARE("m0") in program.instructions, "executable should declare a read out bit"
    assert (
        MEASURE(0, ("m0", 0)) in program.instructions
    ), "executable should measure the read out bit"
コード例 #8
0
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)
コード例 #9
0
ファイル: test_latex.py プロジェクト: vishalbelsare/pyquil
def test_to_latex():
    """A test to give full coverage of latex_generation."""
    p = Program()
    p.inst(
        X(0),
        RX(1.0, 5),
        Y(0),
        CZ(0, 2),
        SWAP(0, 1),
        MEASURE(0, None),
        CNOT(2, 0),
        X(0).controlled(1),
        Y(0).dagger(),
    )
    _ = to_latex(p)

    # Modify settings to access non-standard control paths.
    settings = DiagramSettings(impute_missing_qubits=True)
    _ = to_latex(p, settings)

    settings = DiagramSettings(abbreviate_controlled_rotations=True)
    _ = to_latex(p, settings)

    settings = DiagramSettings(label_qubit_lines=False)
    _ = to_latex(p, settings)
コード例 #10
0
def test_reset(forest):
    device = NxDevice(nx.complete_graph(3))
    qc = QuantumComputer(name="testy!",
                         qam=QVM(connection=forest),
                         device=device,
                         compiler=DummyCompiler())
    p = Program(
        Declare(name="theta", memory_type="REAL"),
        Declare(name="ro", memory_type="BIT"),
        RX(MemoryReference("theta"), 0),
        MEASURE(0, MemoryReference("ro")),
    ).wrap_in_numshots_loop(1000)
    qc.run(executable=p, memory_map={"theta": [np.pi]})

    aref = ParameterAref(name="theta", index=0)
    assert qc.qam._variables_shim[aref] == np.pi
    assert qc.qam._executable == p
    assert qc.qam._memory_results["ro"].shape == (1000, 1)
    assert all([bit == 1 for bit in qc.qam._memory_results["ro"]])
    assert qc.qam.status == "done"

    qc.reset()

    assert qc.qam._variables_shim == {}
    assert qc.qam._executable is None
    assert qc.qam._memory_results["ro"] is None
    assert qc.qam.status == "connected"
コード例 #11
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()
コード例 #12
0
def generate_single_t1_experiment(qubits: Union[int, List[int]],
                                  time: float,
                                  n_shots: int = 1000) -> Program:
    """
    Return a t1 program in native Quil for a single time point.

    :param qubits: Which qubits to measure.
    :param time: The decay time before measurement.
    :param n_shots: The number of shots to average over for the data point.
    :return: A T1 Program.
    """
    program = Program()

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

    ro = program.declare('ro', 'BIT', len(qubits))
    for q in qubits:
        program += RX(np.pi, q)
        program += Pragma('DELAY', [q], str(time))
    for i in range(len(qubits)):
        program += MEASURE(qubits[i], ro[i])
    program.wrap_in_numshots_loop(n_shots)
    return program
コード例 #13
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
コード例 #14
0
ファイル: test_noise.py プロジェクト: timasq/pyquil
def test_decoherence_noise():
    prog = Program(RX(np.pi / 2, 0), CZ(0, 1), RZ(np.pi, 0))
    gates = _get_program_gates(prog)
    m1 = _decoherence_noise_model(gates,
                                  T1=INFINITY,
                                  T2=INFINITY,
                                  ro_fidelity=1.)

    # with no readout error, assignment_probs = identity matrix
    assert np.allclose(m1.assignment_probs[0], np.eye(2))
    assert np.allclose(m1.assignment_probs[1], np.eye(2))
    for g in m1.gates:
        # with infinite coherence time all kraus maps should only have a single, unitary kraus op
        assert len(g.kraus_ops) == 1
        k0, = g.kraus_ops
        # check unitarity
        k0dk0 = k0.dot(k0.conjugate().transpose())
        assert np.allclose(k0dk0, np.eye(k0dk0.shape[0]))

    # verify that selective (by qubit) dephasing and readout infidelity is working
    m2 = _decoherence_noise_model(gates,
                                  T1=INFINITY,
                                  T2={0: 30e-6},
                                  ro_fidelity={
                                      0: .95,
                                      1: 1.0
                                  })
    assert np.allclose(m2.assignment_probs[0], [[.95, 0.05], [.05, .95]])
    assert np.allclose(m2.assignment_probs[1], np.eye(2))
    for g in m2.gates:
        if 0 in g.targets:
            # single dephasing (no damping) channel on qc 0, no noise on qc1 -> 2 Kraus ops
            assert len(g.kraus_ops) == 2
        else:
            assert len(g.kraus_ops) == 1

    # verify that combined T1 and T2 will lead to 4 outcome Kraus map.
    m3 = _decoherence_noise_model(gates, T1={0: 30e-6}, T2={0: 30e-6})
    for g in m3.gates:
        if 0 in g.targets:
            # damping (implies dephasing) channel on qc 0, no noise on qc1 -> 4 Kraus ops
            assert len(g.kraus_ops) == 4
        else:
            assert len(g.kraus_ops) == 1

    # verify that gate names are translated
    new_prog = apply_noise_model(prog, m3)
    new_gates = _get_program_gates(new_prog)

    # check that headers have been embedded
    headers = _noise_model_program_header(m3)
    assert all(
        (isinstance(i, Pragma) and i.command in ["ADD-KRAUS", "READOUT-POVM"])
        or isinstance(i, DefGate) for i in headers)
    assert headers.out() in new_prog.out()

    # verify that high-level add_decoherence_noise reproduces new_prog
    new_prog2 = add_decoherence_noise(prog, T1={0: 30e-6}, T2={0: 30e-6})
    assert new_prog == new_prog2
コード例 #15
0
def test_basic_compile_defgate():
    p = Program()
    p.inst(RX(pi, 0))
    p.defgate("test", [[0, 1], [1, 0]])
    p.inst(("test", 2))
    p.inst(RZ(pi / 2, 0))

    assert p == basic_compile(p)
コード例 #16
0
ファイル: qcl.py プロジェクト: dawidkopczyk/grove
 def prog(theta, idx, sign):
     theta = theta.reshape(3, n_qubits, depth)
     idx = np.unravel_index(idx, theta.shape)
     p = pq.Program()
     for i in range(depth):
         p += ising_prog
         for j in range(n_qubits):
             p.inst(RX(theta[0, j, i], j))
             if idx == (0, j, i):
                 p.inst(RX(sign * np.pi / 2.0, j))
             p.inst(RZ(theta[1, j, i], j))
             if idx == (1, j, i):
                 p.inst(RZ(sign * np.pi / 2.0, j))
             p.inst(RX(theta[2, j, i], j))
             if idx == (2, j, i):
                 p.inst(RX(sign * np.pi / 2.0, j))
     return p
コード例 #17
0
def test_biased_coin():
    # sample from a %75 head and 25% tails coin
    prog = Program().inst(RX(np.pi / 3, 0))
    qvm = QVMConnection(type_trans='density')
    samples = 100000
    results = qvm.run_and_measure(prog, trials=samples)
    coin_bias = sum(map(lambda x: x[0], results)) / float(samples)
    assert np.isclose(coin_bias, 0.25, atol=0.05, rtol=0.05)
コード例 #18
0
ファイル: test_gates.py プロジェクト: tsatir/pyquil
def test_mixed_gate_modifiers():
    g = RX(0.1, 3) \
        .forked(2, [0.2]) \
        .controlled(1) \
        .dagger() \
        .forked(0, [0.3, 0.4])
    assert g.out(
    ) == "FORKED DAGGER CONTROLLED FORKED RX(0.1,0.2,0.3,0.4) 0 1 2 3"
コード例 #19
0
def test_noisy_instruction():
    # Unaffected
    assert I(0) == _noisy_instruction(I(0))
    assert RZ(.234)(0) == _noisy_instruction(RZ(.234)(0))
    assert Pragma('lalala') == _noisy_instruction(Pragma('lalala'))

    # Noisified
    assert _noisy_instruction(CZ(0, 1)).out() == 'noisy-cz 0 1'
    assert _noisy_instruction(RX(np.pi / 2)(0)).out() == 'noisy-x-plus90 0'
    assert _noisy_instruction(RX(-np.pi / 2)(23)).out() == 'noisy-x-minus90 23'

    # Unsupported
    with pytest.raises(ValueError):
        _noisy_instruction(H(0))

    with pytest.raises(ValueError):
        _noisy_instruction(RX(2 * np.pi / 3)(0))
コード例 #20
0
def test_time_evolve():
    one_pauli_term = QubitOperator('X0 Y2 Z3')
    prog = TimeEvolution(1, 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)
    ])

    assert isinstance(true_program, Program)
    assert prog.out() == true_program.out()
コード例 #21
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
コード例 #22
0
def bell_ckt_gd():
    ckt = Program()
    theta_0 = ckt.declare('theta_0', memory_type='REAL')
    theta_1 = ckt.declare("theta_1", memory_type='REAL')
    x_theta = ckt.declare("x_theta", memory_type='REAL')
    ro = ckt.declare('ro', memory_type='BIT', memory_size=2)
    ckt += RX(x_theta, 1)
    ckt += RZ(x_theta, 1)
    ckt += RX(-1 * x_theta, 1)

    ckt += RX(theta_0, 0)
    ckt += RZ(theta_0, 0)

    ckt += RX(x_theta, 0)
    ckt += RZ(theta_1, 0)
    ckt += RX(-1 * x_theta, 0)

    ckt += CZ(1, 0)

    ckt += RX(x_theta, 0)
    ckt += RZ(-1 * theta_1, 0)
    ckt += RX(-1 * x_theta, 0)

    ckt += MEASURE(0, ro[0])
    ckt.wrap_in_numshots_loop(1000)
    return ckt
コード例 #23
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]
コード例 #24
0
def _one_q_sic_prep(index, qubit):
    """Prepare the index-th SIC basis state."""
    if index == 0:
        return Program()

    theta = 2 * np.arccos(1 / np.sqrt(3))
    zx_plane_rotation = Program([RX(-pi / 2, qubit), RZ(theta - pi, qubit), RX(-pi / 2, qubit)])

    if index == 1:
        return zx_plane_rotation

    elif index == 2:
        return zx_plane_rotation + RZ(-2 * pi / 3, qubit)

    elif index == 3:
        return zx_plane_rotation + RZ(2 * pi / 3, qubit)

    raise ValueError(f"Bad SIC index: {index}")
コード例 #25
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
コード例 #26
0
 def _generate_circuit(self, parameters: Optional[np.ndarray] = None):
     circuit = Circuit()
     for theta in self.get_symbols():
         for qubit_index in range(self.number_of_qubits):
             circuit += Circuit(Program(RX(theta, qubit_index)))
     if parameters is not None:
         symbols_map = create_symbols_map(self.get_symbols(), parameters)
         circuit = circuit.evaluate(symbols_map)
     return circuit
コード例 #27
0
def get_dagger_of_native_gate(gate):
    if gate.name == "RZ":
        return RZ(-gate.params[0], gate.qubits[0])
    if gate.name == "RX":
        return RX(-gate.params[0], gate.qubits[0])
    if gate.name == "CZ":
        return CZ(*gate.qubits)

    raise ValueError("Unsupported gate: " + str(gate))
コード例 #28
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
コード例 #29
0
ファイル: test_quil.py プロジェクト: syedm101/pyquil
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'
コード例 #30
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()