def test_decomposed_fallback():
    class Composite(cirq.Gate):
        def num_qubits(self) -> int:
            return 1

        def _decompose_(self, qubits):
            yield cirq.X(*qubits)

    args = cirq.StateVectorSimulationState(
        available_buffer=np.empty((2, 2, 2), dtype=np.complex64),
        qubits=cirq.LineQubit.range(3),
        prng=np.random.RandomState(),
        initial_state=cirq.one_hot(shape=(2, 2, 2), dtype=np.complex64),
        dtype=np.complex64,
    )

    cirq.act_on(Composite(), args, [cirq.LineQubit(1)])
    np.testing.assert_allclose(
        args.target_tensor,
        cirq.one_hot(index=(0, 1, 0), shape=(2, 2, 2), dtype=np.complex64))
Esempio n. 2
0
def test_decomposed_fallback():
    class Composite(cirq.Gate):
        def num_qubits(self) -> int:
            return 1

        def _decompose_(self, qubits):
            yield cirq.X(*qubits)

    args = cirq.ActOnStateVectorArgs(
        target_tensor=cirq.one_hot(shape=(2, 2, 2), dtype=np.complex64),
        available_buffer=np.empty((2, 2, 2), dtype=np.complex64),
        axes=[1],
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )

    cirq.act_on(Composite(), args)
    np.testing.assert_allclose(
        args.target_tensor,
        cirq.one_hot(index=(0, 1, 0), shape=(2, 2, 2), dtype=np.complex64))
Esempio n. 3
0
def test_reset_act_on():
    with pytest.raises(TypeError, match="Failed to act"):
        cirq.act_on(cirq.ResetChannel(), DummyActOnArgs(), qubits=())

    args = cirq.ActOnStateVectorArgs(
        available_buffer=np.empty(shape=(2, 2, 2, 2, 2), dtype=np.complex64),
        qubits=cirq.LineQubit.range(5),
        prng=np.random.RandomState(),
        log_of_measurement_results={},
        initial_state=cirq.one_hot(index=(1, 1, 1, 1, 1),
                                   shape=(2, 2, 2, 2, 2),
                                   dtype=np.complex64),
        dtype=np.complex64,
    )

    cirq.act_on(cirq.ResetChannel(), args, [cirq.LineQubit(1)])
    assert args.log_of_measurement_results == {}
    np.testing.assert_allclose(
        args.target_tensor,
        cirq.one_hot(index=(1, 0, 1, 1, 1),
                     shape=(2, 2, 2, 2, 2),
                     dtype=np.complex64),
    )

    cirq.act_on(cirq.ResetChannel(), args, [cirq.LineQubit(1)])
    assert args.log_of_measurement_results == {}
    np.testing.assert_allclose(
        args.target_tensor,
        cirq.one_hot(index=(1, 0, 1, 1, 1),
                     shape=(2, 2, 2, 2, 2),
                     dtype=np.complex64),
    )
Esempio n. 4
0
def test_reset_act_on():
    with pytest.raises(TypeError, match="Failed to act"):
        cirq.act_on(cirq.ResetChannel(), object())

    args = cirq.ActOnStateVectorArgs(
        target_tensor=cirq.one_hot(index=(1, 1, 1, 1, 1),
                                   shape=(2, 2, 2, 2, 2),
                                   dtype=np.complex64),
        available_buffer=np.empty(shape=(2, 2, 2, 2, 2)),
        axes=[1],
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )

    cirq.act_on(cirq.ResetChannel(), args)
    assert args.log_of_measurement_results == {}
    np.testing.assert_allclose(
        args.target_tensor,
        cirq.one_hot(index=(1, 0, 1, 1, 1),
                     shape=(2, 2, 2, 2, 2),
                     dtype=np.complex64),
    )

    cirq.act_on(cirq.ResetChannel(), args)
    assert args.log_of_measurement_results == {}
    np.testing.assert_allclose(
        args.target_tensor,
        cirq.one_hot(index=(1, 0, 1, 1, 1),
                     shape=(2, 2, 2, 2, 2),
                     dtype=np.complex64),
    )
Esempio n. 5
0
def test_tagged_act_on():
    class YesActOn(cirq.Gate):
        def _num_qubits_(self) -> int:
            return 1

        def _act_on_(self, args):
            return True

    class NoActOn(cirq.Gate):
        def _num_qubits_(self) -> int:
            return 1

        def _act_on_(self, args):
            return NotImplemented

    class MissingActOn(cirq.Operation):
        def with_qubits(self, *new_qubits):
            raise NotImplementedError()

        @property
        def qubits(self):
            raise NotImplementedError()

    q = cirq.LineQubit(1)
    cirq.act_on(YesActOn()(q).with_tags("test"), object())
    with pytest.raises(TypeError, match="Failed to act"):
        cirq.act_on(NoActOn()(q).with_tags("test"), object())
    with pytest.raises(TypeError, match="Failed to act"):
        cirq.act_on(MissingActOn().with_tags("test"), object())
