예제 #1
0
def test_invalid_arguments():
    with pytest.raises(ValueError,
                       match='At least one metric must be specified'):
        NoiseProperties()

    with pytest.raises(
            ValueError,
            match='xeb, pauli error, p00, and p11 must be between 0 and 1'):
        NoiseProperties(p00=1.2)

    with pytest.raises(
            ValueError,
            match='xeb, pauli error, p00, and p11 must be between 0 and 1'):
        NoiseProperties(pauli_error=-0.2)

    with pytest.raises(
            ValueError,
            match=
            'Only one of xeb fidelity, pauli error, or decay constant should be defined',
    ):
        NoiseProperties(pauli_error=0.2, xeb_fidelity=0.5)

    with pytest.raises(ValueError,
                       match='A NoiseProperties object must be specified'):
        NoiseModelFromNoiseProperties(None)
def test_wait_gates():
    q0 = cirq.LineQubit(0)
    props = TestNoiseProperties(**default_props([q0], []))
    model = NoiseModelFromNoiseProperties(props)
    op = cirq.wait(q0, nanos=100)
    circuit = cirq.Circuit(op)
    noisy_circuit = circuit.with_noise(model)
    assert len(noisy_circuit.moments) == 2
    assert noisy_circuit.moments[0].operations[0] == op.with_tags(
        PHYSICAL_GATE_TAG)

    # No depolarizing noise because WaitGate has none.

    assert len(noisy_circuit.moments[1].operations) == 1
    thermal_op = noisy_circuit.moments[1].operations[0]
    assert isinstance(thermal_op.gate, cirq.KrausChannel)
    thermal_choi = cirq.kraus_to_choi(cirq.kraus(thermal_op))
    assert np.allclose(
        thermal_choi,
        [
            [1, 0, 0, 9.990005e-01],
            [0, 9.99500167e-04, 0, 0],
            [0, 0, 0, 0],
            [9.990005e-01, 0, 0, 9.990005e-01],
        ],
    )
def test_measure_gates():
    q00, q01, q10, q11 = cirq.GridQubit.rect(2, 2)
    qubits = [q00, q01, q10, q11]
    props = TestNoiseProperties(**default_props(
        qubits,
        [
            (q00, q01),
            (q01, q00),
            (q10, q11),
            (q11, q10),
            (q00, q10),
            (q10, q00),
            (q01, q11),
            (q11, q01),
        ],
    ))
    model = NoiseModelFromNoiseProperties(props)
    op = cirq.measure(*qubits, key='m')
    circuit = cirq.Circuit(cirq.measure(*qubits, key='m'))
    noisy_circuit = circuit.with_noise(model)
    assert len(noisy_circuit.moments) == 2

    # Amplitude damping before measurement
    assert len(noisy_circuit.moments[0].operations) == 4
    for q in qubits:
        op = noisy_circuit.moments[0].operation_at(q)
        assert isinstance(op.gate, cirq.GeneralizedAmplitudeDampingChannel), q
        assert np.isclose(op.gate.p, 0.90909090), q
        assert np.isclose(op.gate.gamma, 0.011), q

    # Original measurement is after the noise.
    assert len(noisy_circuit.moments[1].operations) == 1
    # Measurements are untagged during reconstruction.
    assert noisy_circuit.moments[1] == circuit.moments[0]
def test_two_qubit_gates(op):
    q0, q1 = cirq.LineQubit.range(2)
    props = TestNoiseProperties(
        **default_props([q0, q1], [(q0, q1), (q1, q0)]))
    model = NoiseModelFromNoiseProperties(props)
    circuit = cirq.Circuit(op)
    noisy_circuit = circuit.with_noise(model)
    assert len(noisy_circuit.moments) == 3
    assert len(noisy_circuit.moments[0].operations) == 1
    assert noisy_circuit.moments[0].operations[0] == op.with_tags(
        PHYSICAL_GATE_TAG)

    # Depolarizing noise
    assert len(noisy_circuit.moments[1].operations) == 1
    depol_op = noisy_circuit.moments[1].operations[0]
    assert isinstance(depol_op.gate, cirq.DepolarizingChannel)
    assert np.isclose(depol_op.gate.p, 0.00952008)

    # Thermal noise
    assert len(noisy_circuit.moments[2].operations) == 2
    thermal_op_0 = noisy_circuit.moments[2].operation_at(q0)
    thermal_op_1 = noisy_circuit.moments[2].operation_at(q1)
    assert isinstance(thermal_op_0.gate, cirq.KrausChannel)
    assert isinstance(thermal_op_1.gate, cirq.KrausChannel)
    thermal_choi_0 = cirq.kraus_to_choi(cirq.kraus(thermal_op_0))
    thermal_choi_1 = cirq.kraus_to_choi(cirq.kraus(thermal_op_1))
    expected_thermal_choi = np.array([
        [1, 0, 0, 9.99680051e-01],
        [0, 3.19948805e-04, 0, 0],
        [0, 0, 0, 0],
        [9.99680051e-01, 0, 0, 9.99680051e-01],
    ])
    assert np.allclose(thermal_choi_0, expected_thermal_choi)
    assert np.allclose(thermal_choi_1, expected_thermal_choi)
