Exemple #1
0
def test_readout_noise_after_moment():
    program = cirq.Circuit()
    qubits = cirq.LineQubit.range(3)
    program.append([
        cirq.H(qubits[0]),
        cirq.CNOT(qubits[0], qubits[1]),
        cirq.CNOT(qubits[1], qubits[2])
    ])
    program.append(
        [
            cirq.measure(qubits[0], key='q0'),
            cirq.measure(qubits[1], key='q1'),
            cirq.measure(qubits[2], key='q2'),
        ],
        strategy=cirq.InsertStrategy.NEW_THEN_INLINE,
    )

    # Use noise model to generate circuit
    depol_noise = ccn.DepolarizingNoiseModel(depol_prob=0.01)
    readout_noise = ccn.ReadoutNoiseModel(bitflip_prob=0.05)
    noisy_circuit = cirq.Circuit(depol_noise.noisy_moments(program, qubits))
    noisy_circuit = cirq.Circuit(
        readout_noise.noisy_moments(noisy_circuit, qubits))

    # Insert channels explicitly
    true_noisy_program = cirq.Circuit()
    true_noisy_program.append([cirq.H(qubits[0])])
    true_noisy_program.append(
        [
            cirq.DepolarizingChannel(0.01).on(q).with_tags(ops.VirtualTag())
            for q in qubits
        ],
        strategy=cirq.InsertStrategy.NEW_THEN_INLINE,
    )
    true_noisy_program.append([cirq.CNOT(qubits[0], qubits[1])])
    true_noisy_program.append(
        [
            cirq.DepolarizingChannel(0.01).on(q).with_tags(ops.VirtualTag())
            for q in qubits
        ],
        strategy=cirq.InsertStrategy.NEW_THEN_INLINE,
    )
    true_noisy_program.append([cirq.CNOT(qubits[1], qubits[2])])
    true_noisy_program.append(
        [
            cirq.DepolarizingChannel(0.01).on(q).with_tags(ops.VirtualTag())
            for q in qubits
        ],
        strategy=cirq.InsertStrategy.NEW_THEN_INLINE,
    )
    true_noisy_program.append([
        cirq.BitFlipChannel(0.05).on(q).with_tags(ops.VirtualTag())
        for q in qubits
    ])
    true_noisy_program.append([
        cirq.measure(qubits[0], key='q0'),
        cirq.measure(qubits[1], key='q1'),
        cirq.measure(qubits[2], key='q2'),
    ])
    assert_equivalent_op_tree(true_noisy_program, noisy_circuit)
Exemple #2
0
def test_constant_qubit_noise():
    a, b, c = cirq.LineQubit.range(3)
    damp = cirq.amplitude_damp(0.5)
    damp_all = cirq.ConstantQubitNoiseModel(damp)
    actual = damp_all.noisy_moments(
        [cirq.Moment([cirq.X(a)]), cirq.Moment()], [a, b, c])
    expected = [
        [
            cirq.Moment([cirq.X(a)]),
            cirq.Moment(
                d.with_tags(ops.VirtualTag())
                for d in [damp(a), damp(b), damp(c)]),
        ],
        [
            cirq.Moment(),
            cirq.Moment(
                d.with_tags(ops.VirtualTag())
                for d in [damp(a), damp(b), damp(c)]),
        ],
    ]
    assert actual == expected
    cirq.testing.assert_equivalent_repr(damp_all)

    with pytest.raises(ValueError, match='num_qubits'):
        _ = cirq.ConstantQubitNoiseModel(cirq.CNOT**0.01)
