Ejemplo n.º 1
0
def test_channel():
    a = cirq.NamedQubit('a')
    op = cirq.bit_flip(0.5).on(a)
    np.testing.assert_allclose(cirq.kraus(op), cirq.kraus(op.gate))
    assert cirq.has_kraus(op)

    assert cirq.kraus(cirq.SingleQubitGate()(a), None) is None
    assert not cirq.has_kraus(cirq.SingleQubitGate()(a))
Ejemplo n.º 2
0
def test_parameterized(resolve_fn):
    op = cirq.X.with_probability(sympy.Symbol('x'))
    assert cirq.is_parameterized(op)
    assert not cirq.has_kraus(op)
    assert not cirq.has_mixture(op)

    op2 = resolve_fn(op, {'x': 0.5})
    assert op2 == cirq.X.with_probability(0.5)
    assert not cirq.is_parameterized(op2)
    assert cirq.has_kraus(op2)
    assert cirq.has_mixture(op2)
def test_state_prep_channel_kraus_small():
    gate = cirq.StatePreparationChannel(np.array([0.0,
                                                  1.0]))(cirq.LineQubit(0))
    np.testing.assert_almost_equal(cirq.kraus(gate), (np.array(
        [[0.0, 0.0], [1.0, 0.0]]), np.array([[0.0, 0.0], [0.0, 1.0]])))
    assert cirq.has_kraus(gate)
    assert not cirq.has_mixture(gate)

    gate = cirq.StatePreparationChannel(np.array([1.0,
                                                  0.0]))(cirq.LineQubit(0))
    np.testing.assert_almost_equal(cirq.kraus(gate), (np.array(
        [[1.0, 0.0], [0.0, 0.0]]), np.array([[0.0, 1.0], [0.0, 0.0]])))
    assert cirq.has_kraus(gate)
    assert not cirq.has_mixture(gate)
Ejemplo n.º 4
0
def test_kraus():
    I = np.eye(2)
    X = np.array([[0, 1], [1, 0]])
    Y = np.array([[0, -1j], [1j, 0]])
    Z = np.diag([1, -1])

    a, b = cirq.LineQubit.range(2)

    m = cirq.Moment()
    assert cirq.has_kraus(m)
    k = cirq.kraus(m)
    assert len(k) == 1
    assert np.allclose(k[0], np.array([[1.0]]))

    m = cirq.Moment(cirq.S(a))
    assert cirq.has_kraus(m)
    k = cirq.kraus(m)
    assert len(k) == 1
    assert np.allclose(k[0], np.diag([1, 1j]))

    m = cirq.Moment(cirq.CNOT(a, b))
    assert cirq.has_kraus(m)
    k = cirq.kraus(m)
    print(k[0])
    assert len(k) == 1
    assert np.allclose(
        k[0], np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1,
                                                                   0]]))

    p = 0.1
    m = cirq.Moment(cirq.depolarize(p).on(a))
    assert cirq.has_kraus(m)
    k = cirq.kraus(m)
    assert len(k) == 4
    assert np.allclose(k[0], np.sqrt(1 - p) * I)
    assert np.allclose(k[1], np.sqrt(p / 3) * X)
    assert np.allclose(k[2], np.sqrt(p / 3) * Y)
    assert np.allclose(k[3], np.sqrt(p / 3) * Z)

    p = 0.2
    q = 0.3
    m = cirq.Moment(cirq.bit_flip(p).on(a), cirq.phase_flip(q).on(b))
    assert cirq.has_kraus(m)
    k = cirq.kraus(m)
    assert len(k) == 4
    assert np.allclose(k[0], np.sqrt((1 - p) * (1 - q)) * np.kron(I, I))
    assert np.allclose(k[1], np.sqrt(q * (1 - p)) * np.kron(I, Z))
    assert np.allclose(k[2], np.sqrt(p * (1 - q)) * np.kron(X, I))
    assert np.allclose(k[3], np.sqrt(p * q) * np.kron(X, Z))