def test_single_qubit_gates(op):
    q0 = cirq.LineQubit(0)
    props = TestNoiseProperties(**default_props([q0], []))
    model = NoiseModelFromNoiseProperties(props)
    circuit = cirq.Circuit(op)
    noisy_circuit = circuit.with_noise(model)
    assert len(noisy_circuit.moments) == 3
    assert len(noisy_circuit.moments[0].operations) == 1
    assert noisy_circuit.moments[0].operations[0] == op.with_tags(
        PHYSICAL_GATE_TAG)

    # Depolarizing noise
    assert len(noisy_circuit.moments[1].operations) == 1
    depol_op = noisy_circuit.moments[1].operations[0]
    assert isinstance(depol_op.gate, cirq.DepolarizingChannel)
    assert np.isclose(depol_op.gate.p, 0.00081252)

    # Thermal noise
    assert len(noisy_circuit.moments[2].operations) == 1
    thermal_op = noisy_circuit.moments[2].operations[0]
    assert isinstance(thermal_op.gate, cirq.KrausChannel)
    thermal_choi = cirq.kraus_to_choi(cirq.kraus(thermal_op))
    assert np.allclose(
        thermal_choi,
        [
            [1, 0, 0, 9.99750031e-01],
            [0, 2.49968753e-04, 0, 0],
            [0, 0, 0, 0],
            [9.99750031e-01, 0, 0, 9.99750031e-01],
        ],
    )
예제 #6
0
def test_ampl_damping_error():
    t1_ns = 200.0

    # Create qubits and circuit
    qubits = [cirq.LineQubit(0), cirq.LineQubit(1)]
    circuit = cirq.Circuit(
        cirq.Moment([cirq.X(qubits[0])]),
        cirq.Moment([cirq.CNOT(qubits[0], qubits[1])]),
        cirq.Moment([cirq.FSimGate(5 * np.pi / 2, np.pi).on_each(qubits)]),
        cirq.Moment([
            cirq.measure(qubits[0], key='q0'),
            cirq.measure(qubits[1], key='q1')
        ]),
    )

    # Create noise model from NoiseProperties object with specified noise
    prop = NoiseProperties(t1_ns=t1_ns)
    noise_model = NoiseModelFromNoiseProperties(prop)

    noisy_circuit = cirq.Circuit(noise_model.noisy_moments(circuit, qubits))

    # Insert expected channels to circuit
    expected_circuit = cirq.Circuit(
        cirq.Moment([cirq.X(qubits[0])]),
        cirq.Moment(
            [cirq.amplitude_damp(1 - np.exp(-25.0 / t1_ns)).on_each(qubits)]),
        cirq.Moment([cirq.CNOT(qubits[0], qubits[1])]),
        cirq.Moment(
            [cirq.amplitude_damp(1 - np.exp(-25.0 / t1_ns)).on_each(qubits)]),
        cirq.Moment([cirq.FSimGate(np.pi / 2, np.pi).on_each(qubits)]),
        cirq.Moment(
            [cirq.amplitude_damp(1 - np.exp(-12.0 / t1_ns)).on_each(qubits)]),
        cirq.Moment([
            cirq.measure(qubits[0], key='q0'),
            cirq.measure(qubits[1], key='q1')
        ]),
        cirq.Moment([
            cirq.amplitude_damp(1 - np.exp(-4000.0 / t1_ns)).on_each(qubits)
        ]),
    )
    assert_equivalent_op_tree(expected_circuit, noisy_circuit)
