1# Copyright 2020 The Cirq Developers
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14import pytest
15import cirq
16
17from cirq_pasqal import PasqalNoiseModel, PasqalDevice
18from cirq.ops import NamedQubit
19
20
21def test_noise_model_init():
22    noise_model = PasqalNoiseModel(PasqalDevice([]))
23    assert noise_model.noise_op_dict == {
24        str(cirq.ops.YPowGate()): cirq.ops.depolarize(1e-2),
25        str(cirq.ops.ZPowGate()): cirq.ops.depolarize(1e-2),
26        str(cirq.ops.XPowGate()): cirq.ops.depolarize(1e-2),
27        str(cirq.ops.HPowGate(exponent=1)): cirq.ops.depolarize(1e-2),
28        str(cirq.ops.PhasedXPowGate(phase_exponent=0)): cirq.ops.depolarize(1e-2),
29        str(cirq.ops.CNotPowGate(exponent=1)): cirq.ops.depolarize(3e-2),
30        str(cirq.ops.CZPowGate(exponent=1)): cirq.ops.depolarize(3e-2),
31        str(cirq.ops.CCXPowGate(exponent=1)): cirq.ops.depolarize(8e-2),
32        str(cirq.ops.CCZPowGate(exponent=1)): cirq.ops.depolarize(8e-2),
33    }
34    with pytest.raises(TypeError, match="noise model varies between Pasqal's devices."):
35        PasqalNoiseModel(cirq.devices.UNCONSTRAINED_DEVICE)
36
37
38def test_noisy_moments():
39    p_qubits = cirq.NamedQubit.range(2, prefix='q')
40    p_device = PasqalDevice(qubits=p_qubits)
41    noise_model = PasqalNoiseModel(p_device)
42    circuit = cirq.Circuit()
43    circuit.append(cirq.ops.CZ(p_qubits[0], p_qubits[1]))
44    circuit.append(cirq.ops.Z(p_qubits[1]))
45    p_circuit = cirq.Circuit(circuit, device=p_device)
46
47    n_mts = []
48    for moment in p_circuit._moments:
49        n_mts.append(noise_model.noisy_moment(moment, p_qubits))
50
51    assert n_mts == [
52        [
53            cirq.ops.CZ.on(NamedQubit('q0'), NamedQubit('q1')),
54            cirq.depolarize(p=0.03).on(NamedQubit('q0')),
55            cirq.depolarize(p=0.03).on(NamedQubit('q1')),
56        ],
57        [cirq.ops.Z.on(NamedQubit('q1')), cirq.depolarize(p=0.01).on(NamedQubit('q1'))],
58    ]
59
60
61def test_default_noise():
62    p_qubits = cirq.NamedQubit.range(2, prefix='q')
63    p_device = PasqalDevice(qubits=p_qubits)
64    noise_model = PasqalNoiseModel(p_device)
65    circuit = cirq.Circuit()
66    Gate_l = cirq.ops.CZPowGate(exponent=2)
67    circuit.append(Gate_l.on(p_qubits[0], p_qubits[1]))
68    p_circuit = cirq.Circuit(circuit, device=p_device)
69    n_mts = []
70    for moment in p_circuit._moments:
71        n_mts.append(noise_model.noisy_moment(moment, p_qubits))
72
73    assert n_mts == [
74        [
75            cirq.ops.CZPowGate(exponent=2).on(NamedQubit('q0'), NamedQubit('q1')),
76            cirq.depolarize(p=0.05).on(NamedQubit('q0')),
77            cirq.depolarize(p=0.05).on(NamedQubit('q1')),
78        ]
79    ]
80
81
82def test_get_op_string():
83    p_qubits = cirq.NamedQubit.range(2, prefix='q')
84    p_device = PasqalDevice(p_qubits)
85    noise_model = PasqalNoiseModel(p_device)
86    circuit = cirq.Circuit()
87    circuit.append(cirq.ops.HPowGate(exponent=0.5).on(p_qubits[0]))
88
89    with pytest.raises(ValueError, match='Got unknown operation:'):
90        for moment in circuit._moments:
91            _ = noise_model.noisy_moment(moment, p_qubits)
92
93    with pytest.raises(ValueError, match='Got unknown operation:'):
94        _ = noise_model.get_op_string(circuit)
95