Ejemplo n.º 5
0
def test_depolarizing_channel_two_qubits():
    d = cirq.depolarize(0.15, n_qubits=2)
    np.testing.assert_almost_equal(
        cirq.kraus(d),
        (
            np.sqrt(0.85) * np.eye(4),
            np.sqrt(0.01) * np.kron(np.eye(2), X),
            np.sqrt(0.01) * np.kron(np.eye(2), Y),
            np.sqrt(0.01) * np.kron(np.eye(2), Z),
            np.sqrt(0.01) * np.kron(X, np.eye(2)),
            np.sqrt(0.01) * np.kron(X, X),
            np.sqrt(0.01) * np.kron(X, Y),
            np.sqrt(0.01) * np.kron(X, Z),
            np.sqrt(0.01) * np.kron(Y, np.eye(2)),
            np.sqrt(0.01) * np.kron(Y, X),
            np.sqrt(0.01) * np.kron(Y, Y),
            np.sqrt(0.01) * np.kron(Y, Z),
            np.sqrt(0.01) * np.kron(Z, np.eye(2)),
            np.sqrt(0.01) * np.kron(Z, X),
            np.sqrt(0.01) * np.kron(Z, Y),
            np.sqrt(0.01) * np.kron(Z, Z),
        ),
    )
    assert cirq.has_kraus(d)

    assert d.num_qubits() == 2
    cirq.testing.assert_has_diagram(
        cirq.Circuit(d(*cirq.LineQubit.range(2))),
        """
0: ───D(0.15)───
      │
1: ───#2────────
        """,
    )
Ejemplo n.º 6
0
def test_kraus_too_big():
    m = cirq.Moment(cirq.IdentityGate(11).on(*cirq.LineQubit.range(11)))
    assert not cirq.has_kraus(m)
    assert not m._has_superoperator_()
    assert m._kraus_() is NotImplemented
    assert m._superoperator_() is NotImplemented
    assert cirq.kraus(m, default=None) is None
Ejemplo n.º 7
0
def test_asymmetric_depolarizing_channel():
    d = cirq.asymmetric_depolarize(0.1, 0.2, 0.3)
    np.testing.assert_almost_equal(
        cirq.kraus(d),
        (np.sqrt(0.4) * np.eye(2), np.sqrt(0.1) * X, np.sqrt(0.2) * Y, np.sqrt(0.3) * Z),
    )
    assert cirq.has_kraus(d)
Ejemplo n.º 8
0
def test_channel():
    class NoDetailsGate(cirq.Gate):
        def num_qubits(self) -> int:
            return 1

    assert not cirq.has_kraus(NoDetailsGate().with_probability(0.5))
    assert cirq.kraus(NoDetailsGate().with_probability(0.5), None) is None
    assert cirq.kraus(cirq.X.with_probability(sympy.Symbol('x')), None) is None
    assert_channel_sums_to_identity(cirq.X.with_probability(0.25))
    assert_channel_sums_to_identity(cirq.bit_flip(0.75).with_probability(0.25))
    assert_channel_sums_to_identity(cirq.amplitude_damp(0.75).with_probability(0.25))

    m = cirq.kraus(cirq.X.with_probability(0.25))
    assert len(m) == 2
    np.testing.assert_allclose(
        m[0],
        cirq.unitary(cirq.X) * np.sqrt(0.25),
        atol=1e-8,
    )
    np.testing.assert_allclose(
        m[1],
        cirq.unitary(cirq.I) * np.sqrt(0.75),
        atol=1e-8,
    )

    m = cirq.kraus(cirq.bit_flip(0.75).with_probability(0.25))
    assert len(m) == 3
    np.testing.assert_allclose(
        m[0],
        cirq.unitary(cirq.I) * np.sqrt(0.25) * np.sqrt(0.25),
        atol=1e-8,
    )
    np.testing.assert_allclose(
        m[1],
        cirq.unitary(cirq.X) * np.sqrt(0.25) * np.sqrt(0.75),
        atol=1e-8,
    )
    np.testing.assert_allclose(
        m[2],
        cirq.unitary(cirq.I) * np.sqrt(0.75),
        atol=1e-8,
    )

    m = cirq.kraus(cirq.amplitude_damp(0.75).with_probability(0.25))
    assert len(m) == 3
    np.testing.assert_allclose(
        m[0],
        np.array([[1, 0], [0, np.sqrt(1 - 0.75)]]) * np.sqrt(0.25),
        atol=1e-8,
    )
    np.testing.assert_allclose(
        m[1],
        np.array([[0, np.sqrt(0.75)], [0, 0]]) * np.sqrt(0.25),
        atol=1e-8,
    )
    np.testing.assert_allclose(
        m[2],
        cirq.unitary(cirq.I) * np.sqrt(0.75),
        atol=1e-8,
    )