예제 #7
0
def test_depolarization_error():
    # Account for floating point errors
    # Needs Cirq issue 3965 to be resolved
    pauli_error = 0.09999999999999998

    # Create qubits and circuit
    qubits = [cirq.LineQubit(0), cirq.LineQubit(1)]
    circuit = cirq.Circuit(
        cirq.Moment([cirq.X(qubits[0])]),
        cirq.Moment([cirq.CNOT(qubits[0], qubits[1])]),
        cirq.Moment([cirq.H(qubits[1])]),
        cirq.Moment([
            cirq.measure(qubits[0], key='q0'),
            cirq.measure(qubits[1], key='q1')
        ]),
    )

    # Create noise model from NoiseProperties object with specified noise
    prop = NoiseProperties(pauli_error=pauli_error)
    noise_model = NoiseModelFromNoiseProperties(prop)

    noisy_circuit = cirq.Circuit(noise_model.noisy_moments(circuit, qubits))

    # Insert expected channels to circuit
    expected_circuit = cirq.Circuit(
        cirq.Moment([cirq.X(qubits[0])]),
        cirq.Moment([cirq.depolarize(pauli_error / 3).on_each(qubits)]),
        cirq.Moment([cirq.CNOT(qubits[0], qubits[1])]),
        cirq.Moment([cirq.depolarize(pauli_error / 3).on_each(qubits)]),
        cirq.Moment([cirq.H(qubits[1])]),
        cirq.Moment([cirq.depolarize(pauli_error / 3).on_each(qubits)]),
        cirq.Moment([
            cirq.measure(qubits[0], key='q0'),
            cirq.measure(qubits[1], key='q1')
        ]),
        cirq.Moment([cirq.depolarize(pauli_error / 3).on_each(qubits)]),
    )
    assert_equivalent_op_tree(expected_circuit, noisy_circuit)
예제 #8
0
def test_sample_model():
    q0, q1 = cirq.LineQubit.range(2)
    props = SampleNoiseProperties([q0, q1], [(q0, q1), (q1, q0)])
    model = NoiseModelFromNoiseProperties(props)
    circuit = cirq.Circuit(cirq.X(q0), cirq.CNOT(q0, q1), cirq.Z(q1),
                           cirq.measure(q0, q1, key='meas'))
    noisy_circuit = circuit.with_noise(model)
    expected_circuit = cirq.Circuit(
        cirq.Moment(cirq.X(q0).with_tags(PHYSICAL_GATE_TAG)),
        cirq.Moment(cirq.H(q0)),
        cirq.Moment(cirq.CNOT(q0, q1).with_tags(PHYSICAL_GATE_TAG)),
        cirq.Moment(cirq.ISWAP(q0, q1)),
        cirq.Moment(cirq.Z(q1).with_tags(PHYSICAL_GATE_TAG)),
        cirq.Moment(cirq.H(q1)),
        cirq.Moment(cirq.measure(q0, q1, key='meas')),
        cirq.Moment(cirq.H(q0), cirq.H(q1)),
    )
    assert noisy_circuit == expected_circuit
예제 #9
0
def test_readout_error():
    p00 = 0.05
    p11 = 0.1

    p = p11 / (p00 + p11)
    gamma = p11 / p

    # Create qubits and circuit
    qubits = [cirq.LineQubit(0), cirq.LineQubit(1)]
    circuit = cirq.Circuit(
        cirq.Moment([cirq.X(qubits[0])]),
        cirq.Moment([cirq.CNOT(qubits[0], qubits[1])]),
        cirq.Moment([cirq.H(qubits[1])]),
        cirq.Moment([
            cirq.measure(qubits[0], key='q0'),
            cirq.measure(qubits[1], key='q1')
        ]),
    )

    # Create noise model from NoiseProperties object with specified noise
    prop = NoiseProperties(p00=p00, p11=p11)
    noise_model = NoiseModelFromNoiseProperties(prop)

    noisy_circuit = cirq.Circuit(noise_model.noisy_moments(circuit, qubits))

    # Insert expected channels to circuit
    expected_circuit = cirq.Circuit(
        cirq.Moment([cirq.X(qubits[0])]),
        cirq.Moment([cirq.CNOT(qubits[0], qubits[1])]),
        cirq.Moment([cirq.H(qubits[1])]),
        cirq.Moment([
            cirq.GeneralizedAmplitudeDampingChannel(
                p=p, gamma=gamma).on_each(qubits)
        ]),
        cirq.Moment([
            cirq.measure(qubits[0], key='q0'),
            cirq.measure(qubits[1], key='q1')
        ]),
    )

    assert_equivalent_op_tree(expected_circuit, noisy_circuit)

    # Create Noise Model with just p00
    prop_p00 = NoiseProperties(p00=p00)
    noise_model_p00 = NoiseModelFromNoiseProperties(prop_p00)

    noisy_circuit_p00 = cirq.Circuit(
        noise_model_p00.noisy_moments(circuit, qubits))

    # Insert expected channels to circuit
    expected_circuit_p00 = cirq.Circuit(
        cirq.Moment([cirq.X(qubits[0])]),
        cirq.Moment([cirq.CNOT(qubits[0], qubits[1])]),
        cirq.Moment([cirq.H(qubits[1])]),
        cirq.Moment([
            cirq.GeneralizedAmplitudeDampingChannel(p=0.0,
                                                    gamma=p00).on_each(qubits)
        ]),
        cirq.Moment([
            cirq.measure(qubits[0], key='q0'),
            cirq.measure(qubits[1], key='q1')
        ]),
    )

    assert_equivalent_op_tree(expected_circuit_p00, noisy_circuit_p00)

    # Create Noise Model with just p11
    prop_p11 = NoiseProperties(p11=p11)
    noise_model_p11 = NoiseModelFromNoiseProperties(prop_p11)

    noisy_circuit_p11 = cirq.Circuit(
        noise_model_p11.noisy_moments(circuit, qubits))

    # Insert expected channels to circuit
    expected_circuit_p11 = cirq.Circuit(
        cirq.Moment([cirq.X(qubits[0])]),
        cirq.Moment([cirq.CNOT(qubits[0], qubits[1])]),
        cirq.Moment([cirq.H(qubits[1])]),
        cirq.Moment([
            cirq.GeneralizedAmplitudeDampingChannel(p=1.0,
                                                    gamma=p11).on_each(qubits)
        ]),
        cirq.Moment([
            cirq.measure(qubits[0], key='q0'),
            cirq.measure(qubits[1], key='q1')
        ]),
    )

    assert_equivalent_op_tree(expected_circuit_p11, noisy_circuit_p11)