Esempio n. 6
0
def test_unitary_fallback():
    class UnitaryXGate(cirq.testing.SingleQubitGate):
        def _unitary_(self):
            return np.array([[0, 1], [1, 0]])

    class UnitaryYGate(cirq.Gate):
        def _qid_shape_(self) -> Tuple[int, ...]:
            return (2, )

        def _unitary_(self):
            return np.array([[0, -1j], [1j, 0]])

    original_tableau = cirq.CliffordTableau(num_qubits=3)
    args = cirq.CliffordTableauSimulationState(
        tableau=original_tableau.copy(),
        qubits=cirq.LineQubit.range(3),
        prng=np.random.RandomState(),
    )

    cirq.act_on(UnitaryXGate(), args, [cirq.LineQubit(1)])
    assert args.tableau == cirq.CliffordTableau(num_qubits=3, initial_state=2)

    args = cirq.CliffordTableauSimulationState(
        tableau=original_tableau.copy(),
        qubits=cirq.LineQubit.range(3),
        prng=np.random.RandomState(),
    )
    cirq.act_on(UnitaryYGate(), args, [cirq.LineQubit(1)])
    expected_args = cirq.CliffordTableauSimulationState(
        tableau=original_tableau.copy(),
        qubits=cirq.LineQubit.range(3),
        prng=np.random.RandomState(),
    )
    cirq.act_on(cirq.Y, expected_args, [cirq.LineQubit(1)])
    assert args.tableau == expected_args.tableau
Esempio n. 7
0
def test_tagged_act_on():
    class YesActOn(cirq.Gate):
        def _num_qubits_(self) -> int:
            return 1

        def _act_on_(self, args, qubits):
            return True

    class NoActOn(cirq.Gate):
        def _num_qubits_(self) -> int:
            return 1

        def _act_on_(self, args, qubits):
            return NotImplemented

    class MissingActOn(cirq.Operation):
        def with_qubits(self, *new_qubits):
            raise NotImplementedError()

        @property
        def qubits(self):
            pass

    q = cirq.LineQubit(1)
    from cirq.protocols.act_on_protocol_test import DummyActOnArgs

    args = DummyActOnArgs()
    cirq.act_on(YesActOn()(q).with_tags("test"), args)
    with pytest.raises(TypeError, match="Failed to act"):
        cirq.act_on(NoActOn()(q).with_tags("test"), args)
    with pytest.raises(TypeError, match="Failed to act"):
        cirq.act_on(MissingActOn().with_tags("test"), args)
Esempio n. 8
0
def test_act_on_clifford_tableau():
    a, b = cirq.LineQubit.range(2)
    m = cirq.measure(a, b, key='out', invert_mask=(True, ))
    # The below assertion does not fail since it ignores non-unitary operations
    cirq.testing.assert_all_implemented_act_on_effects_match_unitary(m)

    with pytest.raises(TypeError, match="Failed to act"):
        cirq.act_on(m, object())

    args = cirq.ActOnCliffordTableauArgs(
        tableau=cirq.CliffordTableau(num_qubits=5, initial_state=0),
        axes=[3, 1],
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [1, 0]}

    args = cirq.ActOnCliffordTableauArgs(
        tableau=cirq.CliffordTableau(num_qubits=5, initial_state=8),
        axes=[3, 1],
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )

    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [1, 1]}

    args = cirq.ActOnCliffordTableauArgs(
        tableau=cirq.CliffordTableau(num_qubits=5, initial_state=10),
        axes=[3, 1],
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [0, 1]}

    with pytest.raises(ValueError, match="already logged to key"):
        cirq.act_on(m, args)
def test_probability_comes_up_short_results_in_fallback():
    class Short(cirq.Gate):
        def num_qubits(self) -> int:
            return 1

        def _kraus_(self):
            return [cirq.unitary(cirq.X) * np.sqrt(0.999), np.eye(2) * 0]

    mock_prng = mock.Mock()
    mock_prng.random.return_value = 0.9999

    args = cirq.StateVectorSimulationState(
        available_buffer=np.empty(2, dtype=np.complex64),
        qubits=cirq.LineQubit.range(1),
        prng=mock_prng,
        initial_state=np.array([1, 0], dtype=np.complex64),
        dtype=np.complex64,
    )

    cirq.act_on(Short(), args, cirq.LineQubit.range(1))

    np.testing.assert_allclose(args.target_tensor, np.array([0, 1]))