Ejemplo n.º 9
0
def assert_not_implemented(val):
    with pytest.raises(TypeError, match='returned NotImplemented'):
        _ = cirq.kraus(val)

    assert cirq.kraus(val, None) is None
    assert cirq.kraus(val, NotImplemented) is NotImplemented
    assert cirq.kraus(val, (1, )) == (1, )
    assert cirq.kraus(val, LOCAL_DEFAULT) is LOCAL_DEFAULT

    assert not cirq.has_kraus(val)
Ejemplo n.º 10
0
def test_op_has_no_kraus():
    class EmptyGate(cirq.testing.SingleQubitGate):
        pass

    m = cirq.Moment(EmptyGate().on(cirq.NamedQubit("a")))
    assert not cirq.has_kraus(m)
    assert not m._has_superoperator_()
    assert m._kraus_() is NotImplemented
    assert m._superoperator_() is NotImplemented
    assert cirq.kraus(m, default=None) is None
Ejemplo n.º 11
0
def assert_consistent_channel(gate: Any,
                              rtol: float = 1e-5,
                              atol: float = 1e-8):
    """Asserts that a given gate has Kraus operators and that they are properly normalized."""
    assert cirq.has_kraus(
        gate), f"Given gate {gate!r} does not return True for cirq.has_kraus."
    kraus_ops = cirq.kraus(gate)
    assert cirq.is_cptp(kraus_ops=kraus_ops, rtol=rtol, atol=atol), (
        f"Kraus operators for {gate!r} did not sum to identity up to expected tolerances. "
        f"Summed to {sum(m.T.conj() @ m for m in kraus_ops)}")
Ejemplo n.º 12
0
def test_asymmetric_depolarizing_channel():
    d = cirq.asymmetric_depolarize(0.1, 0.2, 0.3)
    np.testing.assert_almost_equal(
        cirq.kraus(d),
        (np.sqrt(0.4) * np.eye(2), np.sqrt(0.1) * X, np.sqrt(0.2) * Y,
         np.sqrt(0.3) * Z),
    )
    assert cirq.has_kraus(d)

    assert cirq.AsymmetricDepolarizingChannel(p_x=0, p_y=0.1,
                                              p_z=0).num_qubits() == 1
Ejemplo n.º 13
0
def test_op_has_no_kraus():
    class EmptyGate(cirq.Gate):
        def _num_qubits_(self) -> int:
            return 1

    m = cirq.Moment(EmptyGate().on(cirq.NamedQubit("a")))
    assert not cirq.has_kraus(m)
    assert not m._has_superoperator_()
    assert m._kraus_() is NotImplemented
    assert m._superoperator_() is NotImplemented
    assert cirq.kraus(m, default=None) is None
Ejemplo n.º 14
0
def test_phase_damping_channel():
    d = cirq.phase_damp(0.3)
    np.testing.assert_almost_equal(
        cirq.kraus(d),
        (
            np.array([[1.0, 0.0], [0.0, np.sqrt(1 - 0.3)]]),
            np.array([[0.0, 0.0], [0.0, np.sqrt(0.3)]]),
        ),
    )
    assert cirq.has_kraus(d)
    assert not cirq.has_mixture(d)
Ejemplo n.º 15
0
def test_depolarizing_channel():
    d = cirq.depolarize(0.3)
    np.testing.assert_almost_equal(
        cirq.kraus(d),
        (
            np.sqrt(0.7) * np.eye(2),
            np.sqrt(0.1) * X,
            np.sqrt(0.1) * Y,
            np.sqrt(0.1) * Z,
        ),
    )
    assert cirq.has_kraus(d)
