Esempio n. 1
0
def _xx_interaction_via_full_czs(q0: 'cirq.Qid', q1: 'cirq.Qid', x: float):
    a = x * -2 / np.pi
    yield ops.H(q1)
    yield ops.CZ(q0, q1)
    yield ops.X(q0)**a
    yield ops.CZ(q0, q1)
    yield ops.H(q1)
Esempio n. 2
0
def _xx_interaction_via_full_czs(q0: ops.QubitId, q1: ops.QubitId, x: float):
    a = x * -2 / np.pi
    yield ops.H(q1)
    yield ops.CZ(q0, q1)
    yield ops.X(q0)**a
    yield ops.CZ(q0, q1)
    yield ops.H(q1)
Esempio n. 3
0
def test_moment_by_moment_schedule_device_validation_fails():
    device = _TestDevice()
    qubits = device.qubits
    circuit = Circuit(
        [Moment([ops.CZ(qubits[0], qubits[1]),
                 ops.CZ(qubits[2], qubits[3])])])
    with pytest.raises(ValueError, match="Adjacent CZ"):
        _ = moment_by_moment_schedule(device, circuit)
Esempio n. 4
0
def test_ignores_2qubit_target():
    m = MergeRotations(0.000001)
    q = ops.QubitId()
    q2 = ops.QubitId()
    c = circuits.Circuit([
        circuits.Moment([ops.CZ(q, q2)]),
    ])

    m.optimization_at(c, 0, c.operation_at(q, 0))

    assert c == circuits.Circuit([circuits.Moment([ops.CZ(q, q2)])])
Esempio n. 5
0
def test_czs_separated_by_single_gates_correct():
    q0 = ops.QubitId()
    q1 = ops.QubitId()
    assert_optimization_not_broken(
        circuits.Circuit.from_ops(
            ops.CZ(q0, q1),
            ops.X(q1),
            ops.X(q1),
            ops.X(q1),
            ops.CZ(q0, q1),
        ))
Esempio n. 6
0
def test_moment_by_moment_schedule_moment_of_two_qubit_ops():
    device = _TestDevice()
    qubits = device.qubits

    circuit = Circuit(
        [Moment((ops.CZ(qubits[i], qubits[i + 1]) for i in range(0, 9, 3)))])
    schedule = moment_by_moment_schedule(device, circuit)

    zero_ns = cirq.Timestamp()
    expected = set(
        ScheduledOperation.op_at_on(ops.CZ(qubits[i], qubits[i + 1]), zero_ns,
                                    device) for i in range(0, 9, 3))
    assert set(schedule.scheduled_operations) == expected
Esempio n. 7
0
def _xx_yy_interaction_via_full_czs(q0: 'cirq.Qid', q1: 'cirq.Qid', x: float, y: float):
    a = x * -2 / np.pi
    b = y * -2 / np.pi
    yield ops.X(q0) ** 0.5
    yield ops.H(q1)
    yield ops.CZ(q0, q1)
    yield ops.H(q1)
    yield ops.X(q0) ** a
    yield ops.Y(q1) ** b
    yield ops.H(q1)
    yield ops.CZ(q0, q1)
    yield ops.H(q1)
    yield ops.X(q0) ** -0.5
Esempio 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))
Esempio n. 9
0
def xmon_op_from_proto(proto: operations_pb2.Operation) -> 'cirq.Operation':
    """Convert the proto to the corresponding operation.

    See protos in api/google/v1 for specification of the protos.

    Args:
        proto: Operation proto.

    Returns:
        The operation.
    """
    param = _parameterized_value_from_proto
    qubit = _qubit_from_proto
    if proto.HasField('exp_w'):
        exp_w = proto.exp_w
        return ops.PhasedXPowGate(
            exponent=param(exp_w.half_turns),
            phase_exponent=param(exp_w.axis_half_turns),
        ).on(qubit(exp_w.target))
    if proto.HasField('exp_z'):
        exp_z = proto.exp_z
        return ops.Z(qubit(exp_z.target))**param(exp_z.half_turns)
    if proto.HasField('exp_11'):
        exp_11 = proto.exp_11
        return ops.CZ(qubit(exp_11.target1),
                      qubit(exp_11.target2))**param(exp_11.half_turns)
    if proto.HasField('measurement'):
        meas = proto.measurement
        return ops.MeasurementGate(num_qubits=len(meas.targets),
                                   key=meas.key,
                                   invert_mask=tuple(meas.invert_mask)).on(
                                       *[qubit(q) for q in meas.targets])

    raise ValueError(f'invalid operation: {proto}')
