Ejemplo n.º 1
0
def test_expw_matrix(half_turns):
    if (version[0] == 0 and version[1] <= 3):
        nptest.assert_array_almost_equal(xmon_gates.Exp11Gate(half_turns=half_turns).matrix,
                                google.Exp11Gate(half_turns=half_turns).matrix())
    else:
        nptest.assert_array_almost_equal(xmon_gates.Exp11Gate(half_turns=half_turns).matrix,
                                unitary(ops.CZPowGate(exponent=half_turns)))
Ejemplo n.º 2
0
def fsim_gate(a, b, theta, phi):
    """FSimGate has a default decomposition in cirq to XXPowGate and YYPowGate,
    which is an awkward decomposition for this gate set.
    Decompose into ISWAP and CZ instead."""
    if theta != 0.0:
        yield ops.ISWAP(a, b)**(-2 * theta / np.pi)
    if phi != 0.0:
        yield ops.CZPowGate(exponent=-phi / np.pi)(a, b)
def _exp11Gate(cmd, mapping, qubits):
    """
    Translate a ExpW gate into a Cirq gate.

    Args:
        - cmd (:class:`projectq.ops.Command`) - a projectq command instance
        - mapping (:class:`dict`) - a dictionary of qubit mappings
        - qubits (list of :class:cirq.QubitID`) - cirq qubits

    Returns:
        - :class:`cirq.Operation`
    """
    qb_pos = [mapping[qb.id] for qr in cmd.qubits for qb in qr]
    assert len(qb_pos) == 2
    cirqGate = cop.CZPowGate(exponent=cmd.gate.angle / cmath.pi)
    return cirqGate(*[qubits[idx] for idx in qb_pos])
Ejemplo n.º 4
0
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import List, Union, Sequence, Dict, Optional

import numpy as np

from cirq import ops
from cirq.circuits import Circuit

DEFAULT_GATE_DOMAIN: Dict[ops.Gate, int] = {
    ops.CNOT: 2,
    ops.CZ: 2,
    ops.H: 1,
    ops.ISWAP: 2,
    ops.CZPowGate(): 2,
    ops.S: 1,
    ops.SWAP: 2,
    ops.T: 1,
    ops.X: 1,
    ops.Y: 1,
    ops.Z: 1
}