Ejemplo n.º 16
0
def test_reset_channel():
    r = cirq.reset(cirq.LineQubit(0))
    np.testing.assert_almost_equal(
        cirq.kraus(r),
        (np.array([[1.0, 0.0], [0.0, 0]]), np.array([[0.0, 1.0], [0.0, 0.0]])))
    assert cirq.has_kraus(r)
    assert not cirq.has_mixture(r)
    assert cirq.qid_shape(r) == (2, )

    r = cirq.reset(cirq.LineQid(0, dimension=3))
    np.testing.assert_almost_equal(
        cirq.kraus(r),
        (
            np.array([[1, 0, 0], [0, 0, 0], [0, 0, 0]]),
            np.array([[0, 1, 0], [0, 0, 0], [0, 0, 0]]),
            np.array([[0, 0, 1], [0, 0, 0], [0, 0, 0]]),
        ),
    )  # yapf: disable
    assert cirq.has_kraus(r)
    assert not cirq.has_mixture(r)
    assert cirq.qid_shape(r) == (3, )
Ejemplo n.º 17
0
def test_generalized_amplitude_damping_channel():
    d = cirq.generalized_amplitude_damp(0.1, 0.3)
    np.testing.assert_almost_equal(
        cirq.kraus(d),
        (
            np.sqrt(0.1) * np.array([[1.0, 0.0], [0.0, np.sqrt(1.0 - 0.3)]]),
            np.sqrt(0.1) * np.array([[0.0, np.sqrt(0.3)], [0.0, 0.0]]),
            np.sqrt(0.9) * np.array([[np.sqrt(1.0 - 0.3), 0.0], [0.0, 1.0]]),
            np.sqrt(0.9) * np.array([[0.0, 0.0], [np.sqrt(0.3), 0.0]]),
        ),
    )
    assert cirq.has_kraus(d)
    assert not cirq.has_mixture(d)
Ejemplo n.º 18
0
def test_channel_no_methods():
    class NoMethod:
        pass

    with pytest.raises(TypeError, match='no _kraus_ or _mixture_ or _unitary_ method'):
        _ = cirq.kraus(NoMethod())

    assert cirq.kraus(NoMethod(), None) is None
    assert cirq.kraus(NoMethod, NotImplemented) is NotImplemented
    assert cirq.kraus(NoMethod(), (1,)) == (1,)
    assert cirq.kraus(NoMethod(), LOCAL_DEFAULT) is LOCAL_DEFAULT

    assert not cirq.has_kraus(NoMethod())
Ejemplo n.º 19
0
def test_channel_fallback_to_unitary():
    u = np.array([[1, 0], [1, 0]])

    class ReturnsUnitary:
        def _unitary_(self) -> np.ndarray:
            return u

    np.testing.assert_equal(cirq.kraus(ReturnsUnitary()), (u,))
    np.testing.assert_equal(cirq.kraus(ReturnsUnitary(), None), (u,))
    np.testing.assert_equal(cirq.kraus(ReturnsUnitary(), NotImplemented), (u,))
    np.testing.assert_equal(cirq.kraus(ReturnsUnitary(), (1,)), (u,))
    np.testing.assert_equal(cirq.kraus(ReturnsUnitary(), LOCAL_DEFAULT), (u,))

    assert cirq.has_kraus(ReturnsUnitary())
Ejemplo n.º 20
0
def test_channel_generates_deprecation_warning():
    class UsesDeprecatedChannelMethod:
        def _has_channel_(self):
            return True

        def _channel_(self):
            return (np.eye(2),)

    val = UsesDeprecatedChannelMethod()
    with pytest.warns(DeprecationWarning, match='_has_kraus_'):
        assert cirq.has_kraus(val)
    with pytest.warns(DeprecationWarning, match='_kraus_'):
        ks = cirq.kraus(val)
        assert len(ks) == 1
        assert np.all(ks[0] == np.eye(2))
Ejemplo n.º 21
0
def test_explicit_kraus():
    a0 = np.array([[0, 0], [1, 0]])
    a1 = np.array([[1, 0], [0, 0]])
    c = (a0, a1)

    class ReturnsKraus:
        def _kraus_(self) -> Sequence[np.ndarray]:
            return c

    assert cirq.kraus(ReturnsKraus()) is c
    assert cirq.kraus(ReturnsKraus(), None) is c
    assert cirq.kraus(ReturnsKraus(), NotImplemented) is c
    assert cirq.kraus(ReturnsKraus(), (1, )) is c
    assert cirq.kraus(ReturnsKraus(), LOCAL_DEFAULT) is c

    assert cirq.has_kraus(ReturnsKraus())