Esempio n. 10
0
def controlled_op_to_operations(control: ops.QubitId,
                                target: ops.QubitId,
                                operation: np.ndarray,
                                tolerance: float = 0.0) -> List[ops.Operation]:
    """Decomposes a controlled single-qubit operation into Z/XY/CZ gates.

    Args:
        control: The control qubit.
        target: The qubit to apply an operation to, when the control is on.
        operation: The single-qubit operation being controlled.
        tolerance: A limit on the amount of error introduced by the
            construction.

    Returns:
        A list of Operations that apply the controlled operation.
    """
    u, z_phase, global_phase = single_qubit_op_to_framed_phase_form(operation)
    if abs(z_phase - 1) <= tolerance:
        return []

    u_gates = single_qubit_matrix_to_gates(u, tolerance)
    if u_gates and isinstance(u_gates[-1], ops.ZPowGate):
        # Don't keep border operations that commute with CZ.
        del u_gates[-1]

    ops_before = [gate(target) for gate in u_gates]
    ops_after = protocols.inverse(ops_before)
    effect = ops.CZ(control, target)**(cmath.phase(z_phase) / math.pi)
    kickback = ops.Z(control)**(cmath.phase(global_phase) / math.pi)

    return list(
        ops.flatten_op_tree(
            (ops_before, effect,
             kickback if abs(global_phase - 1) > tolerance else [],
             ops_after)))
Esempio n. 11
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()
    def _decompose_(self, qubits):
        """
		Implements the decomposition of Draper provided in https://arxiv.org/pdf/quant-ph/0008033.pdf

		Args:
			qubits: |qubits| = 2 * self.size_of_inputs, in order a0 a1 ... an b0 b1 ... bn

		"""

        # For slicing
        qubits = list(qubits)

        assert len(
            qubits
        ) == 2 * self._size_of_inputs, f'A and B must be of the same length.'

        # A and B register appear in order
        A = qubits[:self._size_of_inputs]
        B = qubits[self._size_of_inputs:][::-1]

        yield self._apply_qft(A)

        A = A[::-1]

        for i in range(self._size_of_inputs):
            for j in range(i, self._size_of_inputs):
                yield ops.CZ(B[j], A[j - i])**(2 * 1 / (2**(i + 1)))

        A = A[::-1]

        yield cirq.inverse(self._apply_qft(A))
Esempio n. 13
0
def test_from_braket_non_parameterized_two_qubit_gates():
    braket_circuit = BKCircuit()
    instructions = [
        Instruction(braket_gates.CNot(), target=[2, 3]),
        Instruction(braket_gates.Swap(), target=[3, 4]),
        Instruction(braket_gates.ISwap(), target=[2, 3]),
        Instruction(braket_gates.CZ(), target=(3, 4)),
        Instruction(braket_gates.CY(), target=(2, 3)),
    ]
    for instr in instructions:
        braket_circuit.add_instruction(instr)
    cirq_circuit = from_braket(braket_circuit)

    qreg = LineQubit.range(2, 5)
    expected_cirq_circuit = Circuit(
        ops.CNOT(*qreg[:2]),
        ops.SWAP(*qreg[1:]),
        ops.ISWAP(*qreg[:2]),
        ops.CZ(*qreg[1:]),
        ops.ControlledGate(ops.Y).on(*qreg[:2]),
    )
    assert np.allclose(
        protocols.unitary(cirq_circuit),
        protocols.unitary(expected_cirq_circuit),
    )
Esempio n. 14
0
def test_controlled_op_to_gates_omits_negligible_global_phase():
    qc = ops.QubitId()
    qt = ops.QubitId()
    operations = decompositions.controlled_op_to_native_gates(
        control=qc, target=qt, operation=ops.H.matrix(), tolerance=0.0001)

    assert operations == [ops.Y(qt)**-0.25, ops.CZ(qc, qt), ops.Y(qt)**0.25]