Esempio n. 10
0
def test_unitary_fallback_h():
    class UnitaryHGate(cirq.Gate):
        def num_qubits(self) -> int:
            return 1

        def _unitary_(self):
            return np.array([[1, 1], [1, -1]]) / (2**0.5)

    args = cirq.ActOnStabilizerCHFormArgs(
        qubits=cirq.LineQubit.range(3),
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )
    cirq.act_on(UnitaryHGate(), args, [cirq.LineQubit(1)])
    expected_args = cirq.ActOnStabilizerCHFormArgs(
        qubits=cirq.LineQubit.range(3),
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )
    cirq.act_on(cirq.H, expected_args, [cirq.LineQubit(1)])
    np.testing.assert_allclose(args.state.state_vector(),
                               expected_args.state.state_vector())
Esempio n. 11
0
def test_clifford_gate_act_on_large_case():
    n, num_ops = 50, 1000  # because we don't need unitary, it is fast.
    gate_candidate = [cirq.X, cirq.Y, cirq.Z, cirq.H, cirq.S, cirq.CNOT, cirq.CZ]
    for seed in range(10):
        prng = np.random.RandomState(seed)
        t1 = cirq.CliffordTableau(num_qubits=n)
        t2 = cirq.CliffordTableau(num_qubits=n)
        qubits = cirq.LineQubit.range(n)
        args1 = cirq.CliffordTableauSimulationState(tableau=t1, qubits=qubits, prng=prng)
        args2 = cirq.CliffordTableauSimulationState(tableau=t2, qubits=qubits, prng=prng)
        ops = []
        for _ in range(0, num_ops, 100):
            g = prng.randint(len(gate_candidate))
            indices = (prng.randint(n),) if g < 5 else prng.choice(n, 2, replace=False)
            cirq.act_on(
                gate_candidate[g], args1, qubits=[qubits[i] for i in indices], allow_decompose=False
            )
            ops.append(gate_candidate[g].on(*[qubits[i] for i in indices]))
        compiled_gate = cirq.CliffordGate.from_op_list(ops, qubits)
        cirq.act_on(compiled_gate, args2, qubits)

        assert args1.tableau == args2.tableau
Esempio n. 12
0
def test_act_on_state_vector():
    a, b = [cirq.LineQubit(3), cirq.LineQubit(1)]
    m = cirq.measure(a,
                     b,
                     key='out',
                     invert_mask=(True, ),
                     confusion_map={(1, ): np.array([[0, 1], [1, 0]])})

    args = cirq.StateVectorSimulationState(
        available_buffer=np.empty(shape=(2, 2, 2, 2, 2)),
        qubits=cirq.LineQubit.range(5),
        prng=np.random.RandomState(),
        initial_state=cirq.one_hot(shape=(2, 2, 2, 2, 2), dtype=np.complex64),
        dtype=np.complex64,
    )
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [1, 1]}

    args = cirq.StateVectorSimulationState(
        available_buffer=np.empty(shape=(2, 2, 2, 2, 2)),
        qubits=cirq.LineQubit.range(5),
        prng=np.random.RandomState(),
        initial_state=cirq.one_hot(index=(0, 1, 0, 0, 0),
                                   shape=(2, 2, 2, 2, 2),
                                   dtype=np.complex64),
        dtype=np.complex64,
    )
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [1, 0]}

    args = cirq.StateVectorSimulationState(
        available_buffer=np.empty(shape=(2, 2, 2, 2, 2)),
        qubits=cirq.LineQubit.range(5),
        prng=np.random.RandomState(),
        initial_state=cirq.one_hot(index=(0, 1, 0, 1, 0),
                                   shape=(2, 2, 2, 2, 2),
                                   dtype=np.complex64),
        dtype=np.complex64,
    )
    cirq.act_on(m, args)
    datastore = cast(cirq.ClassicalDataDictionaryStore, args.classical_data)
    out = cirq.MeasurementKey('out')
    assert args.log_of_measurement_results == {'out': [0, 0]}
    assert datastore.records[out] == [(0, 0)]
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [0, 0]}
    assert datastore.records[out] == [(0, 0), (0, 0)]
Esempio n. 13
0
def test_clifford_decompose_by_unitary():
    """Validate the decomposition of random Clifford Tableau by unitary matrix.

    Due to the exponential growth in dimension, it cannot validate very large number of qubits.
    """
    n, num_ops = 5, 20
    gate_candidate = [
        cirq.X, cirq.Y, cirq.Z, cirq.H, cirq.S, cirq.CNOT, cirq.CZ
    ]
    for seed in range(100):
        prng = np.random.RandomState(seed)
        t = cirq.CliffordTableau(num_qubits=n)
        qubits = cirq.LineQubit.range(n)
        expect_circ = cirq.Circuit()
        args = cirq.ActOnCliffordTableauArgs(tableau=t,
                                             qubits=qubits,
                                             prng=prng,
                                             log_of_measurement_results={})
        for _ in range(num_ops):
            g = prng.randint(len(gate_candidate))
            indices = (prng.randint(n), ) if g < 5 else prng.choice(
                n, 2, replace=False)
            cirq.act_on(gate_candidate[g],
                        args,
                        qubits=[qubits[i] for i in indices],
                        allow_decompose=False)
            expect_circ.append(
                gate_candidate[g].on(*[qubits[i] for i in indices]))
        ops = cirq.decompose_clifford_tableau_to_operations(
            qubits, args.tableau)
        circ = cirq.Circuit(ops)
        circ.append(cirq.I.on_each(qubits))
        expect_circ.append(cirq.I.on_each(qubits))
        assert_allclose_up_to_global_phase(cirq.unitary(expect_circ),
                                           cirq.unitary(circ),
                                           atol=1e-7)
