Exemple #1
0
def test_identity_short_circuits_act_on():
    args = mock.Mock(cirq.ActOnArgs)
    args._act_on_fallback_.side_effect = mock.Mock(
        side_effect=Exception('No!'))
    cirq.act_on(cirq.IdentityGate(1)(cirq.LineQubit(0)), args)
def test_identity_eq():
    equals_tester = cirq.testing.EqualsTester()
    equals_tester.add_equality_group(cirq.I, cirq.IdentityGate(1))
    equals_tester.add_equality_group(cirq.IdentityGate(2))
    equals_tester.add_equality_group(cirq.IdentityGate(4))
Exemple #3
0
 cirq.GeneralizedAmplitudeDampingChannel(0.1, 0.2),
 'GlobalPhaseOperation':
 cirq.GlobalPhaseOperation(-1j),
 'GridQubit':
 cirq.GridQubit(10, 11),
 'H':
 cirq.H,
 'HPowGate': [cirq.HPowGate(exponent=-8), cirq.H**0.123],
 'I':
 cirq.I,
 'ISWAP':
 cirq.ISWAP,
 'ISwapPowGate': [cirq.ISwapPowGate(exponent=-8), cirq.ISWAP**0.123],
 'IdentityGate': [
     cirq.I,
     cirq.IdentityGate(num_qubits=5),
     cirq.IdentityGate(num_qubits=5, qid_shape=(3, ) * 5)
 ],
 'IdentityOperation': [
     cirq.IdentityOperation(cirq.LineQubit.range(2)),
     cirq.IdentityOperation(cirq.LineQubit.range(5))
 ],
 'LineQubit': [cirq.LineQubit(0), cirq.LineQubit(123)],
 'LineQid': [cirq.LineQid(0, 1),
             cirq.LineQid(123, 2),
             cirq.LineQid(-4, 5)],
 'MeasurementGate': [
     cirq.MeasurementGate(num_qubits=3, key='z'),
     cirq.MeasurementGate(num_qubits=3,
                          key='z',
                          invert_mask=(True, False, True)),
def test_identity_init(num_qubits):
    assert cirq.IdentityGate(num_qubits).num_qubits() == num_qubits
def test_identity_str():
    assert str(cirq.IdentityGate(1)) == 'I'
    assert str(cirq.IdentityGate(2)) == 'I(2)'
Exemple #6
0
    _B,
)

ALLOW_DEPRECATION_IN_TEST = 'ALLOW_DEPRECATION_IN_TEST'


def test_deprecated_submodule():
    with cirq.testing.assert_deprecated(
        "Use cirq.transformers.analytical_decompositions.two_qubit_to_fsim instead",
        deadline="v0.16",
    ):
        _ = cirq.optimizers.two_qubit_to_fsim.decompose_two_qubit_interaction_into_four_fsim_gates


UNITARY_OBJS = [
    cirq.IdentityGate(2),
    cirq.XX ** 0.25,
    cirq.CNOT,
    cirq.CNOT(*cirq.LineQubit.range(2)),
    cirq.CNOT(*cirq.LineQubit.range(2)[::-1]),
    cirq.ISWAP,
    cirq.SWAP,
    cirq.FSimGate(theta=np.pi / 6, phi=np.pi / 6),
] + [cirq.testing.random_unitary(4) for _ in range(5)]