Exemple #3
0
def test_infers_other_methods():
    q = cirq.LineQubit(0)

    class NoiseModelWithNoisyMomentListMethod(cirq.NoiseModel):
        def noisy_moments(self, moments, system_qubits):
            result = []
            for moment in moments:
                if moment.operations:
                    result.append(
                        cirq.X(moment.operations[0].qubits[0]).with_tags(
                            ops.VirtualTag()))
                else:
                    result.append([])
            return result

    a = NoiseModelWithNoisyMomentListMethod()
    assert_equivalent_op_tree(a.noisy_operation(cirq.H(q)),
                              cirq.X(q).with_tags(ops.VirtualTag()))
    assert_equivalent_op_tree(a.noisy_moment(cirq.Moment([cirq.H(q)]), [q]),
                              cirq.X(q).with_tags(ops.VirtualTag()))
    assert_equivalent_op_tree_sequence(
        a.noisy_moments(
            [cirq.Moment(), cirq.Moment([cirq.H(q)])], [q]),
        [[], cirq.X(q).with_tags(ops.VirtualTag())],
    )

    class NoiseModelWithNoisyMomentMethod(cirq.NoiseModel):
        def noisy_moment(self, moment, system_qubits):
            return [
                y.with_tags(ops.VirtualTag())
                for y in cirq.Y.on_each(*moment.qubits)
            ]

    b = NoiseModelWithNoisyMomentMethod()
    assert_equivalent_op_tree(b.noisy_operation(cirq.H(q)),
                              cirq.Y(q).with_tags(ops.VirtualTag()))
    assert_equivalent_op_tree(b.noisy_moment(cirq.Moment([cirq.H(q)]), [q]),
                              cirq.Y(q).with_tags(ops.VirtualTag()))
    assert_equivalent_op_tree_sequence(
        b.noisy_moments(
            [cirq.Moment(), cirq.Moment([cirq.H(q)])], [q]),
        [[], cirq.Y(q).with_tags(ops.VirtualTag())],
    )

    class NoiseModelWithNoisyOperationMethod(cirq.NoiseModel):
        def noisy_operation(self, operation: 'cirq.Operation'):
            return cirq.Z(operation.qubits[0]).with_tags(ops.VirtualTag())

    c = NoiseModelWithNoisyOperationMethod()
    assert_equivalent_op_tree(c.noisy_operation(cirq.H(q)),
                              cirq.Z(q).with_tags(ops.VirtualTag()))
    assert_equivalent_op_tree(c.noisy_moment(cirq.Moment([cirq.H(q)]), [q]),
                              cirq.Z(q).with_tags(ops.VirtualTag()))
    assert_equivalent_op_tree_sequence(
        c.noisy_moments(
            [cirq.Moment(), cirq.Moment([cirq.H(q)])], [q]),
        [[], cirq.Z(q).with_tags(ops.VirtualTag())],
    )
def test_per_qubit_depol_noise_from_data():
    # Generate the depolarization noise model from calibration data.
    calibration = cirq.google.Calibration(_CALIBRATION_DATA)
    noise_model = simple_noise_from_calibration_metrics(calibration=calibration, depol_noise=True)

    # Create the circuit and apply the noise model.
    qubits = [cirq.GridQubit(0, 0), cirq.GridQubit(0, 1), cirq.GridQubit(1, 0)]
    program = cirq.Circuit(
        cirq.Moment([cirq.H(qubits[0])]),
        cirq.Moment([cirq.CNOT(qubits[0], qubits[1])]),
        cirq.Moment([cirq.CNOT(qubits[0], qubits[2])]),
        cirq.Moment([cirq.Z(qubits[1]).with_tags(ops.VirtualTag())]),
        cirq.Moment(
            [
                cirq.measure(qubits[0], key='q0'),
                cirq.measure(qubits[1], key='q1'),
                cirq.measure(qubits[2], key='q2'),
            ]
        ),
    )
    noisy_circuit = cirq.Circuit(noise_model.noisy_moments(program, qubits))

    # Insert channels explicitly to construct expected output.
    expected_program = cirq.Circuit(
        cirq.Moment([cirq.H(qubits[0])]),
        cirq.Moment([cirq.DepolarizingChannel(DEPOL_001).on(qubits[0])]),
        cirq.Moment([cirq.CNOT(qubits[0], qubits[1])]),
        cirq.Moment(
            [
                cirq.DepolarizingChannel(DEPOL_001).on(qubits[0]),
                cirq.DepolarizingChannel(DEPOL_002).on(qubits[1]),
            ]
        ),
        cirq.Moment([cirq.CNOT(qubits[0], qubits[2])]),
        cirq.Moment(
            [
                cirq.DepolarizingChannel(DEPOL_001).on(qubits[0]),
                cirq.DepolarizingChannel(DEPOL_003).on(qubits[2]),
            ]
        ),
        cirq.Moment([cirq.Z(qubits[1]).with_tags(ops.VirtualTag())]),
        cirq.Moment(
            [
                cirq.measure(qubits[0], key='q0'),
                cirq.measure(qubits[1], key='q1'),
                cirq.measure(qubits[2], key='q2'),
            ]
        ),
    )
    _assert_equivalent_op_tree(expected_program, noisy_circuit)
Exemple #5
0
    def noisy_moment(self, moment: 'cirq.Moment', system_qubits: Sequence['cirq.Qid']):
        if _homogeneous_moment_is_measurements(moment) or self.is_virtual_moment(moment):
            # coverage: ignore
            return moment

        return [
            moment,
            ops.Moment(self.qubit_noise_gate(q).with_tags(ops.VirtualTag()) for q in system_qubits),
        ]
Exemple #6
0
 def noisy_moments(self, moments, system_qubits):
     result = []
     for moment in moments:
         if moment.operations:
             result.append(
                 cirq.X(moment.operations[0].qubits[0]).with_tags(
                     ops.VirtualTag()))
         else:
             result.append([])
     return result
