Exemplo n.º 1
0
def test_teleportation_diagram():
    ali = ops.NamedQubit('alice')
    car = ops.NamedQubit('carrier')
    bob = ops.NamedQubit('bob')

    circuit = Circuit.from_ops(
        ops.H(car),
        ops.CNOT(car, bob),
        ops.X(ali)**0.5,
        ops.CNOT(ali, car),
        ops.H(ali),
        [ops.measure(ali), ops.measure(car)],
        ops.CNOT(car, bob),
        ops.CZ(ali, bob))

    diagram = circuit_to_latex_using_qcircuit(
        circuit,
        qubit_order=ops.QubitOrder.explicit([ali, car, bob]))
    assert diagram.strip() == """
\\Qcircuit @R=1em @C=0.75em { \\\\ 
 \\lstick{\\text{alice}}& \\qw &\\qw & \\gate{\\text{X}^{0.5}} \\qw & \\control \\qw & \\gate{\\text{H}} \\qw & \\meter \\qw &\\qw & \\control \\qw &\\qw\\\\
 \\lstick{\\text{carrier}}& \\qw & \\gate{\\text{H}} \\qw & \\control \\qw & \\targ \\qw \\qwx &\\qw & \\meter \\qw & \\control \\qw &\\qw \\qwx &\\qw\\\\
 \\lstick{\\text{bob}}& \\qw &\\qw & \\targ \\qw \\qwx &\\qw &\\qw &\\qw & \\targ \\qw \\qwx & \\control \\qw \\qwx &\\qw \\\\ 
 \\\\ }
        """.strip()
Exemplo n.º 2
0
def test_inverse_of_invertible_op_tree():
    def rev_freeze(root):
        return ops.freeze_op_tree(ops.inverse_of_invertible_op_tree(root))

    operations = [
        ops.Operation(_FlipGate(i), [ops.NamedQubit(str(i))])
        for i in range(10)
    ]
    expected = [
        ops.Operation(_FlipGate(~i), [ops.NamedQubit(str(i))])
        for i in range(10)
    ]

    # Just an item.
    assert rev_freeze(operations[0]) == expected[0]

    # Flat list.
    assert rev_freeze(operations) == tuple(expected[::-1])

    # Tree.
    assert (rev_freeze(
        (operations[1:5], operations[0],
         operations[5:])) == (tuple(expected[5:][::-1]), expected[0],
                              tuple(expected[1:5][::-1])))

    # Flattening after reversing is equivalent to reversing then flattening.
    t = (operations[1:5], operations[0], operations[5:])
    assert (tuple(ops.flatten_op_tree(rev_freeze(t))) == tuple(
        rev_freeze(ops.flatten_op_tree(t))))
Exemplo n.º 3
0
def test_init():
    r = ScheduledOperation(time=Timestamp(picos=5),
                           duration=Duration(picos=7),
                           operation=ops.Operation(ops.H,
                                                   [ops.NamedQubit('a')]))
    assert r.time == Timestamp(picos=5)
    assert r.duration == Duration(picos=7)
    assert r.operation == ops.Operation(ops.H, [ops.NamedQubit('a')])
Exemplo n.º 4
0
def test_text_diagrams():
    a = ops.NamedQubit('a')
    b = ops.NamedQubit('b')
    circuit = Circuit.from_ops(ops.SWAP(a, b), ops.X(a), ops.Y(a), ops.Z(a),
                               ops.CZ(a, b), ops.CNOT(a, b), ops.CNOT(b, a),
                               ops.H(a))
    assert circuit.to_text_diagram().strip() == """
a: ───×───X───Y───Z───@───@───X───H───
      │               │   │   │
b: ───×───────────────@───X───@───────
    """.strip()