예제 #10
0
def test_combined_error():
    # Helper function to calculate pauli error from depolarization
    def pauli_error_from_depolarization(pauli_error, t1_ns, duration):
        t2 = 2 * t1_ns
        pauli_error_from_t1 = (1 - np.exp(-duration / t2)) / 2 + (
            1 - np.exp(-duration / t1_ns)) / 4
        if pauli_error >= pauli_error_from_t1:
            return pauli_error - pauli_error_from_t1
        return pauli_error

    t1_ns = 2000.0
    p11 = 0.01

    # Account for floating point errors
    # Needs Cirq issue 3965 to be resolved
    pauli_error = 0.019999999999999962

    # Create qubits and circuit
    qubits = [cirq.LineQubit(0), cirq.LineQubit(1)]
    circuit = cirq.Circuit(
        cirq.Moment([cirq.X(qubits[0])]),
        cirq.Moment([cirq.CNOT(qubits[0], qubits[1])]),
        cirq.Moment([cirq.measure(qubits[0], key='q0')]),
        cirq.Moment([cirq.ISwapPowGate().on_each(qubits)]),
        cirq.Moment([
            cirq.measure(qubits[0], key='q0'),
            cirq.measure(qubits[1], key='q1')
        ]),
    )

    # Create noise model from NoiseProperties object with specified noise
    prop = NoiseProperties(t1_ns=t1_ns, p11=p11, pauli_error=pauli_error)
    noise_model = NoiseModelFromNoiseProperties(prop)

    with pytest.warns(
            RuntimeWarning,
            match='Pauli error from T1 decay is greater than total Pauli error'
    ):
        noisy_circuit = cirq.Circuit(noise_model.noisy_moments(
            circuit, qubits))

    # Insert expected channels to circuit
    expected_circuit = cirq.Circuit(
        cirq.Moment([cirq.X(qubits[0])]),
        cirq.Moment([
            cirq.depolarize(
                pauli_error_from_depolarization(pauli_error, t1_ns, 25.0) /
                3).on_each(qubits)
        ]),
        cirq.Moment(
            [cirq.amplitude_damp(1 - np.exp(-25.0 / t1_ns)).on_each(qubits)]),
        cirq.Moment([cirq.CNOT(qubits[0], qubits[1])]),
        cirq.Moment([
            cirq.depolarize(
                pauli_error_from_depolarization(pauli_error, t1_ns, 25.0) /
                3).on_each(qubits)
        ]),
        cirq.Moment(
            [cirq.amplitude_damp(1 - np.exp(-25.0 / t1_ns)).on_each(qubits)]),
        cirq.Moment([
            cirq.GeneralizedAmplitudeDampingChannel(p=1.0,
                                                    gamma=p11).on(qubits[0])
        ]),
        cirq.Moment([cirq.measure(qubits[0], key='q0')]),
        cirq.Moment([
            cirq.depolarize(
                pauli_error_from_depolarization(pauli_error, t1_ns, 4000.0) /
                3).on_each(qubits)
        ]),
        cirq.Moment([
            cirq.amplitude_damp(1 - np.exp(-4000.0 / t1_ns)).on_each(qubits)
        ]),
        cirq.Moment([cirq.ISwapPowGate().on_each(qubits)]),
        cirq.Moment([
            cirq.depolarize(
                pauli_error_from_depolarization(pauli_error, t1_ns, 32.0) /
                3).on_each(qubits)
        ]),
        cirq.Moment(
            [cirq.amplitude_damp(1 - np.exp(-32.0 / t1_ns)).on_each(qubits)]),
        cirq.Moment([
            cirq.GeneralizedAmplitudeDampingChannel(p=1.0,
                                                    gamma=p11).on_each(qubits)
        ]),
        cirq.Moment([
            cirq.measure(qubits[0], key='q0'),
            cirq.measure(qubits[1], key='q1')
        ]),
        cirq.Moment([
            cirq.depolarize(
                pauli_error_from_depolarization(pauli_error, t1_ns, 4000.0) /
                3).on_each(qubits)
        ]),
        cirq.Moment([
            cirq.amplitude_damp(1 - np.exp(-4000.0 / t1_ns)).on_each(qubits)
        ]),
    )
    assert_equivalent_op_tree(expected_circuit, noisy_circuit)
