Example #1
0
def test_rot_gates_eq():
    eq = cirq.testing.EqualsTester()
    gates = [
        lambda p: cirq.CZ**p,
        lambda p: cirq.X**p,
        lambda p: cirq.Y**p,
        lambda p: cirq.Z**p,
        lambda p: cirq.CNOT**p,
    ]
    for gate in gates:
        eq.add_equality_group(gate(3.5),
                              gate(-0.5))
        eq.make_equality_group(lambda: gate(0))
        eq.make_equality_group(lambda: gate(0.5))

    eq.add_equality_group(cirq.XPowGate(), cirq.XPowGate(exponent=1), cirq.X)
    eq.add_equality_group(cirq.YPowGate(), cirq.YPowGate(exponent=1), cirq.Y)
    eq.add_equality_group(cirq.ZPowGate(), cirq.ZPowGate(exponent=1), cirq.Z)
    eq.add_equality_group(cirq.ZPowGate(exponent=1,
                                        global_shift=-0.5),
                          cirq.ZPowGate(exponent=5,
                                        global_shift=-0.5))
    eq.add_equality_group(cirq.ZPowGate(exponent=3,
                                        global_shift=-0.5))
    eq.add_equality_group(cirq.ZPowGate(exponent=1,
                                        global_shift=-0.1))
    eq.add_equality_group(cirq.ZPowGate(exponent=5,
                                        global_shift=-0.1))
    eq.add_equality_group(cirq.CNotPowGate(),
                          cirq.CNotPowGate(exponent=1),
                          cirq.CNOT)
    eq.add_equality_group(cirq.CZPowGate(),
                          cirq.CZPowGate(exponent=1), cirq.CZ)
Example #2
0
def test_is_pasqal_device_op():
    d = generic_device(2)

    with pytest.raises(ValueError, match="Got unknown operation"):
        d.is_pasqal_device_op(cirq.NamedQubit('q0'))

    op = (cirq.ops.CZ).on(*(d.qubit_list()))
    bad_op = cirq.ops.CNotPowGate(exponent=0.5)

    assert d.is_pasqal_device_op(op)
    assert d.is_pasqal_device_op(cirq.ops.X(cirq.NamedQubit('q0')))
    assert not d.is_pasqal_device_op(
        cirq.ops.CCX(cirq.NamedQubit('q0'), cirq.NamedQubit('q1'),
                     cirq.NamedQubit('q2'))**0.2)
    assert not d.is_pasqal_device_op(
        bad_op(cirq.NamedQubit('q0'), cirq.NamedQubit('q1')))
    for op1 in [
            cirq.CNotPowGate(exponent=1.0),
            cirq.CNotPowGate(exponent=1.0, global_shift=-0.5)
    ]:
        assert d.is_pasqal_device_op(
            op1(cirq.NamedQubit('q0'), cirq.NamedQubit('q1')))

    op2 = (cirq.ops.H**sympy.Symbol('exp')).on(d.qubit_list()[0])
    assert not d.is_pasqal_device_op(op2)

    d2 = square_virtual_device(control_r=1.1, num_qubits=3)
    assert d.is_pasqal_device_op(cirq.ops.X(TwoDQubit(0, 0)))
    assert not d2.is_pasqal_device_op(op1(TwoDQubit(0, 0), TwoDQubit(0, 1)))
Example #3
0
    def controlled(
            self,
            num_controls: int = None,
            control_values: Optional[Sequence[Union[int,
                                                    Collection[int]]]] = None,
            control_qid_shape: Optional[Tuple[int,
                                              ...]] = None) -> raw_types.Gate:
        """
        Constructs CNotPowGate from controlled XPowGate when applicable.

        This method is a specialized controlled method for XPowGate. It
        overrides the default behavior of returning a ControlledGate by
        transforming the underlying controlled gate to a CNotPowGate and
        removing the last specified control qubit (which acts first
        semantically).  If this is a gate with multiple control qubits, it will
        now be a ControlledGate with one less control.

        This behavior only occurs when the last control qubit is a default-type
        control qubit. A default-type control qubit is one with shape of 2 (not
        a generic qudit) and where the control is satisfied by the qubit being
        ON, as opposed to OFF.

        (Note that a CNotPowGate is, by definition, a controlled-XPowGate.)
        """
        result = super().controlled(num_controls, control_values,
                                    control_qid_shape)
        if (isinstance(result, controlled_gate.ControlledGate)
                and result.control_values[-1] == (1, )
                and result.control_qid_shape[-1] == 2):
            return cirq.CNotPowGate(
                exponent=self._exponent,
                global_shift=self._global_shift).controlled(
                    result.num_controls() - 1, result.control_values[:-1],
                    result.control_qid_shape[:-1])
        return result