Exemplo n.º 5
0
def test_measure_each():
    a = ops.NamedQubit('a')
    b = ops.NamedQubit('b')

    assert cirq.measure_each() == []
    assert cirq.measure_each(a) == [cirq.measure(a)]
    assert cirq.measure_each(a, b) == [cirq.measure(a), cirq.measure(b)]

    assert cirq.measure_each(a, b, key_func=lambda e: e.name + '!') == [
        cirq.measure(a, key='a!'),
        cirq.measure(b, key='b!')
    ]
Exemplo n.º 6
0
def test_measurement_qubit_count_vs_mask_length():
    a = ops.NamedQubit('a')
    b = ops.NamedQubit('b')
    c = ops.NamedQubit('c')

    _ = cirq.MeasurementGate(invert_mask=(True, )).on(a)
    _ = cirq.MeasurementGate(invert_mask=(True, False)).on(a, b)
    _ = cirq.MeasurementGate(invert_mask=(True, False, True)).on(a, b, c)
    with pytest.raises(ValueError):
        _ = cirq.MeasurementGate(invert_mask=(True, False)).on(a)
    with pytest.raises(ValueError):
        _ = cirq.MeasurementGate(invert_mask=(True, False, True)).on(a, b)
Exemplo n.º 7
0
def test_measure():
    a = ops.NamedQubit('a')
    b = ops.NamedQubit('b')

    # Empty application.
    with pytest.raises(ValueError):
        _ = cirq.measure()

    assert cirq.measure(a) == cirq.MeasurementGate(key='a').on(a)
    assert cirq.measure(a, b) == cirq.MeasurementGate(key='a,b').on(a, b)
    assert cirq.measure(b, a) == cirq.MeasurementGate(key='b,a').on(b, a)
    assert cirq.measure(a, key='b') == cirq.MeasurementGate(key='b').on(a)
    assert cirq.measure(a, invert_mask=(True, )) == cirq.MeasurementGate(
        key='a', invert_mask=(True, )).on(a)
Exemplo n.º 8
0
def test_interchangeable_qubit_eq():
    a = ops.NamedQubit('a')
    b = ops.NamedQubit('b')
    c = ops.NamedQubit('c')
    eq = EqualsTester()

    eq.add_equality_group(ops.SWAP(a, b), ops.SWAP(b, a))
    eq.add_equality_group(ops.SWAP(a, c))

    eq.add_equality_group(ops.CZ(a, b), ops.CZ(b, a))
    eq.add_equality_group(ops.CZ(a, c))

    eq.add_equality_group(ops.CNOT(a, b))
    eq.add_equality_group(ops.CNOT(b, a))
    eq.add_equality_group(ops.CNOT(a, c))
Exemplo n.º 9
0
def random_circuit(
        qubits: Union[Sequence[ops.Qid], int],
        n_moments: int,
        op_density: float,
        gate_domain: Optional[Dict[ops.Gate, int]] = None) -> Circuit:
    """Generates a random circuit.

    Args:
        qubits: the qubits that the circuit acts on. Because the qubits on
            which an operation acts are chosen randomly, not all given qubits
            may be acted upon.
        n_moments: the number of moments in the generated circuit.
        op_density: the expected proportion of qubits that are acted on in any
            moment.
        gate_domain: The set of gates to choose from, with a specified arity.

    Raises:
        ValueError:
            * op_density is not in (0, 1).
            * gate_domain is empty.
            * qubits is an int less than 1 or an empty sequence.

    Returns:
        The randomly generated Circuit.
    """
    if not 0 < op_density < 1:
        raise ValueError('op_density must be in (0, 1).')
    if gate_domain is None:
        gate_domain = DEFAULT_GATE_DOMAIN
    if not gate_domain:
        raise ValueError('gate_domain must be non-empty')
    max_arity = max(gate_domain.values())

    if isinstance(qubits, int):
        qubits = tuple(ops.NamedQubit(str(i)) for i in range(qubits))
    n_qubits = len(qubits)
    if n_qubits < 1:
        raise ValueError('At least one qubit must be specified.')

    moments: List[ops.Moment] = []
    for _ in range(n_moments):
        operations = []
        free_qubits = set(q for q in qubits)
        while len(free_qubits) >= max_arity:
            gate, arity = choice(tuple(gate_domain.items()))
            op_qubits = sample(free_qubits, arity)
            free_qubits.difference_update(op_qubits)
            if random() <= op_density:
                operations.append(gate(*op_qubits))
        moments.append(ops.Moment(operations))

    return Circuit(moments)