Esempio n. 15
0
def test_qubits():
    a = ops.QubitId()
    b = ops.QubitId()

    assert Moment([ops.X(a), ops.X(b)]).qubits == {a , b}
    assert Moment([ops.X(a)]).qubits == {a}
    assert Moment([ops.CZ(a, b)]).qubits == {a, b}
Esempio n. 16
0
def test_copy():
    a = ops.QubitId()
    b = ops.QubitId()
    original = Moment([ops.CZ(a, b)])
    copy = original.__copy__()
    assert original == copy
    assert id(original) != id(copy)
Esempio n. 17
0
def _parity_interaction(q0: 'cirq.Qid',
                        q1: 'cirq.Qid',
                        rads: float,
                        atol: float,
                        gate: Optional[ops.Gate] = None):
    """Yields a ZZ interaction framed by the given operation."""
    if abs(rads) < atol:
        return

    h = rads * -2 / np.pi
    if gate is not None:
        g = cast(ops.Gate, gate)
        yield g.on(q0), g.on(q1)

    # If rads is ±pi/4 radians within tolerance, single full-CZ suffices.
    if _is_trivial_angle(rads, atol):
        yield ops.CZ.on(q0, q1)
    else:
        yield ops.CZ(q0, q1)**(-2 * h)

    yield ops.Z(q0)**h
    yield ops.Z(q1)**h
    if gate is not None:
        g = protocols.inverse(gate)
        yield g.on(q0), g.on(q1)
Esempio n. 18
0
def test_ignores_czs_separated_by_parameterized():
    q0 = ops.QubitId()
    q1 = ops.QubitId()
    assert_optimizes(
        before=circuits.Circuit([
            circuits.Moment([ops.CZ(q0, q1)]),
            circuits.Moment([ExpZGate(
                half_turns=Symbol('boo'))(q0)]),
            circuits.Moment([ops.CZ(q0, q1)]),
        ]),
        after=circuits.Circuit([
            circuits.Moment([ops.CZ(q0, q1)]),
            circuits.Moment([ExpZGate(
                half_turns=Symbol('boo'))(q0)]),
            circuits.Moment([ops.CZ(q0, q1)]),
        ]))
Esempio n. 19
0
def _parity_interaction(q0: ops.QubitId,
                        q1: ops.QubitId,
                        rads: float,
                        tolerance: float,
                        gate: Optional[ops.ReversibleEffect] = None):
    """Yields a ZZ interaction framed by the given operation."""
    if abs(rads) < tolerance:
        return

    h = rads * -2 / np.pi
    if gate is not None:
        g = cast(ops.Gate, gate)
        yield g.on(q0), g.on(q1)

    # If rads is ±pi/4 radians within tolerance, single full-CZ suffices.
    if _is_trivial_angle(rads, tolerance):
        yield ops.CZ.on(q0, q1)
    else:
        yield ops.CZ(q0, q1)**(-2 * h)

    yield ops.Z(q0)**h
    yield ops.Z(q1)**h
    if gate is not None:
        g = cast(ops.Gate, gate.inverse())
        yield g.on(q0), g.on(q1)
Esempio n. 20
0
def xmon_op_from_proto_dict(proto_dict: Dict) -> 'cirq.Operation':
    """Convert the proto dictionary to the corresponding operation.

    See protos in api/google/v1 for specification of the protos.

    Args:
        proto_dict: Dictionary representing the proto. Keys are always
            strings, but values may be types correspond to a raw proto type
            or another dictionary (for messages).

    Returns:
        The operation.

    Raises:
        ValueError if the dictionary does not contain required values
        corresponding to the proto.
    """
    def raise_missing_fields(gate_name: str):
        raise ValueError('{} missing required fields: {}'.format(
            gate_name, proto_dict))

    param = _parameterized_value_from_proto_dict
    qubit = _qubit_from_proto_dict
    if 'exp_w' in proto_dict:
        exp_w = proto_dict['exp_w']
        if ('half_turns' not in exp_w or 'axis_half_turns' not in exp_w
                or 'target' not in exp_w):
            raise_missing_fields('ExpW')
        return ops.PhasedXPowGate(
            exponent=param(exp_w['half_turns']),
            phase_exponent=param(exp_w['axis_half_turns']),
        ).on(qubit(exp_w['target']))
    if 'exp_z' in proto_dict:
        exp_z = proto_dict['exp_z']
        if 'half_turns' not in exp_z or 'target' not in exp_z:
            raise_missing_fields('ExpZ')
        return ops.Z(qubit(exp_z['target']))**param(exp_z['half_turns'])
    if 'exp_11' in proto_dict:
        exp_11 = proto_dict['exp_11']
        if ('half_turns' not in exp_11 or 'target1' not in exp_11
                or 'target2' not in exp_11):
            raise_missing_fields('Exp11')
        return ops.CZ(qubit(exp_11['target1']),
                      qubit(exp_11['target2']))**param(exp_11['half_turns'])
    if 'measurement' in proto_dict:
        meas = proto_dict['measurement']
        invert_mask = cast(Tuple[Any, ...], ())
        if 'invert_mask' in meas:
            invert_mask = tuple(
                _load_json_bool(x) for x in meas['invert_mask'])
        if 'key' not in meas or 'targets' not in meas:
            raise_missing_fields('Measurement')
        return ops.MeasurementGate(
            num_qubits=len(meas['targets']),
            key=meas['key'],
            invert_mask=invert_mask).on(*[qubit(q) for q in meas['targets']])

    raise ValueError('invalid operation: {}'.format(proto_dict))