def random_circuit(
        qubits: Union[Sequence[ops.Qid], int],
        n_moments: int,
        op_density: float,
        gate_domain: Optional[Dict[ops.Gate, int]] = None,
        random_state: Optional[Union[np.random.RandomState, int]] = None
def random_rotations_between_grid_interaction_layers_circuit(
    qubits: Iterable['cirq.GridQubit'],
    depth: int,
    *,  # forces keyword arguments
    two_qubit_op_factory: Callable[
        ['cirq.GridQubit', 'cirq.GridQubit', 'np.random.RandomState'],
        'cirq.OP_TREE'] = lambda a, b, _: ops.CZPowGate()(a, b),
    pattern: Sequence[GridInteractionLayer] = GRID_STAGGERED_PATTERN,
    single_qubit_gates: Sequence['cirq.Gate'] = (
        ops.X**0.5,
        ops.Y**0.5,
        ops.PhasedXPowGate(phase_exponent=0.25, exponent=0.5),
    ),
    add_final_single_qubit_layer: bool = True,
    seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
) -> 'cirq.Circuit':
    """Generate a random quantum circuit of a particular form.

    This construction is based on the circuits used in the paper
    https://www.nature.com/articles/s41586-019-1666-5.

    The generated circuit consists of a number of "cycles", this number being
    specified by `depth`. Each cycle is actually composed of two sub-layers:
    a layer of single-qubit gates followed by a layer of two-qubit gates,
    controlled by their respective arguments, see below. The pairs of qubits
    in a given entangling layer is controlled by the `pattern` argument,
    see below.

    Args:
        qubits: The qubits to use.
        depth: The number of cycles.
        two_qubit_op_factory: A callable that returns a two-qubit operation.
            These operations will be generated with calls of the form
            `two_qubit_op_factory(q0, q1, prng)`, where `prng` is the
            pseudorandom number generator.
        pattern: A sequence of GridInteractionLayers, each of which determine
            which pairs of qubits are entangled. The layers in a pattern are
            iterated through sequentially, repeating until `depth` is reached.
        single_qubit_gates: Single-qubit gates are selected randomly from this
            sequence. No qubit is acted upon by the same single-qubit gate in
            consecutive cycles. If only one choice of single-qubit gate is
            given, then this constraint is not enforced.
        add_final_single_qubit_layer: Whether to include a final layer of
            single-qubit gates after the last cycle.
        seed: A seed or random state to use for the pseudorandom number
            generator.
    """
    prng = value.parse_random_state(seed)
    qubits = list(qubits)
    coupled_qubit_pairs = _coupled_qubit_pairs(qubits)

    circuit = circuits.Circuit()
    previous_single_qubit_layer = circuits.Moment()
    single_qubit_layer_factory = _single_qubit_gates_arg_to_factory(
        single_qubit_gates=single_qubit_gates, qubits=qubits, prng=prng)

    for i in range(depth):
        single_qubit_layer = single_qubit_layer_factory.new_layer(
            previous_single_qubit_layer)
        circuit += single_qubit_layer

        two_qubit_layer = _two_qubit_layer(coupled_qubit_pairs,
                                           two_qubit_op_factory,
                                           pattern[i % len(pattern)], prng)
        circuit += two_qubit_layer
        previous_single_qubit_layer = single_qubit_layer

    if add_final_single_qubit_layer:
        circuit += single_qubit_layer_factory.new_layer(
            previous_single_qubit_layer)

    return circuit
def random_rotations_between_two_qubit_circuit(
    q0: 'cirq.Qid',
    q1: 'cirq.Qid',
    depth: int,
    two_qubit_op_factory: Callable[
        ['cirq.Qid', 'cirq.Qid', 'np.random.RandomState'],
        'cirq.OP_TREE'] = lambda a, b, _: ops.CZPowGate()(a, b),
    single_qubit_gates: Sequence['cirq.Gate'] = (
        ops.X**0.5,
        ops.Y**0.5,
        ops.PhasedXPowGate(phase_exponent=0.25, exponent=0.5),
    ),
    add_final_single_qubit_layer: bool = True,
    seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
) -> 'cirq.Circuit':
    """Generate a random two-qubit quantum circuit.

    This construction uses a similar structure to those in the paper
    https://www.nature.com/articles/s41586-019-1666-5.

    The generated circuit consists of a number of "cycles", this number being
    specified by `depth`. Each cycle is actually composed of two sub-layers:
    a layer of single-qubit gates followed by a layer of two-qubit gates,
    controlled by their respective arguments, see below.

    Args:
        q0: The first qubit
        q1: The second qubit
        depth: The number of cycles.
        two_qubit_op_factory: A callable that returns a two-qubit operation.
            These operations will be generated with calls of the form
            `two_qubit_op_factory(q0, q1, prng)`, where `prng` is the
            pseudorandom number generator.
        single_qubit_gates: Single-qubit gates are selected randomly from this
            sequence. No qubit is acted upon by the same single-qubit gate in
            consecutive cycles. If only one choice of single-qubit gate is
            given, then this constraint is not enforced.
        add_final_single_qubit_layer: Whether to include a final layer of
            single-qubit gates after the last cycle (subject to the same
            non-consecutivity constraint).
        seed: A seed or random state to use for the pseudorandom number
            generator.
    """
    prng = value.parse_random_state(seed)

    circuit = circuits.Circuit()
    previous_single_qubit_layer = circuits.Moment()
    single_qubit_layer_factory = _single_qubit_gates_arg_to_factory(
        single_qubit_gates=single_qubit_gates, qubits=(q0, q1), prng=prng)

    for _ in range(depth):
        single_qubit_layer = single_qubit_layer_factory.new_layer(
            previous_single_qubit_layer)
        circuit += single_qubit_layer
        circuit += two_qubit_op_factory(q0, q1, prng)
        previous_single_qubit_layer = single_qubit_layer

    if add_final_single_qubit_layer:
        circuit += single_qubit_layer_factory.new_layer(
            previous_single_qubit_layer)

    return circuit
Ejemplo n.º 7
0
        protocols.unitary(test_circuit),
        protocols.unitary(cirq_circuit),
        atol=1e-7,
    )

    # Cirq AAPowGate has a different global phase than braket AA which gets
    # lost in translation. Here, AA = XX, YY, or ZZ.
    if not isinstance(common_gate,
                      (ops.XXPowGate, ops.YYPowGate, ops.ZZPowGate)):
        assert _equal(test_circuit, cirq_circuit, require_qubit_equality=True)


@pytest.mark.parametrize(
    "uncommon_gate",
    [ops.CNotPowGate(exponent=-1 / 17),
     ops.CZPowGate(exponent=2 / 7)],
)
def test_to_from_braket_uncommon_two_qubit_gates(uncommon_gate):
    """These gates get decomposed when converting Cirq -> Braket -> Cirq, but
    the unitaries should be equal up to global phase.
    """
    cirq_circuit = Circuit(uncommon_gate.on(*LineQubit.range(2)))
    test_circuit = from_braket(to_braket(cirq_circuit))

    testing.assert_allclose_up_to_global_phase(
        protocols.unitary(test_circuit),
        protocols.unitary(cirq_circuit),
        atol=1e-7,
    )

Ejemplo n.º 8
0
        protocols.unitary(test_circuit),
        protocols.unitary(cirq_circuit),
        atol=1e-7,
    )

    # Cirq AAPowGate has a different global phase than braket AA which gets
    # lost in translation. Here, AA = XX, YY, or ZZ.
    if not isinstance(
        common_gate, (ops.XXPowGate, ops.YYPowGate, ops.ZZPowGate)
    ):
        assert _equal(test_circuit, cirq_circuit, require_qubit_equality=True)


@pytest.mark.parametrize(
    "uncommon_gate",
    [ops.CNotPowGate(exponent=-1 / 17), ops.CZPowGate(exponent=2 / 7)],
)
def test_to_from_braket_uncommon_two_qubit_gates(uncommon_gate):
    """These gates get decomposed when converting Cirq -> Braket -> Cirq, but
    the unitaries should be equal up to global phase.
    """
    cirq_circuit = Circuit(uncommon_gate.on(*LineQubit.range(2)))
    test_circuit = from_braket(to_braket(cirq_circuit))

    testing.assert_allclose_up_to_global_phase(
        protocols.unitary(test_circuit),
        protocols.unitary(cirq_circuit),
        atol=1e-7,
    )