FEASIBLE_FSIM_GATES = [
    cirq.ISWAP,
    cirq.FSimGate(np.pi / 2, 0),
    cirq.FSimGate(-np.pi / 2, 0),
    cirq.FSimGate(np.pi / 2, np.pi / 6),
    cirq.FSimGate(np.pi / 2, -np.pi / 6),
Exemple #7
0
def op_grad(
    operation: cirq.GateOperation, parameter: sympy.Symbol
) -> typing.Union[LinearCombinationOfOperations, GradNotImplemented]:
    if not cirq.is_parameterized(operation):
        return ZERO_OP.copy()

    gate = operation.gate
    qubits = operation.qubits

    if isinstance(gate, cirq.XPowGate):
        # dXPow(e=f(t), s) / dt = i π (s + 1 / 2 - X / 2) * (df(t)/dt) XPow(e=f(t), s)
        # Note that: Rx(θ) = XPowGate(exponent=θ/pi, global_shift=-0.5)
        partial = sympy.diff(gate.exponent, parameter)
        coeff_i = 1.0j * sympy.pi * (gate._global_shift + 0.5)
        coeff_x = -1.0j / 2 * sympy.pi
        if partial == 0:
            return ZERO_OP.copy()
        return LinearCombinationOfOperations({
            (cirq.X.on(*qubits), operation):
            coeff_x * partial,
            (cirq.I.on(*qubits), operation):
            coeff_i * partial
        })

    elif isinstance(gate, cirq.YPowGate):
        # dYPow(e=f(t), s) / dt = i π (s + 1 / 2 - Y / 2) * (df(t)/dt) YPow(e=f(t), s)
        # Note that: Ry(θ) = YPowGate(exponent=θ/pi, global_shift=-0.5)
        partial = sympy.diff(gate.exponent, parameter)
        coeff_i = 1.0j * sympy.pi * (gate._global_shift + 0.5)
        coeff_y = -1.0j / 2 * sympy.pi
        if partial == 0:
            return ZERO_OP.copy()
        return LinearCombinationOfOperations({
            (cirq.Y.on(*qubits), operation):
            coeff_y * partial,
            (cirq.I.on(*qubits), operation):
            coeff_i * partial
        })

    elif isinstance(gate, cirq.ZPowGate):
        # dZPow(e=f(t), s) / dt = i π (s + 1 / 2 - Z / 2) * (df(t)/dt) ZPow(e=f(t), s)
        # Note that: Ry(θ) = ZPowGate(exponent=θ/pi, global_shift=-0.5)
        partial = sympy.diff(gate.exponent, parameter)
        coeff_i = 1.0j * sympy.pi * (gate._global_shift + 0.5)
        coeff_z = -1.0j / 2 * sympy.pi
        if partial == 0:
            return ZERO_OP.copy()
        return LinearCombinationOfOperations({
            (cirq.Z.on(*qubits), operation):
            coeff_z * partial,
            (cirq.I.on(*qubits), operation):
            coeff_i * partial
        })

    elif isinstance(gate, GlobalPhaseGate):
        gate = typing.cast(GlobalPhaseGate, gate)
        # Ph(θ) = exp(i pi θ)
        # dPh(f(θ)) / dθ = [i pi df(θ) / dθ] exp(i pi f(θ))
        #                = [i pi df(θ) / dθ] Ph(f(θ))
        coeff = 1.0j * sympy.diff(gate.rad * sympy.pi, parameter)
        if coeff == 0:
            return ZERO_OP.copy()
        return LinearCombinationOfOperations({(operation, ): coeff})

    elif isinstance(gate, cirq.EigenGate):
        gate = typing.cast(cirq.EigenGate, gate)
        eigenvalues = {v for v, p in gate._eigen_components()}
        if eigenvalues == {0, 1}:
            e = gate.exponent
            s = gate._global_shift
            partial = sympy.diff(e, parameter)

            if partial == 0:
                return ZERO_OP.copy()

            num_qubits = gate.num_qubits()
            gate_e1_s0 = copy.deepcopy(gate)
            gate_e1_s0._exponent = 1.0
            gate_e1_s0._global_shift = 0.0  # Any better solutions?
            coeff = 0.5 * sympy.exp(1.0j * sympy.pi * (1 + s) * e)

            return 1.0j * sympy.pi * LinearCombinationOfOperations(
                {
                    (operation, ): s * partial,
                    (gate_e1_s0.on(*qubits), ): -coeff * partial,
                    (cirq.IdentityGate(num_qubits).on(*qubits), ):
                    coeff * partial
                })

        else:
            return GradNotImplemented(operation)

    elif isinstance(gate, GateBlock):
        gate = typing.cast(GateBlock, gate)

        generator_grad = op_tree_generator_grad(gate._op_generator, parameter)

        if isinstance(generator_grad, GradNotImplemented):
            return generator_grad

        if len(generator_grad) == 0:
            return ZERO_OP.copy()

        _grad = LinearCombinationOfOperations({})
        for generator, coeff in generator_grad.items():
            grad_gate = GateBlock(generator)

            _grad += LinearCombinationOfOperations({
                (grad_gate.on(*qubits), ):
                coeff
            })

            # print(grad_gate.diagram())

        return _grad

    elif isinstance(gate, cirq.ControlledGate):
        gate = typing.cast(cirq.ControlledGate, gate)

        sub_gate_qubits = qubits[gate.num_controls():]
        sub_op_grad = op_grad(gate.sub_gate.on(*sub_gate_qubits), parameter)

        if is_zero_op_or_grad_not_implemented(sub_op_grad):
            return sub_op_grad

        _gate_grad = LinearCombinationOfOperations({})
        op: cirq.GateOperation
        for op_series, coeff in sub_op_grad.items():
            _controlled_op_series = [
                cirq.ControlledGate(op.gate,
                                    num_controls=gate.num_controls()).on(
                                        *qubits[:gate.num_controls()],
                                        *sub_gate_qubits) for op in op_series
            ]
            _controlled_negative_op_series = copy.deepcopy(
                _controlled_op_series)
            _controlled_negative_op_series.insert(
                0,
                cirq.ControlledGate(GlobalPhaseGate(rad=1),
                                    num_controls=gate.num_controls()).on(
                                        *qubits[:gate.num_controls()],
                                        *sub_gate_qubits))
            _gate_grad += LinearCombinationOfOperations(
                {
                    tuple(_controlled_op_series): coeff,
                    tuple(_controlled_negative_op_series): -coeff,
                }) / 2.0

        return _gate_grad

    # if `operation` is a basic and indecomposable operation whose grad is
    # not implemented
    elif is_an_indecomposable_operation(operation):
        return GradNotImplemented(operation)

    else:
        op_series = cirq.decompose(
            operation,
            keep=(lambda op: is_a_basic_operation(op) or
                  is_an_indecomposable_operation(op)),
            on_stuck_raise=None)  # type: typing.List[cirq.Operation]

        _grad = op_series_grad(op_series, parameter)
        return _grad
Exemple #8
0
def _all_operations(q0, q1, q2, q3, q4, include_measurements=True):
    class DummyOperation(cirq.Operation):
        qubits = (q0, )
        with_qubits = NotImplemented

        def _qasm_(self, args: cirq.QasmArgs) -> str:
            return '// Dummy operation\n'

        def _decompose_(self):
            # Only used by test_output_unitary_same_as_qiskit
            return ()  # coverage: ignore

    class DummyCompositeOperation(cirq.Operation):
        qubits = (q0, )
        with_qubits = NotImplemented

        def _decompose_(self):
            return cirq.X(self.qubits[0])

        def __repr__(self):
            return 'DummyCompositeOperation()'

    return (
        cirq.Z(q0),
        cirq.Z(q0)**0.625,
        cirq.Y(q0),
        cirq.Y(q0)**0.375,
        cirq.X(q0),
        cirq.X(q0)**0.875,
        cirq.H(q1),
        cirq.X(q0)**0.5,
        cirq.X(q0)**-0.5,
        cirq.CZ(q0, q1),
        cirq.CZ(q0, q1)**0.25,  # Requires 2-qubit decomposition
        cirq.CNOT(q0, q1),
        cirq.CNOT(q0, q1)**0.5,  # Requires 2-qubit decomposition
        cirq.SWAP(q0, q1),
        cirq.SWAP(q0, q1)**0.75,  # Requires 2-qubit decomposition
        cirq.CCZ(q0, q1, q2),
        cirq.CCX(q0, q1, q2),
        cirq.CCZ(q0, q1, q2)**0.5,
        cirq.CCX(q0, q1, q2)**0.5,
        cirq.CSWAP(q0, q1, q2),
        cirq.IdentityGate(1).on(q0),
        cirq.IdentityGate(3).on(q0, q1, q2),
        cirq.ISWAP(q2, q0),  # Requires 2-qubit decomposition
        cirq.PhasedXPowGate(phase_exponent=0.111, exponent=0.25).on(q1),
        cirq.PhasedXPowGate(phase_exponent=0.333, exponent=0.5).on(q1),
        cirq.PhasedXPowGate(phase_exponent=0.777, exponent=-0.5).on(q1),
        (
            cirq.measure(q0, key='xX'),
            cirq.measure(q2, key='x_a'),
            cirq.measure(q1, key='x?'),
            cirq.measure(q3, key='X'),
            cirq.measure(q4, key='_x'),
            cirq.measure(q2, key='x_a'),
            cirq.measure(q1, q2, q3, key='multi', invert_mask=(False, True)),
        ) if include_measurements else (),
        DummyOperation(),
        DummyCompositeOperation(),
    )
Exemple #9
0
def test_identity_repr():
    assert repr(cirq.I) == 'cirq.I'
    assert repr(cirq.IdentityGate(5)) == 'cirq.IdentityGate(5)'
    assert repr(cirq.IdentityGate(
        qid_shape=(2, 3))) == 'cirq.IdentityGate(qid_shape=(2, 3))'
Exemple #10
0
     cirq.CSWAP(*cirq.LineQubit.range(3)),
     cirq.CZ(*cirq.LineQubit.range(2))
 ],
 'GlobalPhaseOperation':
 cirq.GlobalPhaseOperation(-1j),
 'GridQubit':
 cirq.GridQubit(10, 11),
 'H':
 cirq.H,
 'HPowGate': [cirq.HPowGate(exponent=-8), cirq.H**0.123],
 'I':
 cirq.I,
 'ISWAP':
 cirq.ISWAP,
 'ISwapPowGate': [cirq.ISwapPowGate(exponent=-8), cirq.ISWAP**0.123],
 'IdentityGate': [cirq.I, cirq.IdentityGate(num_qubits=5)],
 'LineQubit': [cirq.LineQubit(0), cirq.LineQubit(123)],
 'LineQid': [cirq.LineQid(0, 1),
             cirq.LineQid(123, 2),
             cirq.LineQid(-4, 5)],
 'MeasurementGate': [
     cirq.MeasurementGate(num_qubits=3, key='z'),
     cirq.MeasurementGate(num_qubits=3,
                          key='z',
                          invert_mask=(True, False, True)),
 ],
 'Moment': [
     cirq.Moment(operations=[cirq.X(Q0), cirq.Y(Q1),
                             cirq.Z(Q2)]),
 ],
 'NamedQubit':
Exemple #11
0
                   judge_log,
                   multiplier,
                   result,
                   n_qubits=1,
                   min_two_qubit=0)


@pytest.mark.parametrize(
    "gate",
    [
        cirq.google.SycamoreGate(),
        cirq.CX,
        cirq.XX,
        cirq.YY,
        cirq.ZZ,
        cirq.IdentityGate(num_qubits=2),
    ],
)
def test_two_qubit_gates(judge_log, gate):
    multiplier = 4
    result = JudgeLogEntry(task=f"Two-qubit gate {gate}")

    input = cirq.unitary(gate(*(cirq.LineQubit.range(2))))

    _score_and_log(input,
                   judge_log,
                   multiplier,
                   result,
                   n_qubits=2,
                   min_two_qubit=1)
    ({cirq.XX: 0.5, cirq.YY: -0.5}, np.rot90(np.diag([1, 0, 0, 1]))),
    ({cirq.CCZ: 3j}, np.diag([3j, 3j, 3j, 3j, 3j, 3j, 3j, -3j])),
))
def test_linear_combination_of_gates_has_correct_matrix(terms, expected_matrix):
    combination = cirq.LinearCombinationOfGates(terms)
    assert np.all(combination.matrix() == expected_matrix)