Exemple #7
0
 def noisy_moment(self, moment: 'cirq.Moment', system_qubits: Sequence['cirq.Qid']):
     # Noise should not be appended to previously-added noise.
     if self.is_virtual_moment(moment):
         return moment
     return [
         moment,
         ops.Moment(
             [self.qubit_noise_gate(q).with_tags(ops.VirtualTag()) for q in system_qubits]
         ),
     ]
Exemple #8
0
 def noisy_moment(self, moment: 'cirq.Moment',
                  system_qubits: Sequence['cirq.Qid']):
     if self.is_virtual_moment(moment):
         return moment
     if _homogeneous_moment_is_measurements(moment):
         return [
             ops.Moment(
                 self.readout_noise_gate(q).with_tags(ops.VirtualTag())
                 for q in system_qubits), moment
         ]
     return moment
Exemple #9
0
 def noisy_moment(self, moment: 'cirq.Moment',
                  system_qubits: Sequence['cirq.Qid']):
     if self.is_virtual_moment(moment):
         return moment
     if validate_all_measurements(moment):
         return [
             ops.Moment(
                 self.readout_decay_gate(q).with_tags(ops.VirtualTag())
                 for q in system_qubits),
             moment,
         ]
     return moment
Exemple #10
0
def test_constant_qubit_noise_prepend():
    a, b, c = cirq.LineQubit.range(3)
    damp = cirq.amplitude_damp(0.5)
    damp_all = cirq.ConstantQubitNoiseModel(damp, prepend=True)
    actual = damp_all.noisy_moments(
        [cirq.Moment([cirq.X(a)]), cirq.Moment()], [a, b, c])
    expected = [
        [
            cirq.Moment(
                d.with_tags(ops.VirtualTag())
                for d in [damp(a), damp(b), damp(c)]),
            cirq.Moment([cirq.X(a)]),
        ],
        [
            cirq.Moment(
                d.with_tags(ops.VirtualTag())
                for d in [damp(a), damp(b), damp(c)]),
            cirq.Moment(),
        ],
    ]
    assert actual == expected
    cirq.testing.assert_equivalent_repr(damp_all)
Exemple #11
0
 def noisy_moment(self, moment: 'cirq.Moment',
                  system_qubits: Sequence['cirq.Qid']):
     if self.is_virtual_moment(moment):
         return moment
     if validate_all_measurements(moment):
         output = [
             circuits.Moment(
                 self.readout_noise_gate(q).with_tags(ops.VirtualTag())
                 for q in system_qubits),
             moment,
         ]
         return output if self._prepend else output[::-1]
     return moment
Exemple #12
0
    def noisy_moment(self, moment: 'cirq.Moment',
                     system_qubits: Sequence['cirq.Qid']):
        if validate_all_measurements(moment) or self.is_virtual_moment(moment):
            # coverage: ignore
            return moment

        output = [
            moment,
            circuits.Moment(
                self.qubit_noise_gate(q).with_tags(ops.VirtualTag())
                for q in system_qubits),
        ]
        return output[::-1] if self._prepend else output
Exemple #13
0
    def is_virtual_moment(self, moment: 'cirq.Moment') -> bool:
        """Returns true iff the given moment is non-empty and all of its
        operations are virtual.

        Moments for which this method returns True should not have additional
        noise applied to them.

        Args:
            moment: ``cirq.Moment`` to check for non-virtual operations.

        Returns:
            True if "moment" is non-empty and all operations in "moment" are
            virtual; false otherwise.
        """
        if not moment.operations:
            return False
        return all(ops.VirtualTag() in op.tags for op in moment)
Exemple #14
0
    def noisy_moment(self, moment: 'cirq.Moment',
                     system_qubits: Sequence['cirq.Qid']):
        # Noise should not be appended to previously-added noise.
        if self.is_virtual_moment(moment):
            return moment

        qbs = []

        for op in moment.operations:
            if len(op.qubits) == 2:
                for qb in op.qubits:
                    qbs.append(qb)

        return [
            moment,
            ops.Moment([
                # TODO: Replace with "VirtualTag" class instance.
                self.qubit_noise_gate(q).with_tags(ops.VirtualTag())
                for q in qbs
            ])
        ]
Exemple #15
0
 def noisy_operation(self, operation: 'cirq.Operation'):
     return cirq.Z(operation.qubits[0]).with_tags(ops.VirtualTag())
Exemple #16
0
 def noisy_moment(self, moment, system_qubits):
     return [
         y.with_tags(ops.VirtualTag())
         for y in cirq.Y.on_each(*moment.qubits)
     ]