Ejemplo n.º 22
0
def test_multi_asymmetric_depolarizing_channel():
    d = cirq.asymmetric_depolarize(error_probabilities={'II': 0.8, 'XX': 0.2})
    np.testing.assert_almost_equal(
        cirq.kraus(d),
        (np.sqrt(0.8) * np.eye(4), np.sqrt(0.2) * np.kron(X, X)))
    assert cirq.has_kraus(d)
    np.testing.assert_equal(d._num_qubits_(), 2)

    with pytest.raises(ValueError, match="num_qubits should be 1"):
        assert d.p_i == 1.0
    with pytest.raises(ValueError, match="num_qubits should be 1"):
        assert d.p_x == 0.0
    with pytest.raises(ValueError, match="num_qubits should be 1"):
        assert d.p_y == 0.0
    with pytest.raises(ValueError, match="num_qubits should be 1"):
        assert d.p_z == 0.0
Ejemplo n.º 23
0
def test_channel_fallback_to_mixture():
    m = ((0.3, cirq.unitary(cirq.X)), (0.4, cirq.unitary(cirq.Y)), (0.3, cirq.unitary(cirq.Z)))

    class ReturnsMixture:
        def _mixture_(self) -> Iterable[Tuple[float, np.ndarray]]:
            return m

    c = (
        np.sqrt(0.3) * cirq.unitary(cirq.X),
        np.sqrt(0.4) * cirq.unitary(cirq.Y),
        np.sqrt(0.3) * cirq.unitary(cirq.Z),
    )

    np.allclose(cirq.kraus(ReturnsMixture()), c)
    np.allclose(cirq.kraus(ReturnsMixture(), None), c)
    np.allclose(cirq.kraus(ReturnsMixture(), NotImplemented), c)
    np.allclose(cirq.kraus(ReturnsMixture(), (1,)), c)
    np.allclose(cirq.kraus(ReturnsMixture(), LOCAL_DEFAULT), c)

    assert cirq.has_kraus(ReturnsMixture())