Exemplo n.º 10
0
def test_works_with_basic_gates():
    a = ops.NamedQubit('a')
    b = ops.NamedQubit('b')

    basics = [
        ops.X(a),
        ops.Y(a)**0.5,
        ops.Z(a),
        ops.CZ(a, b)**-0.25,
        ops.CNOT(a, b),
        ops.H(b),
        ops.SWAP(a, b)
    ]
    assert list(ops.inverse_of_invertible_op_tree(basics)) == [
        ops.SWAP(a, b),
        ops.H(b),
        ops.CNOT(a, b),
        ops.CZ(a, b)**0.25,
        ops.Z(a),
        ops.Y(a)**-0.5,
        ops.X(a),
    ]
Exemplo n.º 11
0
def random_two_qubit_circuit_with_czs(
    num_czs: int = 3,
    q0: Qid = None,
    q1: Qid = None,
    random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
) -> circuits.Circuit:
    """Creates a random two qubit circuit with the given number of CNOTs.

    The resulting circuit will have `num_cnots` number of CNOTs that will be
    surrounded by random `PhasedXPowGate` instances on both qubits.

    Args:
         num_czs: the number of CNOTs to be guaranteed in the circuit
         q0: the first qubit the circuit should operate on
         q1: the second qubit the circuit should operate on
         random_state: an optional random seed
    Returns:
         the random two qubit circuit
    """
    prng = value.parse_random_state(random_state)
    q0 = ops.NamedQubit('q0') if q0 is None else q0
    q1 = ops.NamedQubit('q1') if q1 is None else q1

    def random_one_qubit_gate():
        return ops.PhasedXPowGate(phase_exponent=prng.rand(),
                                  exponent=prng.rand())

    def one_cz():
        return [
            ops.CZ.on(q0, q1),
            random_one_qubit_gate().on(q0),
            random_one_qubit_gate().on(q1),
        ]

    return circuits.Circuit([
        random_one_qubit_gate().on(q0),
        random_one_qubit_gate().on(q1),
        [one_cz() for _ in range(num_czs)],
    ])
Exemplo n.º 12
0
def named_qubit_from_proto_id(proto_id: str) -> 'cirq.NamedQubit':
    """Parse a proto id to a `cirq.NamedQubit'

    This simply returns a `cirq.NamedQubit` with a name equal to `proto_id`.
    """
    return ops.NamedQubit(proto_id)
Exemplo n.º 13
0
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
) -> Circuit:
    """Generates a random circuit.

    Args:
        qubits: If a sequence of qubits, then these are the qubits that
            the circuit should act on. Because the qubits on which an
            operation acts are chosen randomly, not all given qubits
            may be acted upon. If an int, then this number of qubits will
            be automatically generated.
        n_moments: the number of moments in the generated circuit.
        op_density: the expected proportion of qubits that are acted on in any
            moment.
        gate_domain: The set of gates to choose from, with a specified arity.
        random_state: Random state or random state seed.

    Raises:
        ValueError:
            * op_density is not in (0, 1).
            * gate_domain is empty.
            * qubits is an int less than 1 or an empty sequence.

    Returns:
        The randomly generated Circuit.
    """
    if not 0 < op_density < 1:
        raise ValueError('op_density must be in (0, 1).')
    if gate_domain is None:
        gate_domain = DEFAULT_GATE_DOMAIN
    if not gate_domain:
        raise ValueError('gate_domain must be non-empty')
    max_arity = max(gate_domain.values())

    if isinstance(qubits, int):
        qubits = tuple(ops.NamedQubit(str(i)) for i in range(qubits))
    n_qubits = len(qubits)
    if n_qubits < 1:
        raise ValueError('At least one qubit must be specified.')

    if random_state is None:
        prng = np.random
    elif isinstance(random_state, np.random.RandomState):
        prng = random_state
    else:
        prng = np.random.RandomState(random_state)

    moments: List[ops.Moment] = []
    gate_arity_pairs = tuple(gate_domain.items())
    num_gates = len(gate_domain)
    for _ in range(n_moments):
        operations = []
        free_qubits = set(qubits)
        while len(free_qubits) >= max_arity:
            gate, arity = gate_arity_pairs[prng.randint(num_gates)]
            op_qubits = prng.choice(list(free_qubits),
                                    size=arity,
                                    replace=False)
            free_qubits.difference_update(op_qubits)
            if prng.rand() <= op_density:
                operations.append(gate(*op_qubits))
        moments.append(ops.Moment(operations))

    return Circuit(moments)