Esempio n. 14
0
def test_act_on_clifford_tableau():
    a, b = [cirq.LineQubit(3), cirq.LineQubit(1)]
    m = cirq.measure(a,
                     b,
                     key='out',
                     invert_mask=(True, ),
                     confusion_map={(1, ): np.array([[0, 1], [1, 0]])})
    # The below assertion does not fail since it ignores non-unitary operations
    cirq.testing.assert_all_implemented_act_on_effects_match_unitary(m)

    args = cirq.CliffordTableauSimulationState(
        tableau=cirq.CliffordTableau(num_qubits=5, initial_state=0),
        qubits=cirq.LineQubit.range(5),
        prng=np.random.RandomState(),
    )
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [1, 1]}

    args = cirq.CliffordTableauSimulationState(
        tableau=cirq.CliffordTableau(num_qubits=5, initial_state=8),
        qubits=cirq.LineQubit.range(5),
        prng=np.random.RandomState(),
    )

    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [1, 0]}

    args = cirq.CliffordTableauSimulationState(
        tableau=cirq.CliffordTableau(num_qubits=5, initial_state=10),
        qubits=cirq.LineQubit.range(5),
        prng=np.random.RandomState(),
    )
    cirq.act_on(m, args)
    datastore = cast(cirq.ClassicalDataDictionaryStore, args.classical_data)
    out = cirq.MeasurementKey('out')
    assert args.log_of_measurement_results == {'out': [0, 0]}
    assert datastore.records[out] == [(0, 0)]
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [0, 0]}
    assert datastore.records[out] == [(0, 0), (0, 0)]
Esempio n. 15
0
def test_act_on_state_vector():
    a, b = [cirq.LineQubit(3), cirq.LineQubit(1)]
    m = cirq.measure(a, b, key='out', invert_mask=(True, ))

    args = cirq.ActOnStateVectorArgs(
        target_tensor=cirq.one_hot(shape=(2, 2, 2, 2, 2), dtype=np.complex64),
        available_buffer=np.empty(shape=(2, 2, 2, 2, 2)),
        qubits=cirq.LineQubit.range(5),
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [1, 0]}

    args = cirq.ActOnStateVectorArgs(
        target_tensor=cirq.one_hot(index=(0, 1, 0, 0, 0),
                                   shape=(2, 2, 2, 2, 2),
                                   dtype=np.complex64),
        available_buffer=np.empty(shape=(2, 2, 2, 2, 2)),
        qubits=cirq.LineQubit.range(5),
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [1, 1]}

    args = cirq.ActOnStateVectorArgs(
        target_tensor=cirq.one_hot(index=(0, 1, 0, 1, 0),
                                   shape=(2, 2, 2, 2, 2),
                                   dtype=np.complex64),
        available_buffer=np.empty(shape=(2, 2, 2, 2, 2)),
        qubits=cirq.LineQubit.range(5),
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [0, 1]}

    with pytest.raises(ValueError, match="already logged to key"):
        cirq.act_on(m, args)
Esempio n. 16
0
def test_act_on_stabilizer_ch_form():
    a, b = [cirq.LineQubit(3), cirq.LineQubit(1)]
    m = cirq.measure(a, b, key='out', invert_mask=(True, ))
    # The below assertion does not fail since it ignores non-unitary operations
    cirq.testing.assert_all_implemented_act_on_effects_match_unitary(m)

    args = cirq.ActOnStabilizerCHFormArgs(
        qubits=cirq.LineQubit.range(5),
        prng=np.random.RandomState(),
        log_of_measurement_results={},
        initial_state=0,
    )
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [1, 0]}

    args = cirq.ActOnStabilizerCHFormArgs(
        qubits=cirq.LineQubit.range(5),
        prng=np.random.RandomState(),
        log_of_measurement_results={},
        initial_state=8,
    )

    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [1, 1]}

    args = cirq.ActOnStabilizerCHFormArgs(
        qubits=cirq.LineQubit.range(5),
        prng=np.random.RandomState(),
        log_of_measurement_results={},
        initial_state=10,
    )
    cirq.act_on(m, args)
    datastore = cast(cirq.ClassicalDataDictionaryStore, args.classical_data)
    out = cirq.MeasurementKey('out')
    assert args.log_of_measurement_results == {'out': [0, 1]}
    assert datastore.records[out] == [(0, 1)]
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [0, 1]}
    assert datastore.records[out] == [(0, 1), (0, 1)]