Ejemplo n.º 24
0
def test_tagged_operation_forwards_protocols():
    """The results of all protocols applied to an operation with a tag should
    be equivalent to the result without tags.
    """
    q1 = cirq.GridQubit(1, 1)
    q2 = cirq.GridQubit(1, 2)
    h = cirq.H(q1)
    tag = 'tag1'
    tagged_h = cirq.H(q1).with_tags(tag)

    np.testing.assert_equal(cirq.unitary(tagged_h), cirq.unitary(h))
    assert cirq.has_unitary(tagged_h)
    assert cirq.decompose(tagged_h) == cirq.decompose(h)
    assert cirq.pauli_expansion(tagged_h) == cirq.pauli_expansion(h)
    assert cirq.equal_up_to_global_phase(h, tagged_h)
    assert np.isclose(cirq.kraus(h), cirq.kraus(tagged_h)).all()

    assert cirq.measurement_key_name(
        cirq.measure(q1, key='blah').with_tags(tag)) == 'blah'
    assert cirq.measurement_key_obj(
        cirq.measure(q1,
                     key='blah').with_tags(tag)) == cirq.MeasurementKey('blah')

    parameterized_op = cirq.XPowGate(
        exponent=sympy.Symbol('t'))(q1).with_tags(tag)
    assert cirq.is_parameterized(parameterized_op)
    resolver = cirq.study.ParamResolver({'t': 0.25})
    assert cirq.resolve_parameters(
        parameterized_op,
        resolver) == cirq.XPowGate(exponent=0.25)(q1).with_tags(tag)
    assert cirq.resolve_parameters_once(
        parameterized_op,
        resolver) == cirq.XPowGate(exponent=0.25)(q1).with_tags(tag)
    assert parameterized_op._unitary_() is NotImplemented
    assert parameterized_op._mixture_() is NotImplemented
    assert parameterized_op._kraus_() is NotImplemented

    y = cirq.Y(q1)
    tagged_y = cirq.Y(q1).with_tags(tag)
    assert tagged_y**0.5 == cirq.YPowGate(exponent=0.5)(q1)
    assert tagged_y * 2 == (y * 2)
    assert 3 * tagged_y == (3 * y)
    assert cirq.phase_by(y, 0.125, 0) == cirq.phase_by(tagged_y, 0.125, 0)
    controlled_y = tagged_y.controlled_by(q2)
    assert controlled_y.qubits == (
        q2,
        q1,
    )
    assert isinstance(controlled_y, cirq.Operation)
    assert not isinstance(controlled_y, cirq.TaggedOperation)

    clifford_x = cirq.SingleQubitCliffordGate.X(q1)
    tagged_x = cirq.SingleQubitCliffordGate.X(q1).with_tags(tag)
    assert cirq.commutes(clifford_x, clifford_x)
    assert cirq.commutes(tagged_x, clifford_x)
    assert cirq.commutes(clifford_x, tagged_x)
    assert cirq.commutes(tagged_x, tagged_x)

    assert cirq.trace_distance_bound(y**0.001) == cirq.trace_distance_bound(
        (y**0.001).with_tags(tag))

    flip = cirq.bit_flip(0.5)(q1)
    tagged_flip = cirq.bit_flip(0.5)(q1).with_tags(tag)
    assert cirq.has_mixture(tagged_flip)
    assert cirq.has_kraus(tagged_flip)

    flip_mixture = cirq.mixture(flip)
    tagged_mixture = cirq.mixture(tagged_flip)
    assert len(tagged_mixture) == 2
    assert len(tagged_mixture[0]) == 2
    assert len(tagged_mixture[1]) == 2
    assert tagged_mixture[0][0] == flip_mixture[0][0]
    assert np.isclose(tagged_mixture[0][1], flip_mixture[0][1]).all()
    assert tagged_mixture[1][0] == flip_mixture[1][0]
    assert np.isclose(tagged_mixture[1][1], flip_mixture[1][1]).all()

    qubit_map = {q1: 'q1'}
    qasm_args = cirq.QasmArgs(qubit_id_map=qubit_map)
    assert cirq.qasm(h, args=qasm_args) == cirq.qasm(tagged_h, args=qasm_args)

    cirq.testing.assert_has_consistent_apply_unitary(tagged_h)