def test_validate_gate_errors():
    d = square_device(1, 1)

    d.validate_gate(cirq.IdentityGate(4))
    with pytest.raises(ValueError, match="controlled gates must have integer exponents"):
        d.validate_gate(cirq.CNotPowGate(exponent=0.5))
    with pytest.raises(ValueError, match="Unsupported gate"):
        d.validate_gate(cirq.SingleQubitGate())
Example #5
0
 def get_default_noise_dict(self) -> Dict[str, Any]:
     """Returns the current noise parameters"""
     default_noise_dict = {
         str(cirq.YPowGate()): cirq.depolarize(1e-2),
         str(cirq.ZPowGate()): cirq.depolarize(1e-2),
         str(cirq.XPowGate()): cirq.depolarize(1e-2),
         str(cirq.PhasedXPowGate(phase_exponent=0)): cirq.depolarize(1e-2),
         str(cirq.HPowGate(exponent=1)): cirq.depolarize(1e-2),
         str(cirq.CNotPowGate(exponent=1)): cirq.depolarize(3e-2),
         str(cirq.CZPowGate(exponent=1)): cirq.depolarize(3e-2),
         str(cirq.CCXPowGate(exponent=1)): cirq.depolarize(8e-2),
         str(cirq.CCZPowGate(exponent=1)): cirq.depolarize(8e-2),
     }
     return default_noise_dict
Example #6
0
 def _decompose_(self, qubits):
     q = qubits
     π = np.pi
     θ, ϕ = self.params
     return [
         cirq.ZPowGate(exponent=1 / 2 - ϕ / π).on(q[1]),
         cirq.X.on(q[0]),
         cirq.CNOT(q[0], q[1]),
         cirq.X.on(q[0]),
         cirq.CNotPowGate(exponent=2 * θ / π).on(
             q[1], q[0]
         ),  # global_shift is needed to remove erronous complex numbers
         cirq.S.on(q[0]),
         cirq.ZPowGate(exponent=-θ / π).on(q[1])
     ]
        c_orig, gateset=cirq.SqrtIswapTargetGateset(use_sqrt_iswap_inv=True), ignore_failures=False
    )
    cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(c_orig, c_new, atol=1e-6)
    assert all(
        (
            all_gates_of_type(m, cirq.Gateset(cirq.PhasedXZGate))
            or all_gates_of_type(m, cirq.Gateset(cirq.SQRT_ISWAP_INV))
        )
        for m in c_new
    )