Esempio n. 21
0
def test_operates_on():
    a = ops.QubitId()
    b = ops.QubitId()
    c = ops.QubitId()

    # Empty case.
    assert not Moment().operates_on([])
    assert not Moment().operates_on([a])
    assert not Moment().operates_on([b])
    assert not Moment().operates_on([a, b])

    # One-qubit operation case.
    assert not Moment([ops.X(a)]).operates_on([])
    assert Moment([ops.X(a)]).operates_on([a])
    assert not Moment([ops.X(a)]).operates_on([b])
    assert Moment([ops.X(a)]).operates_on([a, b])

    # Two-qubit operation case.
    assert not Moment([ops.CZ(a, b)]).operates_on([])
    assert Moment([ops.CZ(a, b)]).operates_on([a])
    assert Moment([ops.CZ(a, b)]).operates_on([b])
    assert Moment([ops.CZ(a, b)]).operates_on([a, b])
    assert not Moment([ops.CZ(a, b)]).operates_on([c])
    assert Moment([ops.CZ(a, b)]).operates_on([a, c])
    assert Moment([ops.CZ(a, b)]).operates_on([a, b, c])

    # Multiple operations case.
    assert not Moment([ops.X(a), ops.X(b)]).operates_on([])
    assert Moment([ops.X(a), ops.X(b)]).operates_on([a])
    assert Moment([ops.X(a), ops.X(b)]).operates_on([b])
    assert Moment([ops.X(a), ops.X(b)]).operates_on([a, b])
    assert not Moment([ops.X(a), ops.X(b)]).operates_on([c])
    assert Moment([ops.X(a), ops.X(b)]).operates_on([a, c])
    assert Moment([ops.X(a), ops.X(b)]).operates_on([a, b, c])
    def _apply_qft(register):
        """
		applies the qft to the register according to https://arxiv.org/pdf/quant-ph/0008033.pdf
		"""
        rreg = register[::-1]
        for i, q in enumerate(rreg):
            yield ops.H(q)
            for j in range(i + 1, len(rreg)):
                yield ops.CZ(rreg[j], q)**(2 * 1 / (2**(j + 1)))
Esempio n. 23
0
def _xx_yy_zz_interaction_via_full_czs(q0: 'cirq.Qid', q1: 'cirq.Qid',
                                       x: float, y: float, z: float):
    a = x * -2 / np.pi + 0.5
    b = y * -2 / np.pi + 0.5
    c = z * -2 / np.pi + 0.5
    yield ops.X(q0)**0.5
    yield ops.H(q1)
    yield ops.CZ(q0, q1)
    yield ops.H(q1)
    yield ops.X(q0)**a
    yield ops.Y(q1)**b
    yield ops.H.on(q0)
    yield ops.CZ(q1, q0)
    yield ops.H(q0)
    yield ops.X(q1)**-0.5
    yield ops.Z(q1)**c
    yield ops.H(q1)
    yield ops.CZ(q0, q1)
    yield ops.H(q1)