@pytest.mark.parametrize(
    'terms, expected_unitary',
    (({
        cirq.X: np.sqrt(0.5),
        cirq.Y: np.sqrt(0.5)
    }, np.array([[0, np.sqrt(-1j)], [np.sqrt(1j), 0]])),
     ({
         cirq.IdentityGate(2): np.sqrt(0.5),
         cirq.YY: -1j * np.sqrt(0.5),
     }, np.sqrt(0.5) *
      np.array([[1, 0, 0, 1j], [0, 1, -1j, 0], [0, -1j, 1, 0], [1j, 0, 0, 1]])))
)
def test_unitary_linear_combination_of_gates_has_correct_unitary(
        terms, expected_unitary):
    combination = cirq.LinearCombinationOfGates(terms)
    assert cirq.has_unitary(combination)
    assert np.allclose(cirq.unitary(combination), expected_unitary)


@pytest.mark.parametrize('terms', ({
    cirq.X: 2
}, {
    cirq.Y**sympy.Symbol('t'): 1
Exemple #13
0
    expected_expansion = cirq.pauli_expansion(expected)
    assert set(actual_expansion.keys()) == set(expected_expansion.keys())
    for name in actual_expansion.keys():
        assert abs(actual_expansion[name] - expected_expansion[name]) < 1e-12


@pytest.mark.parametrize('expression, expected_result', (
    ((cirq.X + cirq.Z) / np.sqrt(2), cirq.H),
    (cirq.X - cirq.Y, -cirq.Y + cirq.X),
    (cirq.X + cirq.S - cirq.X, cirq.S),
    (cirq.Y - 2 * cirq.Y, -cirq.Y),
    (cirq.Rx(0.2), np.cos(0.1) * cirq.I - 1j * np.sin(0.1) * cirq.X),
    (1j * cirq.H * 1j, -cirq.H),
    (-1j * cirq.Y, cirq.Ry(np.pi)),
    (np.sqrt(-1j) * cirq.S, cirq.Rz(np.pi / 2)),
    (0.5 * (cirq.IdentityGate(2) + cirq.XX + cirq.YY + cirq.ZZ), cirq.SWAP),
    ((cirq.IdentityGate(2) + 1j *
      (cirq.XX + cirq.YY) + cirq.ZZ) / 2, cirq.ISWAP),
    (cirq.CNOT + 0 * cirq.SWAP, cirq.CNOT),
    (0.5 * cirq.FREDKIN, cirq.FREDKIN / 2),
    (cirq.FREDKIN * 0.5, cirq.FREDKIN / 2),
))
def test_expressions(expression, expected_result):
    assert_linear_combinations_of_gates_are_equal(expression, expected_result)


@pytest.mark.parametrize('gates', (
    (cirq.X, cirq.T, cirq.T, cirq.X, cirq.Z),
    (cirq.CZ, cirq.XX, cirq.YY, cirq.ZZ),
    (cirq.TOFFOLI, cirq.TOFFOLI, cirq.FREDKIN),
))
Exemple #14
0
def test_identity_on_each_two_qubits():
    q0, q1, q2, q3 = cirq.LineQubit.range(4)
    q0_3, q1_3 = q0.with_dimension(3), q1.with_dimension(3)
    assert cirq.IdentityGate(2).on_each([(q0, q1)
                                         ]) == [cirq.IdentityGate(2)(q0, q1)]
    assert cirq.IdentityGate(2).on_each([(q0, q1), (q2, q3)]) == [
        cirq.IdentityGate(2)(q0, q1),
        cirq.IdentityGate(2)(q2, q3),
    ]
    assert cirq.IdentityGate(2, (3, 3)).on_each([(q0_3, q1_3)]) == [
        cirq.IdentityGate(2, (3, 3))(q0_3, q1_3),
    ]
    assert cirq.IdentityGate(2).on_each(
        (q0, q1)) == [cirq.IdentityGate(2)(q0, q1)]
    with pytest.raises(ValueError,
                       match='Inputs to multi-qubit gates must be Sequence'):
        cirq.IdentityGate(2).on_each(q0, q1)
    with pytest.raises(ValueError,
                       match='All values in sequence should be Qids'):
        cirq.IdentityGate(2).on_each([[(q0, q1)]])
    with pytest.raises(ValueError, match='Expected 2 qubits'):
        cirq.IdentityGate(2).on_each([(q0, )])
    with pytest.raises(ValueError, match='Expected 2 qubits'):
        cirq.IdentityGate(2).on_each([(q0, q1, q2)])
Exemple #15
0
@pytest.mark.parametrize(
    'gate',
    [
        cirq.X,
        cirq.X ** 0.5,
        cirq.rx(np.pi),
        cirq.rx(np.pi / 2),
        cirq.Z,
        cirq.H,
        cirq.CNOT,
        cirq.SWAP,
        cirq.CCZ,
        cirq.ControlledGate(cirq.ControlledGate(cirq.CCZ)),
        GateUsingWorkspaceForApplyUnitary(),
        GateAllocatingNewSpaceForResult(),
        cirq.IdentityGate(qid_shape=(3, 4)),
        # Single qudit gate with dimension 4.
        cirq.MatrixGate(np.kron(*(cirq.unitary(cirq.H),) * 2)),
    ],
)
def test_controlled_gate_is_consistent(gate: cirq.Gate):
    cgate = cirq.ControlledGate(gate)
    cirq.testing.assert_implements_consistent_protocols(cgate)


def test_pow_inverse():
    assert cirq.inverse(CRestricted, None) is None
    assert cirq.pow(CRestricted, 1.5, None) is None
    assert cirq.pow(CY, 1.5) == cirq.ControlledGate(cirq.Y ** 1.5)
    assert cirq.inverse(CY) == CY ** -1 == CY
Exemple #16
0
def matrix_to_sycamore_operations(
        target_qubits: List[cirq.GridQubit],
        matrix: np.ndarray) -> Tuple[cirq.OP_TREE, List[cirq.GridQubit]]:
    """A method to convert a unitary matrix to a list of Sycamore operations.

    This method will return a list of `cirq.Operation`s using the qubits and (optionally) ancilla
    qubits to implement the unitary matrix `matrix` on the target qubits `qubits`.
    The operations are also supported by `cirq.google.gate_sets.SYC_GATESET`.

    Args:
        target_qubits: list of qubits the returned operations will act on. The qubit order defined by the list
            is assumed to be used by the operations to implement `matrix`.
        matrix: a matrix that is guaranteed to be unitary and of size (2**len(qs), 2**len(qs)).
    Returns:
        A tuple of operations and ancilla qubits allocated.
            Operations: In case the matrix is supported, a list of operations `ops` is returned.
                `ops` acts on `qs` qubits and for which `cirq.unitary(ops)` is equal to `matrix` up
                 to certain tolerance. In case the matrix is not supported, it might return NotImplemented to
                 reduce the noise in the judge output.
            Ancilla qubits: In case ancilla qubits are allocated a list of ancilla qubits. Otherwise
                an empty list.
        .
    """
    converter = cirq.google.ConvertToSycamoreGates()
    xmon_converter = cirq.google.ConvertToXmonGates()

    increment_unitaries = []
    for i in range(1, 10):
        inp = np.empty((2**i, 2**i))
        inp[1:] = np.eye(2**i)[:-1]
        inp[:1] = np.eye(2**i)[-1:]
        increment_unitaries.append(inp)

    oneQ_unitaries = [(cirq.unitary(cirq.X), cirq.X),
                      (cirq.unitary(cirq.Y), cirq.Y),
                      (cirq.unitary(cirq.Z), cirq.Z),
                      (cirq.unitary(cirq.H), cirq.H),
                      (cirq.unitary(cirq.S), cirq.S),
                      (cirq.unitary(cirq.T), cirq.T)]

    twoQ_sycamore_unitaries = [(cirq.unitary(cirq.google.SycamoreGate()),
                                cirq.google.SycamoreGate()),
                               (cirq.unitary(cirq.IdentityGate(num_qubits=2)),
                                cirq.IdentityGate(num_qubits=2)),
                               (cirq.unitary(cirq.XX), cirq.XX),
                               (cirq.unitary(cirq.YY), cirq.YY)]

    twoQ_xmon_unitaries = [(cirq.unitary(cirq.ZZ), cirq.ZZ),
                           (cirq.unitary(cirq.CX), cirq.CX)]

    threeQ_sycamore_unitaries = [
        (cirq.unitary(cirq.CCX), cirq.CCX),
        (cirq.unitary(cirq.CSWAP), cirq.CSWAP),
        # (cirq.unitary(cirq.ControlledGate(cirq.ISWAP ** 0.5)), cirq.ControlledGate(cirq.ISWAP ** 0.5)),
        (cirq.unitary(cirq.CCZ), cirq.CCZ),
        (cirq.unitary(cirq.IdentityGate(num_qubits=3)),
         cirq.IdentityGate(num_qubits=3))
    ]

    fourQ_sycamore_unitaries = [(cirq.unitary(cirq.IdentityGate(num_qubits=4)),
                                 cirq.IdentityGate(num_qubits=4))]

    def controlled_sqrt_iswap(qs):
        c = cirq.Circuit()
        c.append(cirq.ControlledGate(cirq.Y**-0.5).on(qs[0], qs[2]))
        c.append(cirq.CCZ.on(qs[0], qs[1], qs[2]))
        c.append(cirq.ControlledGate(cirq.Y**0.5).on(qs[0], qs[2]))
        c.append(cirq.ControlledGate(cirq.Y**0.5).on(qs[0], qs[1]))
        c.append(cirq.CX.on(qs[0], qs[1]))
        c.append(cirq.ControlledGate(cirq.Y**-0.5).on(qs[0], qs[1]))
        c.append(cirq.CCZ(qs[0], qs[1], qs[2]))
        c.append(cirq.ControlledGate(cirq.Y**0.5).on(qs[0], qs[1]))
        c.append(cirq.ControlledGate(cirq.T).on(qs[0], qs[1]))
        c.append(cirq.ControlledGate(cirq.Y**-0.5).on(qs[0], qs[1]))
        c.append(cirq.CCZ(qs[0], qs[1], qs[2]))
        c.append(cirq.ControlledGate(cirq.Y**-0.5).on(qs[0], qs[2]))
        c.append(cirq.ControlledGate(cirq.Y**0.5).on(qs[0], qs[1]))
        c.append(cirq.ControlledGate(cirq.Z**-0.25).on(qs[0], qs[1]))
        c.append(cirq.ControlledGate(cirq.Y**0.5).on(qs[0], qs[1]))
        c.append(cirq.CX.on(qs[0], qs[1]))
        c.append(cirq.CCZ.on(qs[0], qs[1], qs[2]))
        c.append(cirq.ControlledGate(cirq.Y**0.5).on(qs[0], qs[2]))
        return c

    def keep_func(gate):
        if cirq.unitary(gate).shape[0] < 5:
            return True
        else:
            return False

    def twoQ_sycamore_optimize(target_qubits, gate):
        g = gate.on(target_qubits[0], target_qubits[1])
        g = converter.convert(g)
        c = cirq.Circuit(g)
        c = cirq.google.optimized_for_sycamore(c, optimizer_type="sycamore")
        return c, []

    def twoQ_xmon_optimize(target_qubits, gate):
        g = gate.on(target_qubits[0], target_qubits[1])
        g = converter.convert(g)
        c = cirq.Circuit(g)
        c = cirq.google.optimized_for_sycamore(c, optimizer_type="xmon")
        return c, []

    # TODO: Fix up the CISWAP
    def threeQ_sycamore_optimize(target_qubits, gate):
        g = gate.on(*target_qubits)
        g = converter.convert(g)
        c = cirq.Circuit(g)
        c = cirq.google.optimized_for_sycamore(c, optimizer_type="xmon")
        return c, []

    def sycamore_optimize(target_qubits, gate):
        g = gate.on(*target_qubits)
        g = cirq.decompose(g, keep=keep_func)
        c = cirq.Circuit(g)
        c = cirq.google.optimized_for_sycamore(c, optimizer_type="sycamore")
        return c, []

    if matrix.shape[0] == 4:
        for twoQ_sycamore_unitary in twoQ_sycamore_unitaries:
            if np.isclose(matrix, twoQ_sycamore_unitary[0]).all():
                return twoQ_sycamore_optimize(target_qubits,
                                              twoQ_sycamore_unitary[1])

        for twoQ_xmon_unitary in twoQ_xmon_unitaries:
            if np.isclose(matrix, twoQ_xmon_unitary[0]).all():
                return twoQ_xmon_optimize(target_qubits, twoQ_xmon_unitary[1])

    if matrix.shape[0] == 8:
        #         if np.isclose(matrix, cirq.unitary(cirq.ControlledGate(cirq.ISWAP ** 0.5))).all():
        # #             g = cirq.ControlledGate(cirq.ISWAP ** 0.5).on(*target_qubits)
        # #             g = cirq.decompose(g)
        # #             c = controlled_sqrt_iswap(target_qubits)
        #             g = cirq.FSimGate(-np.pi/4, 0)
        #             g = cirq.decompose(g.on(*target_qubits))
        #             c = cirq.Circuit(g)
        #             return cirq.decompose(c, keep=keep_func), []
        for threeQ_sycamore_unitary in threeQ_sycamore_unitaries:
            if np.isclose(matrix, threeQ_sycamore_unitary[0]).all():
                return threeQ_sycamore_optimize(target_qubits,
                                                threeQ_sycamore_unitary[1])

    if len(target_qubits) == 1:
        for g in oneQ_unitaries:
            if np.isclose(matrix, g[0]).all():
                gate = converter.convert(g[1].on(*target_qubits))
                return gate, []

    def CNOT_toffoli_decomp(bitset, garbage, t, d):
        target = t
        gates = []
        for i in range(1, len(bitset) - 1):
            gates.append(cirq.CCX(garbage[-i - d], bitset[-i], target))
            target = garbage[-i - d]
        for gate in gates:
            yield gate
        gates.reverse()
        yield cirq.CCX(bitset[0], bitset[1], target)
        for gate in gates[:-1]:
            yield gate

    def CNOT_toffoli_decomp(bitset, garbage, t, d):
        target = t
        gates = []
        for i in range(1, len(bitset) - 1):
            gates.append(cirq.CCX(garbage[-i - d], bitset[-i], target))
            target = garbage[-i - d]
        gates.append(cirq.CCX(bitset[0], bitset[1], target))
        for gate in gates:
            yield gate
        gates.reverse()
        for gate in gates[1:]:
            yield gate
        gates.reverse()
        for gate in gates[1:]:
            yield gate
        gates.reverse()
        for gate in gates[1:-1]:
            yield gate

    def decompose_large_CNOT(control_qubits, target, ancilla):
        if len(control_qubits) == 0:
            return cirq.X(target)

        if len(control_qubits) == 1:
            return cirq.CX(control_qubits[0], target)

        if len(control_qubits) == 2:
            return cirq.CCX(control_qubits[0], control_qubits[1], target)

        bitset1 = [tq for i, tq in enumerate(control_qubits) if i % 2 == 0]
        bitset2 = [tq for i, tq in enumerate(control_qubits) if i % 2 == 1]
        bitset2.append(ancilla)
        gate1 = CNOT_toffoli_decomp(bitset1, bitset2, ancilla, 1)
        gate2 = CNOT_toffoli_decomp(bitset2, bitset1, target, 0)
        gate3 = CNOT_toffoli_decomp(bitset1, bitset2, ancilla, 1)
        gate4 = CNOT_toffoli_decomp(bitset2, bitset1, target, 0)
        return cirq.Circuit([gate1, gate2, gate3, gate4])

    if len(target_qubits) == 4:
        for fourQ_sycamore_unitary in fourQ_sycamore_unitaries:
            if np.isclose(matrix, fourQ_sycamore_unitary[0]).all():
                return sycamore_optimize(target_qubits,
                                         fourQ_sycamore_unitary[1])

        if np.isclose(matrix,
                      cirq.unitary(cirq.ControlledGate(cirq.CCX))).all():
            control_qubits = target_qubits[:-1]
            target = target_qubits[-1]
            ancilla = cirq.GridQubit(2, 3)
            c = decompose_large_CNOT(control_qubits, target, ancilla)
            return cirq.decompose(c), [ancilla]

    def increment(qubits):
        n_qubits = len(qubits)
        ancilla = cirq.GridQubit(2, 3)
        c = cirq.Circuit()
        for i in range(n_qubits):
            control_qubits = qubits[i + 1:]
            target = qubits[i]
            c.append(decompose_large_CNOT(control_qubits, target, ancilla))
        if n_qubits < 3:
            return c, []
        return c, [ancilla]

    def is_adjacent(q1, q2):
        return (q1.row == q2.row and np.abs(q1.col - q2.col)
                == 1) or (np.abs(q1.row - q2.row) == 1 and q1.col == q2.col)

    def swap_path(qs, q1, q2):
        path = []
        if q1 == q2:
            return path
        q = q1
        while not is_adjacent(q, q2):
            if not q2.row - q.row == 0:
                row_dir = int((q2.row - q.row) / np.abs(q2.row - q.row))
                if cirq.GridQubit(q.row + row_dir, q.col) in qs:
                    q = cirq.GridQubit(q.row + row_dir, q.col)
                    path.append(q)
                    continue
            if not q2.col - q.col == 0:
                col_dir = int((q2.col - q.col) / np.abs(q2.col - q.col))
                q = cirq.GridQubit(q.row, q.col + col_dir)
                path.append(q)
        return path

    def two_q_sycamore(g, q1, q2, qs):
        sp = swap_path(qs, q1, q2)
        if len(sp) == 0:
            yield g
            return
        q = q1
        for i in range(len(sp)):
            yield cirq.SWAP(q, sp[i])
            q = sp[i]
        yield g.gate(q, q2)
        sp.reverse()
        for i in range(1, len(sp)):
            yield cirq.SWAP(q, sp[i])
            q = sp[i]
        yield cirq.SWAP(q, q1)

    for U in increment_unitaries:
        if U.shape == matrix.shape:
            if np.isclose(U, matrix).all():
                if len(target_qubits) >= 7:
                    c, a = increment(target_qubits)
                    c = cirq.decompose(c)
                    # return c, a
                    cn = cirq.Circuit()
                    for g in c:
                        if len(g.qubits) == 1:
                            cn.append(g)
                        else:
                            q1 = g.qubits[0]
                            q2 = g.qubits[1]
                            cn.append(
                                cirq.Circuit(
                                    two_q_sycamore(g, q1, q2, target_qubits)))
                    return converter.convert(cn), a
                else:
                    c, a = increment(target_qubits)
                    c = cirq.decompose(c)
                    return c, a

    def isDiag(M):
        i, j = np.nonzero(M)
        return np.all(i == j)

    if isDiag(matrix):
        if np.isclose(matrix.diagonal(), 1).all():
            return cirq.Circuit(), []

    if isDiag(matrix):
        diagonal = matrix.diagonal()
        diagangles = (-1j * np.log(diagonal)).real

        diag_gate = cirq.DiagonalGate(diagangles)
        gate = diag_gate(*target_qubits)._decompose_()[1:]
        gate = converter.convert(gate)
        diag_circuit = cirq.Circuit(gate)
        return diag_circuit, []

    def pulverize_matrix(m):
        # N = 2^n
        N = len(m)

        L, CS, R = scipy.linalg.cossin(m, p=N / 2, q=N / 2)

        if len(m) == 2:
            stacked_matrices = np.stack([L, CS, R])
            return stacked_matrices

        # BREAK DOWN L MATRIX
        L1 = L[:round(N / 2), :round(N / 2)]
        L2 = L[round(N / 2):, round(N / 2):]

        L1_decomp = pulverize_matrix(L1)
        L2_decomp = pulverize_matrix(L2)

        left_matrices = 1j * np.zeros([
            L1_decomp.shape[0], L1_decomp.shape[1] * 2, L1_decomp.shape[2] * 2
        ])
        left_matrices[:, :round(N / 2), :round(N / 2)] += L1_decomp
        left_matrices[:, round(N / 2):, round(N / 2):] += L2_decomp

        # BREAK DOWN R MATRIX
        R1 = R[:round(N / 2), :round(N / 2)]
        R2 = R[round(N / 2):, round(N / 2):]

        R1_decomp = pulverize_matrix(R1)
        R2_decomp = pulverize_matrix(R2)

        right_matrices = 1j * np.zeros([
            R1_decomp.shape[0], R1_decomp.shape[1] * 2, R1_decomp.shape[2] * 2
        ])
        right_matrices[:, :round(N / 2), :round(N / 2)] += R1_decomp
        right_matrices[:, round(N / 2):, round(N / 2):] += R2_decomp

        all_matrices = np.concatenate(
            [left_matrices, CS[None], right_matrices])
        return all_matrices

    def get_S_matrix(m):
        S = np.zeros([round(2**int(m)), round(2**int(m))]) + 1

        cols = [
            np.sign(
                np.cos(2**(m - 1 - i) * np.pi * np.arange(0, 2**int(m), 1) /
                       2**int(m) + 10**-6)) for i in range(int(m))
        ]

        for bit in range(len(cols)):
            for i in range(len(S)):
                if round(2**bit) & i:
                    S[:, i] *= cols[bit]

        return S

    def gray_code_changes(m):
        return gray_code_changes_r(m) + [m]

    def gray_code_changes_r(m):
        if m < 0:
            return []
        return gray_code_changes_r(m - 1) + [m] + gray_code_changes_r(m - 1)

    def UCRy(ctrls, target, alphas, S_T_inv, seq):

        thetas = np.matmul(S_T_inv, alphas)

        gates = []
        for i in range(len(seq)):
            theta_i = thetas[i]
            q_i = ctrls[int(seq[i])]
            gates += [cirq.Ry(rads=theta_i)(target)]
            gates += [cirq.CNOT(q_i, target)]

        return gates

    def ry_angle(u):
        u_log = 1j * scipy.linalg.logm(u)
        return ((2j * u_log[0][1]).real)

    def extract_ry_angles(matrix, target_bit, n):
        alphas = []
        for i in range(len(matrix)):
            if not int(2**(n - 1 - target_bit)) & i:
                ry_gate = matrix[(i, i + int(2**(n - 1 - target_bit))), :][:, (
                    i, i + int(2**(n - 1 - target_bit)))]
                alphas += [ry_angle(ry_gate)]
        alphas = np.array(alphas)
        return alphas

    def UCRy_gates_from_matrix(matrix, target_bit, qs, n, S_T_inv):
        alphas = extract_ry_angles(matrix, target_bit, n)
        ctrl_qs = qs[0:int(target_bit)] + qs[int(target_bit) + 1:]
        gates = UCRy(ctrl_qs[::-1], qs[int(target_bit)], alphas, S_T_inv,
                     gray_code_changes(n - 2))
        return gates

    def arbitrary_diagonal_gate_from_matrix(matrix, qs):
        diagonal = matrix.diagonal()
        diagangles = (-1j * np.log(diagonal)).real
        diag_gate = cirq.DiagonalGate(diagangles)
        gates = diag_gate(*qs)._decompose_()[0:]
        return (gates)

    def arbitrary_operation_from_matrix(U, qs):
        n = round(np.log2(len(U)))
        S = get_S_matrix(n - 1)
        S_T_inv = np.linalg.inv(S.transpose())

        matrices = pulverize_matrix(U)
        ucry_target_bits = [n - 1 - i for i in gray_code_changes(n - 1)[:-1]]

        gates = []

        for m_i in range(len(matrices)):
            # print(m_i, "/", len(matrices))
            if m_i % 2 == 0:
                gates = arbitrary_diagonal_gate_from_matrix(matrices[m_i],
                                                            qs) + gates
                # print(np.sum(np.abs(cirq.unitary(cirq.Circuit(arbitrary_diagonal_gate_from_matrix(matrices[m_i], qs))) - matrices[m_i])))
                # print(matrices[m_i])
            else:
                target_bit = ucry_target_bits[int(m_i / 2)]
                gates = UCRy_gates_from_matrix(matrices[m_i], target_bit, qs,
                                               n, S_T_inv) + gates
                # print(np.sum(np.abs(cirq.unitary(cirq.Circuit(UCRy_gates_from_matrix(matrices[m_i], target_bit, qs, n, S_T_inv))) - matrices[m_i])))

        return gates

    gates = arbitrary_operation_from_matrix(matrix, target_qubits)

    c = cirq.Circuit()
    if len(target_qubits) < 8:
        for g in gates:
            if len(g.qubits) == 1:
                c.append(g)
            elif len(g.qubits) == 2:
                q1 = g.qubits[0]
                q2 = g.qubits[1]
                c.append(cirq.Circuit(two_q_sycamore(g, q1, q2,
                                                     target_qubits)))
        return converter.convert(c), []

    else:
        c.append(gates)
        return c, []

    return NotImplemented, []
    # Some random points
    random_unitary(17323),
    random_unitary(99415),
    random_unitary(65832),
    random_unitary(45373),
    random_unitary(27123),
]
ONE_SQRT_ISWAP_UNITARIES = [
    *perturbations_gate(cirq.SQRT_ISWAP),
    *perturbations_gate(cirq.ISwapPowGate(exponent=-0.5, global_shift=1)),
    *perturbations_unitary(random_locals(np.pi / 8, np.pi / 8, 0, seed=80342)),
    *perturbations_unitary(random_locals(np.pi / 8, np.pi / 8, 0, seed=83551)),
    *perturbations_unitary(random_locals(np.pi / 8, np.pi / 8, 0, seed=52450)),
]
ZERO_UNITARIES = [
    *perturbations_gate(cirq.IdentityGate(2)),
    *perturbations_unitary(random_locals(0, 0, 0, seed=62933)),
    *perturbations_unitary(random_locals(0, 0, 0, seed=50590)),
]

# Lists of seeds for cirq.testing.random_unitary(4, random_state=seed)
# corresponding to different regions in the Weyl chamber and possible
# eigenvalue crossings in the 3-SQRT_ISWAP decomposition
# Key: 1 (fig. 4):  x < y + abs(z)
#      2 (fig. 7a): x > pi/8
#      4 (fig. 7b): z < 0
#      8 (fig. 7c): y+abs(z) < pi/8 if x <= pi/8 else y+abs(z) < pi/4
WEYL_REGION_UNITARIES = {
    1: list(map(random_unitary, [49903, 84819, 84769])),
    3: list(map(random_unitary, [89483, 79607, 96012])),
    5: list(map(random_unitary, [31979, 78758, 47661])),
Exemple #18
0
def test_identity_trace_distance_bound():
    assert cirq.I._trace_distance_bound_() == 0
    assert cirq.IdentityGate(num_qubits=2)._trace_distance_bound_() == 0
Exemple #19
0
    expected_expansion = cirq.pauli_expansion(expected)
    assert set(actual_expansion.keys()) == set(expected_expansion.keys())
    for name in actual_expansion.keys():
        assert abs(actual_expansion[name] - expected_expansion[name]) < 1e-12


@pytest.mark.parametrize('expression, expected_result', (
    ((cirq.X + cirq.Z) / np.sqrt(2), cirq.H),
    (cirq.X - cirq.Y, -cirq.Y + cirq.X),
    (cirq.X + cirq.S - cirq.X, cirq.S),
    (cirq.Y - 2 * cirq.Y, -cirq.Y),
    (cirq.Rx(0.2), np.cos(0.1) * cirq.I - 1j * np.sin(0.1) * cirq.X),
    (1j * cirq.H * 1j, -cirq.H),
    (-1j * cirq.Y, cirq.Ry(np.pi)),
    (np.sqrt(-1j) * cirq.S, cirq.Rz(np.pi / 2)),
    (0.5 * (cirq.IdentityGate(2) + cirq.XX + cirq.YY + cirq.ZZ), cirq.SWAP),
    ((cirq.IdentityGate(2) + 1j *
      (cirq.XX + cirq.YY) + cirq.ZZ) / 2, cirq.ISWAP),
    (cirq.CNOT + 0 * cirq.SWAP, cirq.CNOT),
    (0.5 * cirq.FREDKIN, cirq.FREDKIN / 2),
    (cirq.FREDKIN * 0.5, cirq.FREDKIN / 2),
    (((cirq.X + cirq.Y) / np.sqrt(2))**2, cirq.I),
    ((cirq.X + cirq.Z)**3, 2 * (cirq.X + cirq.Z)),
    ((cirq.X + 1j * cirq.Y)**2, cirq.LinearCombinationOfGates({})),
    ((cirq.X - 1j * cirq.Y)**2, cirq.LinearCombinationOfGates({})),
    (((3 * cirq.X - 4 * cirq.Y + 12 * cirq.Z) / 13)**24, cirq.I),
    (((3 * cirq.X - 4 * cirq.Y + 12 * cirq.Z) / 13)**25,
     (3 * cirq.X - 4 * cirq.Y + 12 * cirq.Z) / 13),
))
def test_gate_expressions(expression, expected_result):
    assert_linear_combinations_are_equal(expression, expected_result)
Exemple #20
0
def test_pauli_expansion_notimplemented():
    assert cirq.IdentityGate(1, (3, ))._pauli_expansion_() == NotImplemented
Exemple #21
0
    def _sample_measure_results(
        self,
        program: cirq.Circuit,
        repetitions: int = 1,
    ) -> Dict[str, np.ndarray]:
        """Samples from measurement gates in the circuit.

        Note that this will execute the circuit 'repetitions' times.

        Args:
            program: The circuit to sample from.
            repetitions: The number of samples to take.

        Returns:
            A dictionary from measurement gate key to measurement
            results. Measurement results are stored in a 2-dimensional
            numpy array, the first dimension corresponding to the repetition
            and the second to the actual boolean measurement results (ordered
            by the qubits being measured.)

        Raises:
            ValueError: If there are multiple MeasurementGates with the same key,
                or if repetitions is negative.
        """

        # Add noise to the circuit if a noise model was provided.
        all_qubits = program.all_qubits()
        program = qsimc.QSimCircuit(
            self.noise.noisy_moments(program, sorted(all_qubits))
            if self.noise is not cirq.NO_NOISE else program, )

        # Compute indices of measured qubits
        ordered_qubits = cirq.QubitOrder.DEFAULT.order_for(all_qubits)
        num_qubits = len(ordered_qubits)

        qubit_map = {
            qubit: index
            for index, qubit in enumerate(ordered_qubits)
        }

        # Compute:
        # - number of qubits for each measurement key.
        # - measurement ops for each measurement key.
        # - measurement info for each measurement.
        # - total number of measured bits.
        measurement_ops = [
            op for _, op, _ in program.findall_operations_with_gate_type(
                cirq.MeasurementGate)
        ]
        num_qubits_by_key: Dict[str, int] = {}
        meas_ops: Dict[str, List[cirq.GateOperation]] = {}
        meas_infos: List[MeasInfo] = []
        num_bits = 0
        for op in measurement_ops:
            gate = op.gate
            key = cirq.measurement_key_name(gate)
            meas_ops.setdefault(key, [])
            i = len(meas_ops[key])
            meas_ops[key].append(op)
            n = len(op.qubits)
            if key in num_qubits_by_key:
                if n != num_qubits_by_key[key]:
                    raise ValueError(
                        f"repeated key {key!r} with different numbers of qubits: "
                        f"{num_qubits_by_key[key]} != {n}")
            else:
                num_qubits_by_key[key] = n
            meas_infos.append(
                MeasInfo(
                    key=key,
                    idx=i,
                    invert_mask=gate.full_invert_mask(),
                    start=num_bits,
                    end=num_bits + n,
                ))
            num_bits += n

        # Set qsim options
        options = {**self.qsim_options}

        results = {
            key: np.ndarray(shape=(repetitions, len(meas_ops[key]), n),
                            dtype=int)
            for key, n in num_qubits_by_key.items()
        }

        noisy = _needs_trajectories(program)
        if not noisy and program.are_all_measurements_terminal(
        ) and repetitions > 1:
            # Measurements must be replaced with identity gates to sample properly.
            # Simply removing them may omit qubits from the circuit.
            for i in range(len(program.moments)):
                program.moments[i] = cirq.Moment(
                    op if not isinstance(op.gate, cirq.MeasurementGate) else
                    [cirq.IdentityGate(1).on(q) for q in op.qubits]
                    for op in program.moments[i])
            translator_fn_name = "translate_cirq_to_qsim"
            options["c"], _ = self._translate_circuit(
                program,
                translator_fn_name,
                cirq.QubitOrder.DEFAULT,
            )
            options["s"] = self.get_seed()
            raw_results = self._sim_module.qsim_sample_final(
                options, repetitions)
            full_results = np.array([[
                bool(result & (1 << q)) for q in reversed(range(num_qubits))
            ] for result in raw_results])

            for key, oplist in meas_ops.items():
                for i, op in enumerate(oplist):
                    meas_indices = [qubit_map[qubit] for qubit in op.qubits]
                    invert_mask = op.gate.full_invert_mask()
                    # Apply invert mask to re-ordered results
                    results[
                        key][:,
                             i, :] = full_results[:,
                                                  meas_indices] ^ invert_mask

        else:
            if noisy:
                translator_fn_name = "translate_cirq_to_qtrajectory"
                sampler_fn = self._sim_module.qtrajectory_sample
            else:
                translator_fn_name = "translate_cirq_to_qsim"
                sampler_fn = self._sim_module.qsim_sample

            options["c"], _ = self._translate_circuit(
                program,
                translator_fn_name,
                cirq.QubitOrder.DEFAULT,
            )
            measurements = np.empty(shape=(repetitions, num_bits), dtype=int)
            for i in range(repetitions):
                options["s"] = self.get_seed()
                measurements[i] = sampler_fn(options)

            for m in meas_infos:
                results[m.key][:, m.idx, :] = (measurements[:, m.start:m.end]
                                               ^ m.invert_mask)

        return results
Exemple #22
0
def test_identity_str():
    assert str(cirq.IdentityGate(1)) == 'I'
    assert str(cirq.IdentityGate(2)) == 'I(2)'
    # Qid shape is not included in str
    assert str(cirq.IdentityGate(1, (3, ))) == 'I'
    assert str(cirq.IdentityGate(2, (1, 2))) == 'I(2)'
def test_identity_unitary(num_qubits):
    i = cirq.IdentityGate(num_qubits)
    assert np.allclose(cirq.unitary(i), np.identity(2**num_qubits))
Exemple #24
0
def test_identity_repr():
    assert repr(cirq.IdentityGate(2)) == 'cirq.IdentityGate(2)'
    assert repr(cirq.I) == 'cirq.I'
    assert repr(cirq.IdentityGate(2, (2, 3))) == 'cirq.IdentityGate(2, (2, 3))'
def test_identity_repr():
    assert repr(cirq.IdentityGate(2)) == 'cirq.IdentityGate(2)'
def test_subcircuit_identity_does_not_join():
    args = create_container(qs2)
    assert len(set(args.values())) == 3
    args.apply_operation(cirq.CircuitOperation(cirq.FrozenCircuit(cirq.IdentityGate(2)(q0, q1))))
    assert len(set(args.values())) == 3
    assert args[q0] is not args[q1]
def test_kak_vector_negative_atol():
    with pytest.raises(ValueError, match='must be positive'):
        cirq.kak_vector(np.eye(4), atol=-1.0)


def test_kak_vector_input_not_unitary():
    with pytest.raises(ValueError, match='must correspond to'):
        cirq.kak_vector(np.zeros((4, 4)))


@pytest.mark.parametrize(
    'unitary',
    [
        cirq.testing.random_unitary(4),
        cirq.unitary(cirq.IdentityGate(2)),
        cirq.unitary(cirq.SWAP),
        cirq.unitary(cirq.SWAP**0.25),
        cirq.unitary(cirq.ISWAP),
        cirq.unitary(cirq.CZ**0.5),
        cirq.unitary(cirq.CZ),
    ],
)
def test_kak_decompose(unitary: np.ndarray):
    kak = cirq.kak_decomposition(unitary)
    circuit = cirq.Circuit(kak._decompose_(cirq.LineQubit.range(2)))
    np.testing.assert_allclose(cirq.unitary(circuit), unitary, atol=1e-8)
    assert len(circuit) == 5
    assert len(list(circuit.all_operations())) == 8

Exemple #28
0
def test_cirq_qsim_all_supported_gates():
    q0 = cirq.GridQubit(1, 1)
    q1 = cirq.GridQubit(1, 0)
    q2 = cirq.GridQubit(0, 1)
    q3 = cirq.GridQubit(0, 0)

    circuit = cirq.Circuit(
        cirq.Moment([
            cirq.H(q0),
            cirq.H(q1),
            cirq.H(q2),
            cirq.H(q3),
        ]),
        cirq.Moment([
            cirq.T(q0),
            cirq.T(q1),
            cirq.T(q2),
            cirq.T(q3),
        ]),
        cirq.Moment([
            cirq.CZPowGate(exponent=0.7, global_shift=0.2)(q0, q1),
            cirq.CXPowGate(exponent=1.2, global_shift=0.4)(q2, q3),
        ]),
        cirq.Moment([
            cirq.XPowGate(exponent=0.3, global_shift=1.1)(q0),
            cirq.YPowGate(exponent=0.4, global_shift=1)(q1),
            cirq.ZPowGate(exponent=0.5, global_shift=0.9)(q2),
            cirq.HPowGate(exponent=0.6, global_shift=0.8)(q3),
        ]),
        cirq.Moment([
            cirq.CX(q0, q2),
            cirq.CZ(q1, q3),
        ]),
        cirq.Moment([
            cirq.X(q0),
            cirq.Y(q1),
            cirq.Z(q2),
            cirq.S(q3),
        ]),
        cirq.Moment([
            cirq.XXPowGate(exponent=0.4, global_shift=0.7)(q0, q1),
            cirq.YYPowGate(exponent=0.8, global_shift=0.5)(q2, q3),
        ]),
        cirq.Moment([cirq.I(q0),
                     cirq.I(q1),
                     cirq.IdentityGate(2)(q2, q3)]),
        cirq.Moment([
            cirq.rx(0.7)(q0),
            cirq.ry(0.2)(q1),
            cirq.rz(0.4)(q2),
            cirq.PhasedXPowGate(phase_exponent=0.8,
                                exponent=0.6,
                                global_shift=0.3)(q3),
        ]),
        cirq.Moment([
            cirq.ZZPowGate(exponent=0.3, global_shift=1.3)(q0, q2),
            cirq.ISwapPowGate(exponent=0.6, global_shift=1.2)(q1, q3),
        ]),
        cirq.Moment([
            cirq.XPowGate(exponent=0.1, global_shift=0.9)(q0),
            cirq.YPowGate(exponent=0.2, global_shift=1)(q1),
            cirq.ZPowGate(exponent=0.3, global_shift=1.1)(q2),
            cirq.HPowGate(exponent=0.4, global_shift=1.2)(q3),
        ]),
        cirq.Moment([
            cirq.SwapPowGate(exponent=0.2, global_shift=0.9)(q0, q1),
            cirq.PhasedISwapPowGate(phase_exponent=0.8, exponent=0.6)(q2, q3),
        ]),
        cirq.Moment([
            cirq.PhasedXZGate(x_exponent=0.2,
                              z_exponent=0.3,
                              axis_phase_exponent=1.4)(q0),
            cirq.T(q1),
            cirq.H(q2),
            cirq.S(q3),
        ]),
        cirq.Moment([
            cirq.SWAP(q0, q2),
            cirq.XX(q1, q3),
        ]),
        cirq.Moment([
            cirq.rx(0.8)(q0),
            cirq.ry(0.9)(q1),
            cirq.rz(1.2)(q2),
            cirq.T(q3),
        ]),
        cirq.Moment([
            cirq.YY(q0, q1),
            cirq.ISWAP(q2, q3),
        ]),
        cirq.Moment([
            cirq.T(q0),
            cirq.Z(q1),
            cirq.Y(q2),
            cirq.X(q3),
        ]),
        cirq.Moment([
            cirq.FSimGate(0.3, 1.7)(q0, q2),
            cirq.ZZ(q1, q3),
        ]),
        cirq.Moment([
            cirq.ry(1.3)(q0),
            cirq.rz(0.4)(q1),
            cirq.rx(0.7)(q2),
            cirq.S(q3),
        ]),
        cirq.Moment([
            cirq.IdentityGate(4).on(q0, q1, q2, q3),
        ]),
        cirq.Moment([
            cirq.CCZPowGate(exponent=0.7, global_shift=0.3)(q2, q0, q1),
        ]),
        cirq.Moment([
            cirq.CCXPowGate(exponent=0.4, global_shift=0.6)(
                q3, q1, q0).controlled_by(q2, control_values=[0]),
        ]),
        cirq.Moment([
            cirq.rx(0.3)(q0),
            cirq.ry(0.5)(q1),
            cirq.rz(0.7)(q2),
            cirq.rx(0.9)(q3),
        ]),
        cirq.Moment([
            cirq.TwoQubitDiagonalGate([0.1, 0.2, 0.3, 0.4])(q0, q1),
        ]),
        cirq.Moment([
            cirq.ThreeQubitDiagonalGate([0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.2,
                                         1.3])(q1, q2, q3),
        ]),
        cirq.Moment([
            cirq.CSwapGate()(q0, q3, q1),
        ]),
        cirq.Moment([
            cirq.rz(0.6)(q0),
            cirq.rx(0.7)(q1),
            cirq.ry(0.8)(q2),
            cirq.rz(0.9)(q3),
        ]),
        cirq.Moment([
            cirq.TOFFOLI(q3, q2, q0),
        ]),
        cirq.Moment([
            cirq.FREDKIN(q1, q3, q2),
        ]),
        cirq.Moment([
            cirq.MatrixGate(
                np.array([[0, -0.5 - 0.5j, -0.5 - 0.5j, 0],
                          [0.5 - 0.5j, 0, 0, -0.5 + 0.5j],
                          [0.5 - 0.5j, 0, 0, 0.5 - 0.5j],
                          [0, -0.5 - 0.5j, 0.5 + 0.5j, 0]]))(q0, q1),
            cirq.MatrixGate(
                np.array([[0.5 - 0.5j, 0, 0, -0.5 + 0.5j],
                          [0, 0.5 - 0.5j, -0.5 + 0.5j, 0],
                          [0, -0.5 + 0.5j, -0.5 + 0.5j, 0],
                          [0.5 - 0.5j, 0, 0, 0.5 - 0.5j]]))(q2, q3),
        ]),
        cirq.Moment([
            cirq.MatrixGate(np.array([[1, 0], [0, 1j]]))(q0),
            cirq.MatrixGate(np.array([[0, -1j], [1j, 0]]))(q1),
            cirq.MatrixGate(np.array([[0, 1], [1, 0]]))(q2),
            cirq.MatrixGate(np.array([[1, 0], [0, -1]]))(q3),
        ]),
        cirq.Moment([
            cirq.riswap(0.7)(q0, q1),
            cirq.givens(1.2)(q2, q3),
        ]),
        cirq.Moment([
            cirq.H(q0),
            cirq.H(q1),
            cirq.H(q2),
            cirq.H(q3),
        ]),
    )

    simulator = cirq.Simulator()
    cirq_result = simulator.simulate(circuit)

    qsim_simulator = qsimcirq.QSimSimulator()
    qsim_result = qsim_simulator.simulate(circuit)

    assert cirq.linalg.allclose_up_to_global_phase(qsim_result.state_vector(),
                                                   cirq_result.state_vector())
import numpy as np
import cirq
import cirq_google

ALL_POSSIBLE_FSIM_GATES = [
    cirq.CZPowGate,
    cirq.FSimGate,
    cirq.PhasedFSimGate,
    cirq.ISwapPowGate,
    cirq.PhasedISwapPowGate,
    cirq.IdentityGate,
]
THETA, PHI = sympy.Symbol("theta"), sympy.Symbol("phi")
VALID_IDENTITY = [
    (cirq.CZ ** THETA, {THETA: 2}),
    (cirq.IdentityGate(2), {}),
    (cirq.FSimGate(THETA, PHI), {THETA: 0, PHI: 0}),
    (cirq.PhasedFSimGate(THETA, 0, 0, 0, PHI), {THETA: 0, PHI: 0}),
    (cirq.ISWAP ** THETA, {THETA: 4}),
    (cirq.PhasedISwapPowGate(exponent=THETA, phase_exponent=PHI), {THETA: 4, PHI: 2}),
]

VALID_CZPOW_GATES = [
    (cirq.CZPowGate(exponent=THETA, global_shift=2.5), {THETA: 0.1}),
    (cirq.CZ ** THETA, {THETA: 0.5}),
    (cirq.FSimGate(theta=THETA, phi=0.1), {THETA: 0}),
    (cirq.FSimGate(theta=2 * np.pi, phi=PHI), {PHI: -0.4}),
    (
        cirq.PhasedFSimGate.from_fsim_rz(
            theta=THETA,
            phi=10,
 def _convert_to_identity(
         self, g: POSSIBLE_FSIM_GATES) -> Optional[cirq.IdentityGate]:
     cg = self._convert_to_fsim(g)
     return (None if (cg is None or not self._approx_eq_or_symbol(
         (cg.theta, cg.phi), (0, 0))) else cirq.IdentityGate(2))