@pytest.mark.parametrize(
    'gate',
    [
        cirq.CNotPowGate(exponent=sympy.Symbol('t')),
        cirq.PhasedFSimGate(theta=sympy.Symbol('t'), chi=sympy.Symbol('t'), phi=sympy.Symbol('t')),
    ],
)
@pytest.mark.parametrize('use_sqrt_iswap_inv', [True, False])
def test_two_qubit_gates_with_symbols(gate: cirq.Gate, use_sqrt_iswap_inv: bool):
    # Note that even though these gates are not natively supported by
    # `cirq.parameterized_2q_op_to_sqrt_iswap_operations`, the transformation succeeds because
    # `cirq.optimize_for_target_gateset` also relies on `cirq.decompose` as a fallback.

    c_orig = cirq.Circuit(gate(*cirq.LineQubit.range(2)))
    c_new = cirq.optimize_for_target_gateset(
        c_orig,
        gateset=cirq.SqrtIswapTargetGateset(
            use_sqrt_iswap_inv=use_sqrt_iswap_inv,
            additional_gates=[cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate],
Example #8
0
def _get_circuit_proto_pairs():
    q0 = cirq.GridQubit(0, 0)
    q1 = cirq.GridQubit(0, 1)

    pairs = [
        # HPOW and aliases.
        (cirq.Circuit(cirq.HPowGate(exponent=0.3)(q0)),
         _build_gate_proto("HP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.HPowGate(exponent=sympy.Symbol('alpha'))(q0)),
         _build_gate_proto("HP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.HPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0)),
         _build_gate_proto("HP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.H(q0)),
         _build_gate_proto("HP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0'])),

        # XPOW and aliases.
        (cirq.Circuit(cirq.XPowGate(exponent=0.3)(q0)),
         _build_gate_proto("XP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.XPowGate(exponent=sympy.Symbol('alpha'))(q0)),
         _build_gate_proto("XP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.XPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0)),
         _build_gate_proto("XP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.X(q0)),
         _build_gate_proto("XP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0'])),

        # YPOW and aliases
        (cirq.Circuit(cirq.YPowGate(exponent=0.3)(q0)),
         _build_gate_proto("YP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.YPowGate(exponent=sympy.Symbol('alpha'))(q0)),
         _build_gate_proto("YP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.YPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0)),
         _build_gate_proto("YP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.Y(q0)),
         _build_gate_proto("YP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0'])),

        # ZPOW and aliases.
        (cirq.Circuit(cirq.ZPowGate(exponent=0.3)(q0)),
         _build_gate_proto("ZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.ZPowGate(exponent=sympy.Symbol('alpha'))(q0)),
         _build_gate_proto("ZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.ZPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0)),
         _build_gate_proto("ZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0'])),
        (cirq.Circuit(cirq.Z(q0)),
         _build_gate_proto("ZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0'])),

        # XXPow and aliases
        (cirq.Circuit(cirq.XXPowGate(exponent=0.3)(q0, q1)),
         _build_gate_proto("XXP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.XXPowGate(exponent=sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("XXP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.XXPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("XXP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.XX(q0, q1)),
         _build_gate_proto("XXP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0', '0_1'])),

        # YYPow and aliases
        (cirq.Circuit(cirq.YYPowGate(exponent=0.3)(q0, q1)),
         _build_gate_proto("YYP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.YYPowGate(exponent=sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("YYP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.YYPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("YYP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.YY(q0, q1)),
         _build_gate_proto("YYP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0', '0_1'])),

        # ZZPow and aliases
        (cirq.Circuit(cirq.ZZPowGate(exponent=0.3)(q0, q1)),
         _build_gate_proto("ZZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.ZZPowGate(exponent=sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("ZZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.ZZPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("ZZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.ZZ(q0, q1)),
         _build_gate_proto("ZZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0', '0_1'])),

        # CZPow and aliases
        (cirq.Circuit(cirq.CZPowGate(exponent=0.3)(q0, q1)),
         _build_gate_proto("CZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.CZPowGate(exponent=sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("CZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.CZPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("CZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.CZ(q0, q1)),
         _build_gate_proto("CZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0', '0_1'])),

        # CNOTPow and aliases
        (cirq.Circuit(cirq.CNotPowGate(exponent=0.3)(q0, q1)),
         _build_gate_proto("CNP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.CNotPowGate(exponent=sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("CNP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.CNotPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("CNP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.CNOT(q0, q1)),
         _build_gate_proto("CNP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0', '0_1'])),

        # SWAPPow and aliases
        (cirq.Circuit(cirq.SwapPowGate(exponent=0.3)(q0, q1)),
         _build_gate_proto("SP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.SwapPowGate(exponent=sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("SP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.SwapPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("SP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.SWAP(q0, q1)),
         _build_gate_proto("SP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0', '0_1'])),

        # ISWAPPow and aliases
        (cirq.Circuit(cirq.ISwapPowGate(exponent=0.3)(q0, q1)),
         _build_gate_proto("ISP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [0.3, 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.ISwapPowGate(exponent=sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("ISP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 1.0, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.ISwapPowGate(exponent=3.1 * sympy.Symbol('alpha'))(q0, q1)),
         _build_gate_proto("ISP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           ['alpha', 3.1, 0.0], ['0_0', '0_1'])),
        (cirq.Circuit(cirq.ISWAP(q0, q1)),
         _build_gate_proto("ISP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, 0.0], ['0_0', '0_1'])),

        # PhasedXPow and aliases
        (cirq.Circuit(
            cirq.PhasedXPowGate(phase_exponent=0.9,
                                exponent=0.3,
                                global_shift=0.2)(q0)),
         _build_gate_proto("PXP", [
             'phase_exponent', 'phase_exponent_scalar', 'exponent',
             'exponent_scalar', 'global_shift'
         ], [0.9, 1.0, 0.3, 1.0, 0.2], ['0_0'])),
        (cirq.Circuit(
            cirq.PhasedXPowGate(phase_exponent=sympy.Symbol('alpha'),
                                exponent=0.3)(q0)),
         _build_gate_proto("PXP", [
             'phase_exponent', 'phase_exponent_scalar', 'exponent',
             'exponent_scalar', 'global_shift'
         ], ['alpha', 1.0, 0.3, 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(
            cirq.PhasedXPowGate(phase_exponent=3.1 * sympy.Symbol('alpha'),
                                exponent=0.3)(q0)),
         _build_gate_proto("PXP", [
             'phase_exponent', 'phase_exponent_scalar', 'exponent',
             'exponent_scalar', 'global_shift'
         ], ['alpha', 3.1, 0.3, 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(
            cirq.PhasedXPowGate(phase_exponent=0.9,
                                exponent=sympy.Symbol('beta'))(q0)),
         _build_gate_proto("PXP", [
             'phase_exponent', 'phase_exponent_scalar', 'exponent',
             'exponent_scalar', 'global_shift'
         ], [0.9, 1.0, 'beta', 1.0, 0.0], ['0_0'])),
        (cirq.Circuit(
            cirq.PhasedXPowGate(phase_exponent=0.9,
                                exponent=5.1 * sympy.Symbol('beta'))(q0)),
         _build_gate_proto("PXP", [
             'phase_exponent', 'phase_exponent_scalar', 'exponent',
             'exponent_scalar', 'global_shift'
         ], [0.9, 1.0, 'beta', 5.1, 0.0], ['0_0'])),
        (cirq.Circuit(
            cirq.PhasedXPowGate(phase_exponent=3.1 * sympy.Symbol('alpha'),
                                exponent=5.1 * sympy.Symbol('beta'))(q0)),
         _build_gate_proto("PXP", [
             'phase_exponent', 'phase_exponent_scalar', 'exponent',
             'exponent_scalar', 'global_shift'
         ], ['alpha', 3.1, 'beta', 5.1, 0.0], ['0_0'])),

        # RX, RY, RZ with symbolization is tested in special cases as the
        # string comparison of the float converted sympy.pi does not happen
        # smoothly. See: test_serialize_deserialize_special_case_one_qubit
        (cirq.Circuit(cirq.rx(np.pi)(q0)),
         _build_gate_proto("XP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, -0.5], ['0_0'])),
        (cirq.Circuit(cirq.ry(np.pi)(q0)),
         _build_gate_proto("YP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, -0.5], ['0_0'])),
        (cirq.Circuit(cirq.rz(np.pi)(q0)),
         _build_gate_proto("ZP",
                           ['exponent', 'exponent_scalar', 'global_shift'],
                           [1.0, 1.0, -0.5], ['0_0'])),

        # Identity
        (cirq.Circuit(cirq.I(q0)),
         _build_gate_proto("I", ['unused'], [True], ['0_0'])),

        # FSimGate
        (cirq.Circuit(cirq.FSimGate(theta=0.1, phi=0.2)(q0, q1)),
         _build_gate_proto("FSIM",
                           ['theta', 'theta_scalar', 'phi', 'phi_scalar'],
                           [0.1, 1.0, 0.2, 1.0], ['0_0', '0_1'])),
        (cirq.Circuit(
            cirq.FSimGate(theta=2.1 * sympy.Symbol("alpha"),
                          phi=1.3 * sympy.Symbol("beta"))(q0, q1)),
         _build_gate_proto("FSIM",
                           ['theta', 'theta_scalar', 'phi', 'phi_scalar'],
                           ['alpha', 2.1, 'beta', 1.3], ['0_0', '0_1'])),
    ]

    return pairs
Example #9
0
        (cast(cirq.Gate, cirq.ISWAP), 7),  # cast is for fixing mypy confusion
        (cirq.CZ, 8),
        (cirq.SWAP, 7),
        (cirq.CNOT, 9),
        (cirq.ISWAP**0.5, 1),
        (cirq.ISWAP**-0.5, 1),
        (cirq.ISwapPowGate(exponent=0.5), 1),
        (cirq.ISwapPowGate(exponent=-0.5), 1),
        (cirq.FSimGate(theta=np.pi / 4, phi=0), 1),
        *[(cirq.SwapPowGate(exponent=a), 13)
          for a in np.linspace(0, 2 * np.pi, 20)],
        *[(cirq.CZPowGate(exponent=a), 8)
          for a in np.linspace(0, 2 * np.pi, 20)],
        *[(cirq.ISwapPowGate(exponent=a), 5)
          for a in np.linspace(0, 2 * np.pi, 20)],
        *[(cirq.CNotPowGate(exponent=a), 9)
          for a in np.linspace(0, 2 * np.pi, 20)],
        *[(cirq.FSimGate(theta=a, phi=a), 13)
          for a in np.linspace(0, 2 * np.pi, 20)],
    ],
)
def test_two_qubit_gates(gate: cirq.Gate, expected_length: int):
    """Tests that two qubit gates decompose to an equivalent and
    serializable circuit with the expected length (or less).
    """
    q0 = cirq.GridQubit(5, 3)
    q1 = cirq.GridQubit(5, 4)
    original_circuit = cirq.Circuit(gate(q0, q1))
    converted_circuit = original_circuit.copy()
    converted_circuit_iswap_inv = cirq.optimize_for_target_gateset(
        original_circuit,
Example #10
0
    z = cirq.ZPowGate(exponent=5)
    assert z.exponent == 5

    # Canonicalizes exponent for equality, but keeps the inner details.
    assert cirq.Z**0.5 != cirq.Z**-0.5
    assert (cirq.Z**-1)**0.5 == cirq.Z**-0.5
    assert cirq.Z**-1 == cirq.Z


@pytest.mark.parametrize(
    'input_gate, specialized_output',
    [(cirq.Z, cirq.CZ), (cirq.CZ, cirq.CCZ), (cirq.X, cirq.CX),
     (cirq.CX, cirq.CCX),
     (cirq.ZPowGate(exponent=0.5), cirq.CZPowGate(exponent=0.5)),
     (cirq.CZPowGate(exponent=0.5), cirq.CCZPowGate(exponent=0.5)),
     (cirq.XPowGate(exponent=0.5), cirq.CNotPowGate(exponent=0.5)),
     (cirq.CNotPowGate(exponent=0.5), cirq.CCXPowGate(exponent=0.5))])
def test_specialized_control(input_gate, specialized_output):
    # Single qubit control on the input gate gives the specialized output
    assert input_gate.controlled() == specialized_output
    assert input_gate.controlled(num_controls=1) == specialized_output
    assert input_gate.controlled(
        control_values=((1, ), )) == specialized_output
    assert input_gate.controlled(control_qid_shape=(2, )) == specialized_output
    assert np.allclose(
        cirq.unitary(specialized_output),
        cirq.unitary(cirq.ControlledGate(input_gate, num_controls=1)))

    # For multi-qudit controls, if the last control is a qubit with control
    # value 1, construct the specialized output leaving the rest of the
    # controls as they are.
Example #11
0
 'Bristlecone':
 cirq.google.Bristlecone,
 'CCNOT':
 cirq.CCNOT,
 'CCX':
 cirq.CCX,
 'CCXPowGate':
 cirq.CCXPowGate(exponent=0.123, global_shift=0.456),
 'CCZ':
 cirq.CCZ,
 'CCZPowGate':
 cirq.CCZPowGate(exponent=0.123, global_shift=0.456),
 'CNOT':
 cirq.CNOT,
 'CNotPowGate':
 cirq.CNotPowGate(exponent=0.123, global_shift=0.456),
 'ControlledOperation':
 cirq.ControlledOperation(sub_operation=cirq.Y(cirq.NamedQubit('target')),
                          controls=cirq.LineQubit.range(2),
                          control_values=[0, 1]),
 'ControlledGate':
 cirq.ControlledGate(sub_gate=cirq.Y,
                     num_controls=2,
                     control_values=[0, 1],
                     control_qid_shape=(3, 2)),
 'CX':
 cirq.CX,
 'CSWAP':
 cirq.CSWAP,
 'CSwapGate':
 cirq.CSwapGate(),
Example #12
0
def test_CY(benchmark, nqubits):
    benchmark.group = "C-Rx(0.5)"
    run_bench(benchmark, nqubits, cirq.CNotPowGate(exponent=0.5), (2, 3))
Example #13
0
class CirqDevice(QubitDevice, abc.ABC):
    """Abstract base device for PennyLane-Cirq.

    Args:
        wires (int or Iterable[Number, str]]): Number of subsystems represented by the device,
            or iterable that contains unique labels for the subsystems as numbers (i.e., ``[-1, 0, 2]``)
            or strings (``['ancilla', 'q1', 'q2']``).
        shots (int): Number of circuit evaluations/random samples used
            to estimate expectation values of observables. Shots need to be >= 1.
        qubits (List[cirq.Qubit]): A list of Cirq qubits that are used
            as wires. By default, an array of ``cirq.LineQubit`` instances is created.
            Wires are mapped to qubits using Cirq's internal mechanism for ordering
            qubits. For example, if ``wires=2`` and ``qubits=[q1, q2]``, with
            ``q1>q2``, then the wire indices 0 and 1 are mapped to q2 and q1, respectively.
            If the user provides their own wire labels, e.g., ``wires=["alice", "bob"]``, and the
            qubits are the same as the previous example, then "alice" would map to qubit q2
            and "bob" would map to qubit q1.
    """

    name = "Cirq Abstract PennyLane plugin base class"
    pennylane_requires = ">=0.11.0"
    version = __version__
    author = "Xanadu Inc"
    _capabilities = {
        "model": "qubit",
        "tensor_observables": True,
        "inverse_operations": True,
    }

    short_name = "cirq.base_device"

    def __init__(self, wires, shots, analytic, qubits=None):

        if not isinstance(wires, Iterable):
            # interpret wires as the number of consecutive wires
            wires = range(wires)
        num_wires = len(wires)

        if qubits:
            if num_wires != len(qubits):
                raise qml.DeviceError(
                    "The number of given qubits and the specified number of wires have to match. Got {} wires and {} qubits.".format(
                        wires, len(qubits)
                    )
                )
        else:
            qubits = [cirq.LineQubit(idx) for idx in range(num_wires)]

        # cirq orders the subsystems based on a total order defined on qubits.
        # For consistency, this plugin uses that same total order
        self._unsorted_qubits = qubits
        self.qubits = sorted(qubits)

        super().__init__(wires, shots, analytic)

        self.circuit = None
        self.cirq_device = None

        # Add inverse operations
        self._inverse_operation_map = {}
        for key in self._operation_map:
            if not self._operation_map[key]:
                continue

            # We have to use a new CirqOperation instance because .inv() acts in-place
            inverted_operation = CirqOperation(self._operation_map[key].parametrization)
            inverted_operation.inv()

            self._inverse_operation_map[key + Operation.string_for_inverse] = inverted_operation

        self._complete_operation_map = {
            **self._operation_map,
            **self._inverse_operation_map,
        }

    _operation_map = {
        "BasisState": None,
        "QubitStateVector": None,
        "QubitUnitary": CirqOperation(cirq.MatrixGate),
        "PauliX": CirqOperation(lambda: cirq.X),
        "PauliY": CirqOperation(lambda: cirq.Y),
        "PauliZ": CirqOperation(lambda: cirq.Z),
        "Hadamard": CirqOperation(lambda: cirq.H),
        "S": CirqOperation(lambda: cirq.S),
        "T": CirqOperation(lambda: cirq.T),
        "CNOT": CirqOperation(lambda: cirq.CNOT),
        "SWAP": CirqOperation(lambda: cirq.SWAP),
        "ISWAP": CirqOperation(lambda: cirq.ISWAP),
        "CZ": CirqOperation(lambda: cirq.CZ),
        "PhaseShift": CirqOperation(lambda phi: cirq.ZPowGate(exponent=phi / np.pi)),
        "CPhase": CirqOperation(lambda phi: cirq.CZPowGate(exponent=phi / np.pi)),
        "RX": CirqOperation(lambda phi: cirq.XPowGate(exponent=phi / np.pi, global_shift=0.5)),
        "RY": CirqOperation(lambda phi: cirq.YPowGate(exponent=phi / np.pi, global_shift=0.5)),
        "RZ": CirqOperation(lambda phi: cirq.ZPowGate(exponent=phi / np.pi, global_shift=0.5)),
        "Rot": CirqOperation(
            lambda a, b, c: [
                cirq.ZPowGate(exponent=a / np.pi, global_shift=0.5),
                cirq.YPowGate(exponent=b / np.pi, global_shift=0.5),
                cirq.ZPowGate(exponent=c / np.pi, global_shift=0.5),
            ]
        ),
        "CRX": CirqOperation(lambda phi: cirq.CNotPowGate(exponent=phi / np.pi, global_shift=0.5)),
        # "CRY": CirqOperation(lambda phi: cirq.ControlledGate(cirq.YPowGate(exponent=phi / np.pi, global_shift=-0.5))),
        "CRZ": CirqOperation(lambda phi: cirq.CZPowGate(exponent=phi / np.pi, global_shift=0.5)),
        # "CRot": CirqOperation(
        # lambda a, b, c: [
        # cirq.ControlledGate(cirq.rz(a)),
        # cirq.ControlledGate(cirq.ry(b)),
        # cirq.ControlledGate(cirq.rz(c)),
        # ]
        # ),
        "CSWAP": CirqOperation(lambda: cirq.CSWAP),
        "Toffoli": CirqOperation(lambda: cirq.TOFFOLI),
    }

    _observable_map = {
        "PauliX": CirqOperation(lambda: cirq.X),
        "PauliY": CirqOperation(lambda: cirq.Y),
        "PauliZ": CirqOperation(lambda: cirq.Z),
        "Hadamard": CirqOperation(lambda: cirq.H),
        # TODO(chase): Consider using qml.utils.decompose_hamiltonian()
        # to support this observable.
        "Hermitian": None,
        "Identity": CirqOperation(lambda: cirq.I),
    }

    def to_paulistring(self, observable):
        """Convert an observable to a cirq.PauliString"""
        if isinstance(observable, Tensor):
            obs = [self.to_paulistring(o) for o in observable.obs]
            return functools.reduce(operator.mul, obs)

        cirq_op = self._observable_map[observable.name]
        if cirq_op is None:
            raise NotImplementedError(f"{observable.name} is not currently supported.")
        cirq_op.parametrize(*observable.parameters)
        device_wires = self.map_wires(observable.wires)
        return functools.reduce(
            operator.mul, cirq_op.apply(*[self.qubits[w] for w in device_wires.labels])
        )

    def reset(self):
        # pylint: disable=missing-function-docstring
        super().reset()

        if self.cirq_device:
            self.circuit = cirq.Circuit(device=self.cirq_device)
        else:
            self.circuit = cirq.Circuit()

    @property
    def observables(self):
        # pylint: disable=missing-function-docstring
        return set(self._observable_map.keys())

    @property
    def operations(self):
        # pylint: disable=missing-function-docstring
        return set(self._operation_map.keys())

    @abc.abstractmethod
    def _apply_basis_state(self, basis_state_operation):
        """Apply a basis state preparation.

        Args:
            basis_state_operation (pennylane.BasisState): the BasisState operation instance that shall be applied

        Raises:
            NotImplementedError: when not implemented in the subclass
        """
        raise NotImplementedError

    @abc.abstractmethod
    def _apply_qubit_state_vector(self, qubit_state_vector_operation):
        """Apply a state vector preparation.

        Args:
            qubit_state_vector_operation (pennylane.QubitStateVector): the QubitStateVector operation instance that shall be applied

        Raises:
            NotImplementedError: when not implemented in the subclass
        """
        raise NotImplementedError

    def _apply_operation(self, operation):
        """Apply a single PennyLane Operation.

        Args:
            operation (pennylane.Operation): the operation that shall be applied
        """
        cirq_operation = self._complete_operation_map[operation.name]

        # If command is None do nothing
        if cirq_operation:
            cirq_operation.parametrize(*operation.parameters)

            device_wires = self.map_wires(operation.wires)
            self.circuit.append(
                cirq_operation.apply(*[self.qubits[w] for w in device_wires.labels])
            )

    def apply(self, operations, **kwargs):
        # pylint: disable=missing-function-docstring
        rotations = kwargs.pop("rotations", [])

        for i, operation in enumerate(operations):
            if i > 0 and operation.name in {"BasisState", "QubitStateVector"}:
                raise qml.DeviceError(
                    "The operation {} is only supported at the beginning of a circuit.".format(
                        operation.name
                    )
                )

            if operation.name == "BasisState":
                self._apply_basis_state(operation)
            elif operation.name == "QubitStateVector":
                self._apply_qubit_state_vector(operation)
            else:
                self._apply_operation(operation)

        # TODO: get pre rotated state here

        # Diagonalize the given observables
        for operation in rotations:
            self._apply_operation(operation)

    def define_wire_map(self, wires):  # pylint: disable=missing-function-docstring
        cirq_order = np.argsort(self._unsorted_qubits)
        consecutive_wires = Wires(cirq_order)

        wire_map = zip(wires, consecutive_wires)
        return OrderedDict(wire_map)
@pytest.mark.parametrize(
    'gate, expected_length',
    [
        (cast(cirq.Gate, cirq.ISWAP), 7),  # cast is for fixing mypy confusion
        (cirq.CZ, 8),
        (cirq.SWAP, 7),
        (cirq.CNOT, 9),
        (cirq.ISWAP ** 0.5, 1),
        (cirq.ISWAP ** -0.5, 1),
        (cirq.ISwapPowGate(exponent=0.5), 1),
        (cirq.ISwapPowGate(exponent=-0.5), 1),
        (cirq.FSimGate(theta=np.pi / 4, phi=0), 1),
        *[(cirq.SwapPowGate(exponent=a), 13) for a in np.linspace(0, 2 * np.pi, 20)],
        *[(cirq.CZPowGate(exponent=a), 8) for a in np.linspace(0, 2 * np.pi, 20)],
        *[(cirq.ISwapPowGate(exponent=a), 5) for a in np.linspace(0, 2 * np.pi, 20)],
        *[(cirq.CNotPowGate(exponent=a), 9) for a in np.linspace(0, 2 * np.pi, 20)],
        *[(cirq.FSimGate(theta=a, phi=a), 13) for a in np.linspace(0, 2 * np.pi, 20)],
    ],
)
def test_two_qubit_gates(gate: cirq.Gate, expected_length: int):
    """Tests that two qubit gates decompose to an equivalent and
    serializable circuit with the expected length (or less).
    """
    q0 = cirq.GridQubit(5, 3)
    q1 = cirq.GridQubit(5, 4)
    original_circuit = cirq.Circuit(gate(q0, q1))
    converted_circuit = original_circuit.copy()
    cgoc.ConvertToSqrtIswapGates().optimize_circuit(converted_circuit)
    cig.SQRT_ISWAP_GATESET.serialize(converted_circuit)
    assert len(converted_circuit) <= expected_length
    assert _unitaries_allclose(original_circuit, converted_circuit)