Esempio n. 24
0
def test_moment_by_moment_schedule_max_duration():
    device = _TestDevice()
    qubits = device.qubits

    circuit = Circuit([
        Moment([ops.H(qubits[0]),
                ops.CZ(qubits[1], qubits[2])]),
        Moment([ops.H(qubits[0])])
    ])
    schedule = moment_by_moment_schedule(device, circuit)

    zero_ns = cirq.Timestamp()
    fourty_ns = cirq.Timestamp(nanos=40)
    assert set(schedule.scheduled_operations) == {
        ScheduledOperation.op_at_on(ops.H(qubits[0]), zero_ns, device),
        ScheduledOperation.op_at_on(ops.CZ(qubits[1], qubits[2]), zero_ns,
                                    device),
        ScheduledOperation.op_at_on(ops.H(qubits[0]), fourty_ns, device),
    }
Esempio n. 25
0
def test_moment_by_moment_schedule_two_moments():
    device = _TestDevice()
    qubits = device.qubits

    circuit = Circuit([
        Moment(ops.H(q) for q in qubits),
        Moment((ops.CZ(qubits[i], qubits[i + 1]) for i in range(0, 9, 3)))
    ])
    schedule = moment_by_moment_schedule(device, circuit)

    zero_ns = cirq.Timestamp()
    twenty_ns = cirq.Timestamp(nanos=20)
    expected_one_qubit = set(
        ScheduledOperation.op_at_on(ops.H(q), zero_ns, device) for q in qubits)
    expected_two_qubit = set(
        ScheduledOperation.op_at_on(ops.CZ(qubits[i], qubits[i + 1]),
                                    twenty_ns, device) for i in range(0, 9, 3))
    expected = expected_one_qubit.union(expected_two_qubit)
    assert set(schedule.scheduled_operations) == expected
Esempio n. 26
0
    def decompose_keep_func(self, op: ops.Operation) -> bool:
        # Keep CZs.
        if len(op.qubits) == 2 and op == ops.CZ(*op.qubits):
            return True

        # Keep within-group operation with a known unitary
        if self.all_in_same_group(*op.qubits):
            if protocols.unitary(op, None) is not None:
                return True

        return False
Esempio n. 27
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()
Esempio n. 28
0
def _easy_direction_partial_cz(q0: ops.QubitId, q1: ops.QubitId, t: float):
    """The actual hardware can only do CZs that phase counter-clockwise.

    This method replaces clockwise phase(t) to counter-clockwise.

    Args:
      q0: The first qubit being operated on.
      q1: The other qubit being operated on.
      t: The parameter to describe partial-CZ(CZ^t).

    Yields:
      Yields an equivalent circuit for CZ^t with counter-clock phased CZs.
    """
    if t >= 0:
        yield ops.CZ(q0, q1)**t
        return
    yield ops.Z(q0)**t
    yield ops.X(q1)
    yield ops.CZ(q0, q1)**(-t)
    yield ops.X(q1)
Esempio n. 29
0
def test_validation():
    a = ops.QubitId()
    b = ops.QubitId()
    c = ops.QubitId()
    d = ops.QubitId()

    _ = Moment([])
    _ = Moment([ops.X(a)])
    _ = Moment([ops.CZ(a, b)])
    _ = Moment([ops.CZ(b, d)])
    _ = Moment([ops.CZ(a, b), ops.CZ(c, d)])
    _ = Moment([ops.CZ(a, c), ops.CZ(b, d)])
    _ = Moment([ops.CZ(a, c), ops.X(b)])

    with pytest.raises(ValueError):
        _ = Moment([ops.X(a), ops.X(a)])
    with pytest.raises(ValueError):
        _ = Moment([ops.CZ(a, c), ops.X(c)])
    with pytest.raises(ValueError):
        _ = Moment([ops.CZ(a, c), ops.CZ(c, d)])
Esempio n. 30
0
def test_clears_known_empties_even_at_zero_tolerance():
    m = circuits.DropNegligible(0.001)
    q = ops.QubitId()
    q2 = ops.QubitId()
    c = circuits.Circuit.from_ops(
        ops.Z(q)**0,
        ops.Y(q)**0.0000001,
        ops.X(q)**-0.0000001,
        ops.CZ(q, q2)**0)

    m.optimize_circuit(c)
    assert c == circuits.Circuit([circuits.Moment()] * 4)