예제 #11
0
def test_deprecated_virtual_predicate():
    q0, q1 = cirq.LineQubit.range(2)
    props = SampleNoiseProperties([q0, q1], [(q0, q1), (q1, q0)])
    model = NoiseModelFromNoiseProperties(props)
    with cirq.testing.assert_deprecated("Use is_virtual", deadline="v0.16"):
        _ = model.virtual_predicate(cirq.X(q0))
예제 #12
0
def compare_generated_noise_to_metrics(
    calibration: cirq_google.Calibration, validate: bool = True, tolerance: float = 0.01
):
    """Compares the metrics from a Calibration object to those measured from a Noise Model
       created with cirq.devices.noise_properties_from_calibration.

    Args:
    calibration: Calibration object to be turned into a Noise Model
    validate: check calibration metrics are in agreement (arg for noise_properties_from_calibration)
    tolerance: tolerance for calibration metrics (argument for noise_properties_from_calibration)

    Returns:
    df: Pandas dataframe comparing input and measured values for each calibration metric
    """
    # Create Noise Model from Calibration object
    noise_prop = noise_properties_from_calibration(calibration, validate, tolerance)
    noise_model = NoiseModelFromNoiseProperties(noise_prop)

    p00 = noise_prop.p00
    p11 = noise_prop.p11
    xeb_fidelity = noise_prop.xeb
    pauli_error = noise_prop.pauli_error
    t1_ns = noise_prop.t1_ns
    average_error = noise_prop.average_error()

    qubits = [cirq.LineQubit(0), cirq.LineQubit(1)]

    # Create simulator for experiments with noise model
    simulator = cirq.sim.DensityMatrixSimulator(noise=noise_model)

    # Experiments to measure metrics
    estimate_readout = cirq.experiments.estimate_single_qubit_readout_errors(
        simulator, qubits=[qubits[0]], repetitions=1000
    )

    xeb_result = cirq.experiments.cross_entropy_benchmarking(
        simulator, qubits, num_circuits=50, repetitions=1000
    )
    measured_xeb = np.mean([datum.xeb_fidelity for datum in xeb_result.data])
    decay_constant = xeb_result.depolarizing_model().cycle_depolarization

    output = []

    if p00 is not None:
        output.append(['p00', p00, estimate_readout.zero_state_errors[cirq.LineQubit(0)]])
    if p11 is not None:
        output.append(['p11', p11, estimate_readout.one_state_errors[cirq.LineQubit(0)]])
    if xeb_fidelity is not None:
        output.append(['XEB Fidelity', xeb_fidelity, measured_xeb])
    if t1_ns is not None:
        t1_results = cirq.experiments.t1_decay(
            simulator,
            qubit=qubits[0],
            num_points=100,
            repetitions=100,
            min_delay=cirq.Duration(nanos=10),
            max_delay=cirq.Duration(micros=1),
        )
        output.append(['T1', t1_ns, t1_results.constant])
    if pauli_error is not None:
        N = 2  # Dimension of Hilbert Space
        measured_pauli_error = (1 - decay_constant) * (1 - 1 / N / N)
        output.append(['Pauli Error', pauli_error, measured_pauli_error])
    if average_error is not None:
        N = 2  # Dimension of Hilbert Space
        measured_average_error = (1 - decay_constant) * (1 - 1 / N)
        output.append(['Average Error', average_error, measured_average_error])

    columns = ["Metric", "Initial value", "Measured value"]
    df = pd.DataFrame(output, columns=columns)
    return df