Ejemplo n.º 25
0
def circuit_to_density_matrix_tensors(
    circuit: cirq.Circuit,
    qubits: Optional[Sequence[cirq.Qid]] = None
) -> Tuple[List[qtn.Tensor], Dict['cirq.Qid', int], Dict[Tuple[str, str],
                                                         Tuple[float, float]]]:
    """Given a circuit with mixtures or channels, construct a tensor network
    representation of the density matrix.

    This assumes you start in the |0..0><0..0| state. Indices are named
    "nf{i}_q{x}" and "nb{i}_q{x}" where i is a time index and x is a
    qubit index. nf- and nb- refer to the "forwards" and "backwards"
    copies of the circuit. Kraus indices are named "k{j}" where j is an
    independent "kraus" internal index which you probably never need to access.

    Args:
        circuit: The circuit containing operations that support the
            cirq.unitary() or cirq.kraus() protocols.
        qubits: The qubits in the circuit. The `positions` return argument
            will position qubits according to their index in this list.

    Returns:
        tensors: A list of Quimb Tensor objects
        qubit_frontier: A mapping from qubit to time index at the end of
            the circuit. This can be used to deduce the names of the free
            tensor indices.
        positions: A positions dictionary suitable for passing to tn.graph()'s
            `fix` argument to draw the resulting tensor network similar to a
            quantum circuit.

    Raises:
        ValueError: If an op is encountered that cannot be converted.
    """
    if qubits is None:
        # coverage: ignore
        qubits = sorted(circuit.all_qubits())
    qubits = tuple(qubits)

    qubit_frontier: Dict[cirq.Qid, int] = {q: 0 for q in qubits}
    kraus_frontier = 0
    positions: Dict[Tuple[str, str], Tuple[float, float]] = {}
    tensors: List[qtn.Tensor] = []

    x_scale = 2
    y_scale = 3
    x_nudge = 0.3
    n_qubits = len(qubits)
    yb_offset = (n_qubits + 0.5) * y_scale

    def _positions(_mi, _these_qubits):
        return _add_to_positions(
            positions,
            _mi,
            _these_qubits,
            all_qubits=qubits,
            x_scale=x_scale,
            y_scale=y_scale,
            x_nudge=x_nudge,
            yb_offset=yb_offset,
        )

    # Initialize forwards and backwards qubits into the 0 state, i.e. prepare
    # rho_0 = |0><0|.
    for q in qubits:
        tensors += [
            qtn.Tensor(data=quimb.up().squeeze(),
                       inds=(f'nf0_q{q}', ),
                       tags={'Q0', 'i0f', _qpos_tag(q)}),
            qtn.Tensor(data=quimb.up().squeeze(),
                       inds=(f'nb0_q{q}', ),
                       tags={'Q0', 'i0b', _qpos_tag(q)}),
        ]
        _positions(0, q)

    for mi, moment in enumerate(circuit.moments):
        for op in moment.operations:
            start_inds_f = [f'nf{qubit_frontier[q]}_q{q}' for q in op.qubits]
            start_inds_b = [f'nb{qubit_frontier[q]}_q{q}' for q in op.qubits]
            for q in op.qubits:
                qubit_frontier[q] += 1
            end_inds_f = [f'nf{qubit_frontier[q]}_q{q}' for q in op.qubits]
            end_inds_b = [f'nb{qubit_frontier[q]}_q{q}' for q in op.qubits]

            if cirq.has_unitary(op):
                U = cirq.unitary(op).reshape(
                    (2, ) * 2 * len(op.qubits)).astype(np.complex128)
                tensors.append(
                    qtn.Tensor(
                        data=U,
                        inds=end_inds_f + start_inds_f,
                        tags={
                            f'Q{len(op.qubits)}', f'i{mi + 1}f',
                            _qpos_tag(op.qubits)
                        },
                    ))
                tensors.append(
                    qtn.Tensor(
                        data=np.conj(U),
                        inds=end_inds_b + start_inds_b,
                        tags={
                            f'Q{len(op.qubits)}', f'i{mi + 1}b',
                            _qpos_tag(op.qubits)
                        },
                    ))
            elif cirq.has_kraus(op):
                K = np.asarray(cirq.kraus(op), dtype=np.complex128)
                kraus_inds = [f'k{kraus_frontier}']
                tensors.append(
                    qtn.Tensor(
                        data=K,
                        inds=kraus_inds + end_inds_f + start_inds_f,
                        tags={
                            f'kQ{len(op.qubits)}', f'i{mi + 1}f',
                            _qpos_tag(op.qubits)
                        },
                    ))
                tensors.append(
                    qtn.Tensor(
                        data=np.conj(K),
                        inds=kraus_inds + end_inds_b + start_inds_b,
                        tags={
                            f'kQ{len(op.qubits)}', f'i{mi + 1}b',
                            _qpos_tag(op.qubits)
                        },
                    ))
                kraus_frontier += 1
            else:
                raise ValueError(repr(op))  # coverage: ignore

            _positions(mi + 1, op.qubits)
    return tensors, qubit_frontier, positions
Ejemplo n.º 26
0
def test_has_kraus_when_decomposed(decomposed_cls):
    op = HasKrausWhenDecomposed(decomposed_cls).on(cirq.NamedQubit('test'))
    assert cirq.has_kraus(op)
    assert not cirq.has_kraus(op, allow_decompose=False)
Ejemplo n.º 27
0
def test_has_kraus(cls):
    assert cirq.has_kraus(cls())
Ejemplo n.º 28
0
def test_has_channel_protocol_is_deprecated():
    with cirq.testing.assert_deprecated(deadline='v0.13'):
        assert cirq.has_channel(cirq.depolarize(0.1)) == cirq.has_kraus(cirq.depolarize(0.1))
Ejemplo n.º 29
0
def test_bit_flip_channel():
    d = cirq.bit_flip(0.3)
    np.testing.assert_almost_equal(
        cirq.kraus(d), (np.sqrt(1.0 - 0.3) * np.eye(2), np.sqrt(0.3) * X))
    assert cirq.has_kraus(d)