Esempio n. 17
0
def test_act_on_stabilizer_ch_form():
    a, b = [cirq.LineQubit(3), cirq.LineQubit(1)]
    m = cirq.measure(a, b, key='out', invert_mask=(True, ))
    # The below assertion does not fail since it ignores non-unitary operations
    cirq.testing.assert_all_implemented_act_on_effects_match_unitary(m)

    args = cirq.ActOnStabilizerCHFormArgs(
        state=cirq.StabilizerStateChForm(num_qubits=5, initial_state=0),
        qubits=cirq.LineQubit.range(5),
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [1, 0]}

    args = cirq.ActOnStabilizerCHFormArgs(
        state=cirq.StabilizerStateChForm(num_qubits=5, initial_state=8),
        qubits=cirq.LineQubit.range(5),
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )

    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [1, 1]}

    args = cirq.ActOnStabilizerCHFormArgs(
        state=cirq.StabilizerStateChForm(num_qubits=5, initial_state=10),
        qubits=cirq.LineQubit.range(5),
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [0, 1]}

    with pytest.raises(ValueError, match="already logged to key"):
        cirq.act_on(m, args)
Esempio n. 18
0
def test_act_on_qutrit():
    a, b = [cirq.LineQid(3, dimension=3), cirq.LineQid(1, dimension=3)]
    m = cirq.measure(
        a,
        b,
        key='out',
        invert_mask=(True, ),
        confusion_map={(1, ): np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]])},
    )

    args = cirq.StateVectorSimulationState(
        available_buffer=np.empty(shape=(3, 3, 3, 3, 3)),
        qubits=cirq.LineQid.range(5, dimension=3),
        prng=np.random.RandomState(),
        initial_state=cirq.one_hot(index=(0, 2, 0, 2, 0),
                                   shape=(3, 3, 3, 3, 3),
                                   dtype=np.complex64),
        dtype=np.complex64,
    )
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [2, 0]}

    args = cirq.StateVectorSimulationState(
        available_buffer=np.empty(shape=(3, 3, 3, 3, 3)),
        qubits=cirq.LineQid.range(5, dimension=3),
        prng=np.random.RandomState(),
        initial_state=cirq.one_hot(index=(0, 1, 0, 2, 0),
                                   shape=(3, 3, 3, 3, 3),
                                   dtype=np.complex64),
        dtype=np.complex64,
    )
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [2, 2]}

    args = cirq.StateVectorSimulationState(
        available_buffer=np.empty(shape=(3, 3, 3, 3, 3)),
        qubits=cirq.LineQid.range(5, dimension=3),
        prng=np.random.RandomState(),
        initial_state=cirq.one_hot(index=(0, 2, 0, 1, 0),
                                   shape=(3, 3, 3, 3, 3),
                                   dtype=np.complex64),
        dtype=np.complex64,
    )
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [0, 0]}
Esempio n. 19
0
def test_unitary_fallback():
    class UnitaryXGate(cirq.Gate):
        def _num_qubits_(self) -> int:
            return 1

        def _unitary_(self):
            return np.array([[0, 1], [1, 0]])

    class UnitaryYGate(cirq.Gate):
        def _qid_shape_(self) -> Tuple[int, ...]:
            return (2, )

        def _unitary_(self):
            return np.array([[0, -1j], [1j, 0]])

    original_tableau = cirq.CliffordTableau(num_qubits=3)
    args = cirq.ActOnCliffordTableauArgs(
        tableau=original_tableau.copy(),
        qubits=cirq.LineQubit.range(3),
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )

    cirq.act_on(UnitaryXGate(), args, [cirq.LineQubit(1)])
    assert args.tableau == cirq.CliffordTableau(num_qubits=3, initial_state=2)

    args = cirq.ActOnCliffordTableauArgs(
        tableau=original_tableau.copy(),
        qubits=cirq.LineQubit.range(3),
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )
    cirq.act_on(UnitaryYGate(), args, [cirq.LineQubit(1)])
    expected_args = cirq.ActOnCliffordTableauArgs(
        tableau=original_tableau.copy(),
        qubits=cirq.LineQubit.range(3),
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )
    cirq.act_on(cirq.Y, expected_args, [cirq.LineQubit(1)])
    assert args.tableau == expected_args.tableau