Exemplo n.º 14
0
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: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
) -> circuits.Circuit:
    """Generates a random circuit.

    Args:
        qubits: If a sequence of qubits, then these are the qubits that
            the circuit should act on. Because the qubits on which an
            operation acts are chosen randomly, not all given qubits
            may be acted upon. If an int, then this number of qubits will
            be automatically generated, and the qubits will be
            `cirq.NamedQubits` with names given by the integers in
            `range(qubits)`.
        n_moments: The number of moments in the generated circuit.
        op_density: The probability that a gate is selected to operate on
            randomly selected qubits. Note that this is not the expected number
            of qubits that are acted on, since there are cases where the
            number of qubits that a gate acts on does not evenly divide the
            total number of qubits.
        gate_domain: The set of gates to choose from, specified as a dictionary
            where each key is a gate and the value of the key is the number of
            qubits the gate acts on. If not provided, the default gate domain is
            {X, Y, Z, H, S, T, CNOT, CZ, SWAP, ISWAP, CZPowGate()}. Only gates
            which act on a number of qubits less than len(qubits) (or qubits if
            provided as an int) are selected from the gate domain.
        random_state: Random state or random state seed.

    Raises:
        ValueError:
            * op_density is not in (0, 1].
            * gate_domain is empty.
            * qubits is an int less than 1 or an empty sequence.

    Returns:
        The randomly generated Circuit.
    """
    if not 0 < op_density <= 1:
        raise ValueError(f'op_density must be in (0, 1] but was {op_density}.')
    if gate_domain is None:
        gate_domain = DEFAULT_GATE_DOMAIN
    if not gate_domain:
        raise ValueError('gate_domain must be non-empty.')

    if isinstance(qubits, int):
        qubits = tuple(ops.NamedQubit(str(i)) for i in range(qubits))
    n_qubits = len(qubits)
    if n_qubits < 1:
        raise ValueError('At least one qubit must be specified.')
    gate_domain = {k: v for k, v in gate_domain.items() if v <= n_qubits}
    if not gate_domain:
        raise ValueError(f'After removing gates that act on less than '
                         f'{n_qubits} qubits, gate_domain had no gates.')
    max_arity = max(gate_domain.values())

    prng = value.parse_random_state(random_state)

    moments: List[circuits.Moment] = []
    gate_arity_pairs = sorted(gate_domain.items(), key=repr)
    num_gates = len(gate_domain)
    for _ in range(n_moments):
        operations = []
        free_qubits = set(qubits)
        while len(free_qubits) >= max_arity:
            gate, arity = gate_arity_pairs[prng.randint(num_gates)]
            op_qubits = prng.choice(sorted(free_qubits),
                                    size=arity,
                                    replace=False)
            free_qubits.difference_update(op_qubits)
            if prng.rand() <= op_density:
                operations.append(gate(*op_qubits))
        moments.append(circuits.Moment(operations))

    return circuits.Circuit(moments)