Ejemplo n.º 30
0
    def translate_cirq_to_qtrajectory(
        self,
        qubit_order: cirq.QubitOrderOrList = cirq.QubitOrder.DEFAULT
    ) -> qsim.NoisyCircuit:
        """
        Translates this noisy Cirq circuit to the qsim representation.
        :qubit_order: Ordering of qubits
        :return: a tuple of (C++ qsim NoisyCircuit object, moment boundary
            gate indices)
        """
        qsim_ncircuit = qsim.NoisyCircuit()
        ordered_qubits = cirq.QubitOrder.as_qubit_order(qubit_order).order_for(
            self.all_qubits())

        # qsim numbers qubits in reverse order from cirq
        ordered_qubits = list(reversed(ordered_qubits))

        qsim_ncircuit.num_qubits = len(ordered_qubits)

        def to_matrix(op: cirq.GateOperation):
            mat = cirq.unitary(op.gate, None)
            if mat is None:
                return NotImplemented

            return cirq.MatrixGate(mat).on(*op.qubits)

        qubit_to_index_dict = {q: i for i, q in enumerate(ordered_qubits)}
        time_offset = 0
        gate_count = 0
        moment_indices = []
        for moment in self:
            moment_length = 0
            ops_by_gate = []
            ops_by_mix = []
            ops_by_channel = []
            # Capture ops of each type in the appropriate list.
            for qsim_op in moment:
                if cirq.has_unitary(qsim_op) or cirq.is_measurement(qsim_op):
                    oplist = cirq.decompose(qsim_op,
                                            fallback_decomposer=to_matrix,
                                            keep=_has_cirq_gate_kind)
                    ops_by_gate.append(oplist)
                    moment_length = max(moment_length, len(oplist))
                    pass
                elif cirq.has_mixture(qsim_op):
                    ops_by_mix.append(qsim_op)
                    moment_length = max(moment_length, 1)
                    pass
                elif cirq.has_kraus(qsim_op):
                    ops_by_channel.append(qsim_op)
                    moment_length = max(moment_length, 1)
                    pass
                else:
                    raise ValueError(f"Encountered unparseable op: {qsim_op}")

            # Gates must be added in time order.
            for gi in range(moment_length):
                # Handle gate output.
                for gate_ops in ops_by_gate:
                    if gi >= len(gate_ops):
                        continue
                    qsim_op = gate_ops[gi]
                    time = time_offset + gi
                    add_op_to_circuit(qsim_op, time, qubit_to_index_dict,
                                      qsim_ncircuit)
                    gate_count += 1
                # Handle mixture output.
                for mixture in ops_by_mix:
                    mixdata = []
                    for prob, mat in cirq.mixture(mixture):
                        square_mat = np.reshape(mat,
                                                (int(np.sqrt(mat.size)), -1))
                        unitary = cirq.is_unitary(square_mat)
                        # Package matrix into a qsim-friendly format.
                        mat = np.reshape(mat, (-1, )).astype(np.complex64,
                                                             copy=False)
                        mixdata.append((prob, mat.view(np.float32), unitary))
                    qubits = [qubit_to_index_dict[q] for q in mixture.qubits]
                    qsim.add_channel(time_offset, qubits, mixdata,
                                     qsim_ncircuit)
                    gate_count += 1
                # Handle channel output.
                for channel in ops_by_channel:
                    chdata = []
                    for i, mat in enumerate(cirq.kraus(channel)):
                        square_mat = np.reshape(mat,
                                                (int(np.sqrt(mat.size)), -1))
                        unitary = cirq.is_unitary(square_mat)
                        singular_vals = np.linalg.svd(square_mat)[1]
                        lower_bound_prob = min(singular_vals)**2
                        # Package matrix into a qsim-friendly format.
                        mat = np.reshape(mat, (-1, )).astype(np.complex64,
                                                             copy=False)
                        chdata.append(
                            (lower_bound_prob, mat.view(np.float32), unitary))
                    qubits = [qubit_to_index_dict[q] for q in channel.qubits]
                    qsim.add_channel(time_offset, qubits, chdata,
                                     qsim_ncircuit)
                    gate_count += 1
            time_offset += moment_length
            moment_indices.append(gate_count)

        return qsim_ncircuit, moment_indices