Esempio n. 20
0
def test_unitary_fallback():

    class UnitaryXGate(cirq.Gate):

        def num_qubits(self) -> int:
            return 1

        def _unitary_(self):
            return np.array([[0, 1], [1, 0]])

    class UnitaryYGate(cirq.Gate):

        def num_qubits(self) -> int:
            return 1

        def _unitary_(self):
            return np.array([[0, -1j], [1j, 0]])

    original_tableau = cirq.CliffordTableau(num_qubits=3)
    args = cirq.ActOnCliffordTableauArgs(tableau=original_tableau.copy(),
                                         axes=[1],
                                         prng=np.random.RandomState(),
                                         log_of_measurement_results={})

    cirq.act_on(UnitaryXGate(), args)
    assert args.tableau == cirq.CliffordTableau(num_qubits=3, initial_state=2)

    args = cirq.ActOnCliffordTableauArgs(tableau=original_tableau.copy(),
                                         axes=[1],
                                         prng=np.random.RandomState(),
                                         log_of_measurement_results={})
    cirq.act_on(UnitaryYGate(), args)
    expected_args = cirq.ActOnCliffordTableauArgs(
        tableau=original_tableau.copy(),
        axes=[1],
        prng=np.random.RandomState(),
        log_of_measurement_results={})
    cirq.act_on(cirq.Y, expected_args)
    assert args.tableau == expected_args.tableau
Esempio n. 21
0
def test_act_on_qutrit():
    a, b = cirq.LineQid.range(2, dimension=3)
    m = cirq.measure(a, b, key='out', invert_mask=(True, ))

    args = cirq.ActOnStateVectorArgs(
        target_tensor=cirq.one_hot(index=(0, 2, 0, 2, 0),
                                   shape=(3, 3, 3, 3, 3),
                                   dtype=np.complex64),
        available_buffer=np.empty(shape=(3, 3, 3, 3, 3)),
        axes=[3, 1],
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [2, 2]}

    args = cirq.ActOnStateVectorArgs(
        target_tensor=cirq.one_hot(index=(0, 1, 0, 2, 0),
                                   shape=(3, 3, 3, 3, 3),
                                   dtype=np.complex64),
        available_buffer=np.empty(shape=(3, 3, 3, 3, 3)),
        axes=[3, 1],
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [2, 1]}

    args = cirq.ActOnStateVectorArgs(
        target_tensor=cirq.one_hot(index=(0, 2, 0, 1, 0),
                                   shape=(3, 3, 3, 3, 3),
                                   dtype=np.complex64),
        available_buffer=np.empty(shape=(3, 3, 3, 3, 3)),
        axes=[3, 1],
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )
    cirq.act_on(m, args)
    assert args.log_of_measurement_results == {'out': [0, 2]}
Esempio n. 22
0
def test_act_on_fallback_fails():
    args = DummyActOnArgs(fallback_result=NotImplemented)
    with pytest.raises(TypeError, match='Failed to act'):
        cirq.act_on(op, args)
Esempio n. 23
0
def test_act_on_tableau(phase):
    original_tableau = cirq.CliffordTableau(0)
    args = cirq.ActOnCliffordTableauArgs(original_tableau.copy(), [],
                                         np.random.RandomState(), {})
    cirq.act_on(cirq.GlobalPhaseOperation(phase), args, allow_decompose=False)
    assert args.tableau == original_tableau
Esempio n. 24
0
def test_cz_act_on_equivalent_to_h_cx_h_tableau():
    args1 = cirq.ActOnCliffordTableauArgs(
        tableau=cirq.CliffordTableau(num_qubits=2),
        qubits=cirq.LineQubit.range(2),
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )
    args2 = cirq.ActOnCliffordTableauArgs(
        tableau=cirq.CliffordTableau(num_qubits=2),
        qubits=cirq.LineQubit.range(2),
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )
    cirq.act_on(cirq.S, args=args1, qubits=[cirq.LineQubit(1)], allow_decompose=False)
    cirq.act_on(cirq.S, args=args2, qubits=[cirq.LineQubit(1)], allow_decompose=False)

    # Args1 uses H*CNOT*H
    cirq.act_on(cirq.H, args=args1, qubits=[cirq.LineQubit(1)], allow_decompose=False)
    cirq.act_on(cirq.CNOT, args=args1, qubits=cirq.LineQubit.range(2), allow_decompose=False)
    cirq.act_on(cirq.H, args=args1, qubits=[cirq.LineQubit(1)], allow_decompose=False)
    # Args2 uses CZ
    cirq.act_on(cirq.CZ, args=args2, qubits=cirq.LineQubit.range(2), allow_decompose=False)

    assert args1.tableau == args2.tableau
Esempio n. 25
0
def test_qubits_should_be_defined_for_operations():
    args = DummyActOnArgs()
    with pytest.raises(ValueError, match='Calls to act_on should'):
        cirq.act_on(cirq.KrausChannel([np.array([[1, 0], [0, 0]])]),
                    args,
                    qubits=None)
Esempio n. 26
0
def test_act_on_fallback_succeeds():
    args = DummyActOnArgs(fallback_result=True)
    cirq.act_on(op, args)
Esempio n. 27
0
def test_act_on_fallback_errors():
    args = DummyActOnArgs(fallback_result=False)
    with pytest.raises(
            ValueError,
            match='_act_on_fallback_ must return True or NotImplemented'):
        cirq.act_on(op, args)
Esempio n. 28
0
def direct_fidelity_estimation(
    circuit: cirq.Circuit,
    qubits: List[cirq.Qid],
    sampler: cirq.Sampler,
    n_measured_operators: Optional[int],
    samples_per_term: int,
):
    """
    Implementation of direct fidelity estimation, as per 'Direct Fidelity
    Estimation from Few Pauli Measurements' https://arxiv.org/abs/1104.4695 and
    'Practical characterization of quantum devices without tomography'
    https://arxiv.org/abs/1104.3835.

    Args:
        circuit: The circuit to run the simulation on.
        qubits: The list of qubits.
        sampler: Either a noisy simulator or an engine.
        n_measured_operators: The total number of Pauli measurements, or None to
            explore each Pauli state once.
        samples_per_term: if set to 0, we use the 'sampler' parameter above as
            a noise (must be of type cirq.DensityMatrixSimulator) and
            simulate noise in the circuit. If greater than 0, we instead use the
            'sampler' parameter directly to estimate the characteristic
            function.
    Returns:
        The estimated fidelity and a log of the run.
    """
    # n_measured_operators is upper-case N in https://arxiv.org/abs/1104.3835

    # Number of qubits, lower-case n in https://arxiv.org/abs/1104.3835
    n_qubits = len(qubits)

    clifford_circuit = True
    qubit_map = {qubits[i]: i for i in range(n_qubits)}
    clifford_tableau = cirq.CliffordTableau(n_qubits)
    try:
        for gate in circuit.all_operations():
            tableau_args = clifford.ActOnCliffordTableauArgs(
                clifford_tableau, [qubit_map[i] for i in gate.qubits],
                np.random.RandomState(), {})
            cirq.act_on(gate, tableau_args)
    except TypeError:
        clifford_circuit = False

    # Computes for every \hat{P_i} of https://arxiv.org/abs/1104.3835
    # estimate rho_i and Pr(i). We then collect tuples (rho_i, Pr(i), \hat{Pi})
    # inside the variable 'pauli_traces'.
    if clifford_circuit:
        # The stabilizers_basis variable only contains basis vectors. For
        # example, if we have n=3 qubits, then we should have 2**n=8 Pauli
        # states that we can sample, but the basis will still have 3 entries. We
        # must flip a coin for each, whether or not to include them.
        stabilizer_basis: List[
            cirq.DensePauliString] = clifford_tableau.stabilizers()

        pauli_traces = _estimate_pauli_traces_clifford(n_qubits,
                                                       stabilizer_basis,
                                                       n_measured_operators)
    else:
        pauli_traces = _estimate_pauli_traces_general(qubits, circuit,
                                                      n_measured_operators)

    p = np.asarray([x.Pr_i for x in pauli_traces])

    if n_measured_operators is None:
        # Since we enumerate all the possible traces, the probs should add to 1.
        assert np.isclose(np.sum(p), 1.0, atol=1e-6)
    p /= np.sum(p)

    fidelity = 0.0

    if samples_per_term == 0:
        # sigma in https://arxiv.org/abs/1104.3835
        if not isinstance(sampler, cirq.DensityMatrixSimulator):
            raise TypeError(
                'sampler is not a cirq.DensityMatrixSimulator but samples_per_term is zero.'
            )
        noisy_simulator = cast(cirq.DensityMatrixSimulator, sampler)
        noisy_density_matrix = cast(
            cirq.DensityMatrixTrialResult,
            noisy_simulator.simulate(circuit)).final_density_matrix

    if clifford_circuit and n_measured_operators is None:
        # In case the circuit is Clifford and we compute an exhaustive list of
        # Pauli traces, instead of sampling we can simply enumerate them because
        # they all have the same probability.
        measured_pauli_traces = pauli_traces
    else:
        # Otherwise, randomly sample as per probability.
        measured_pauli_traces = np.random.choice(pauli_traces,
                                                 size=len(pauli_traces),
                                                 p=p)

    trial_results: List[Result] = []
    for pauli_trace in measured_pauli_traces:
        measure_pauli_string: cirq.PauliString = pauli_trace.P_i
        rho_i = pauli_trace.rho_i

        if samples_per_term > 0:
            sigma_i = asyncio.get_event_loop().run_until_complete(
                estimate_characteristic_function(circuit, measure_pauli_string,
                                                 qubits, sampler,
                                                 samples_per_term))
        else:
            sigma_i, _ = compute_characteristic_function(
                circuit, measure_pauli_string, qubits, noisy_density_matrix)

        trial_results.append(Result(pauli_trace=pauli_trace, sigma_i=sigma_i))

        fidelity += sigma_i / rho_i

    estimated_fidelity = fidelity / len(pauli_traces)

    std_dev_estimate: Optional[float]
    std_dev_bound: Optional[float]
    if clifford_circuit:
        std_dev_estimate, std_dev_bound = _estimate_std_devs_clifford(
            estimated_fidelity, len(measured_pauli_traces))
    else:
        std_dev_estimate, std_dev_bound = None, None

    dfe_intermediate_result = DFEIntermediateResult(
        clifford_tableau=clifford_tableau if clifford_circuit else None,
        pauli_traces=pauli_traces,
        trial_results=trial_results,
        std_dev_estimate=std_dev_estimate,
        std_dev_bound=std_dev_bound,
    )

    return estimated_fidelity, dfe_intermediate_result
Esempio n. 29
0
def test_z_h_act_on_tableau():
    with pytest.raises(TypeError, match="Failed to act"):
        cirq.act_on(cirq.Z, object())
    with pytest.raises(TypeError, match="Failed to act"):
        cirq.act_on(cirq.H, object())
    original_tableau = cirq.CliffordTableau(num_qubits=5, initial_state=31)
    flipped_tableau = cirq.CliffordTableau(num_qubits=5, initial_state=23)

    args = cirq.ActOnCliffordTableauArgs(
        tableau=original_tableau.copy(),
        axes=[1],
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )

    cirq.act_on(cirq.H, args, allow_decompose=False)
    cirq.act_on(cirq.Z**0.5, args, allow_decompose=False)
    cirq.act_on(cirq.Z**0.5, args, allow_decompose=False)
    cirq.act_on(cirq.H, args, allow_decompose=False)
    assert args.log_of_measurement_results == {}
    assert args.tableau == flipped_tableau

    cirq.act_on(cirq.H, args, allow_decompose=False)
    cirq.act_on(cirq.Z, args, allow_decompose=False)
    cirq.act_on(cirq.H, args, allow_decompose=False)
    assert args.log_of_measurement_results == {}
    assert args.tableau == original_tableau

    cirq.act_on(cirq.H, args, allow_decompose=False)
    cirq.act_on(cirq.Z**3.5, args, allow_decompose=False)
    cirq.act_on(cirq.Z**3.5, args, allow_decompose=False)
    cirq.act_on(cirq.H, args, allow_decompose=False)
    assert args.log_of_measurement_results == {}
    assert args.tableau == flipped_tableau

    cirq.act_on(cirq.Z**2, args, allow_decompose=False)
    assert args.log_of_measurement_results == {}
    assert args.tableau == flipped_tableau

    cirq.act_on(cirq.H**2, args, allow_decompose=False)
    assert args.log_of_measurement_results == {}
    assert args.tableau == flipped_tableau

    foo = sympy.Symbol('foo')
    with pytest.raises(TypeError, match="Failed to act action on state"):
        cirq.act_on(cirq.Z**foo, args)

    with pytest.raises(TypeError, match="Failed to act action on state"):
        cirq.act_on(cirq.H**foo, args)

    with pytest.raises(TypeError, match="Failed to act action on state"):
        cirq.act_on(cirq.H**1.5, args)
Esempio n. 30
0
def test_cz_act_on_tableau():
    with pytest.raises(TypeError, match="Failed to act"):
        cirq.act_on(cirq.Y, object())
    original_tableau = cirq.CliffordTableau(num_qubits=5, initial_state=31)

    args = cirq.ActOnCliffordTableauArgs(
        tableau=original_tableau.copy(),
        axes=[0, 1],
        prng=np.random.RandomState(),
        log_of_measurement_results={},
    )

    cirq.act_on(cirq.CZ, args, allow_decompose=False)
    assert args.log_of_measurement_results == {}
    assert args.tableau.stabilizers() == [
        cirq.DensePauliString('ZIIII', coefficient=-1),
        cirq.DensePauliString('IZIII', coefficient=-1),
        cirq.DensePauliString('IIZII', coefficient=-1),
        cirq.DensePauliString('IIIZI', coefficient=-1),
        cirq.DensePauliString('IIIIZ', coefficient=-1),
    ]
    assert args.tableau.destabilizers() == [
        cirq.DensePauliString('XZIII', coefficient=1),
        cirq.DensePauliString('ZXIII', coefficient=1),
        cirq.DensePauliString('IIXII', coefficient=1),
        cirq.DensePauliString('IIIXI', coefficient=1),
        cirq.DensePauliString('IIIIX', coefficient=1),
    ]

    cirq.act_on(cirq.CZ, args, allow_decompose=False)
    assert args.log_of_measurement_results == {}
    assert args.tableau == original_tableau

    cirq.act_on(cirq.CZ**4, args, allow_decompose=False)
    assert args.log_of_measurement_results == {}
    assert args.tableau == original_tableau

    foo = sympy.Symbol('foo')
    with pytest.raises(TypeError, match="Failed to act action on state"):
        cirq.act_on(cirq.CZ**foo, args)

    with pytest.raises(TypeError, match="Failed to act action on state"):
        cirq.act_on(cirq.CZ**1.5, args)