def test_empty(self): """Test construction with empty noise_ops.""" with self.assertRaises(TypeError): QuantumError() with self.assertRaises(NoiseError): QuantumError([])
def test_depolarizing_error_2q_gate(self): """Test 2-qubit depolarizing error as gate qobj""" p_depol = 0.3 actual = depolarizing_error(p_depol, 2) expected = QuantumError([ (PauliGate("II"), 1 - p_depol * 15 / 16), (PauliGate("IX"), p_depol / 16), (PauliGate("IY"), p_depol / 16), (PauliGate("IZ"), p_depol / 16), (PauliGate("XI"), p_depol / 16), (PauliGate("XX"), p_depol / 16), (PauliGate("XY"), p_depol / 16), (PauliGate("XZ"), p_depol / 16), (PauliGate("YI"), p_depol / 16), (PauliGate("YX"), p_depol / 16), (PauliGate("YY"), p_depol / 16), (PauliGate("YZ"), p_depol / 16), (PauliGate("ZI"), p_depol / 16), (PauliGate("ZX"), p_depol / 16), (PauliGate("ZY"), p_depol / 16), (PauliGate("ZZ"), p_depol / 16), ]) for i in range(actual.size): circ, prob = actual.error_term(i) expected_circ, expected_prob = expected.error_term(i) self.assertEqual(circ, expected_circ, msg=f"Incorrect {i}-th circuit") self.assertAlmostEqual(prob, expected_prob, msg=f"Incorrect {i}-th probability")
def test_depolarizing_error_2q_gate(self): """Test 2-qubit depolarizing error as gate qobj""" p_depol = 0.3 with self.assertWarns(DeprecationWarning): actual = depolarizing_error(p_depol, 2, standard_gates=True) target_circs = [[{"name": "id", "qubits": [0]}, {"name": "id", "qubits": [1]}], [{"name": "id", "qubits": [0]}, {"name": "x", "qubits": [1]}], [{"name": "id", "qubits": [0]}, {"name": "y", "qubits": [1]}], [{"name": "id", "qubits": [0]}, {"name": "z", "qubits": [1]}], [{"name": "x", "qubits": [0]}, {"name": "id", "qubits": [1]}], [{"name": "x", "qubits": [0]}, {"name": "x", "qubits": [1]}], [{"name": "x", "qubits": [0]}, {"name": "y", "qubits": [1]}], [{"name": "x", "qubits": [0]}, {"name": "z", "qubits": [1]}], [{"name": "y", "qubits": [0]}, {"name": "id", "qubits": [1]}], [{"name": "y", "qubits": [0]}, {"name": "x", "qubits": [1]}], [{"name": "y", "qubits": [0]}, {"name": "y", "qubits": [1]}], [{"name": "y", "qubits": [0]}, {"name": "z", "qubits": [1]}], [{"name": "z", "qubits": [0]}, {"name": "id", "qubits": [1]}], [{"name": "z", "qubits": [0]}, {"name": "x", "qubits": [1]}], [{"name": "z", "qubits": [0]}, {"name": "y", "qubits": [1]}], [{"name": "z", "qubits": [0]}, {"name": "z", "qubits": [1]}]] target_probs = [1 - p_depol * 15 / 16] + [p_depol / 16] * 15 with self.assertWarns(DeprecationWarning): expected = QuantumError(zip(target_circs, target_probs), standard_gates=True) for i in range(actual.size): circ, prob = actual.error_term(i) expected_circ, expected_prob = expected.error_term(i) self.assertEqual(circ, expected_circ, msg=f"Incorrect {i}-th circuit") self.assertAlmostEqual(prob, expected_prob, msg=f"Incorrect {i}-th probability")
def test_init_with_circuits(self): """Test construction with mixture of quantum circuits.""" qc = QuantumCircuit(2) qc.h(0) qc.cx(0, 1) self.assertEqual(QuantumError(qc).size, 1) self.assertEqual(QuantumError([(qc, 0.7), (qc, 0.3)]).size, 2)
def test_raise_non_cptp_kraus(self): """Test exception is raised for non-CPTP input.""" a_0 = np.array([[1, 0], [0, np.sqrt(1 - 0.3)]], dtype=complex) a_1 = np.array([[0, 0], [np.sqrt(0.3), 0]], dtype=complex) with self.assertRaises(NoiseError), self.assertKrausWarning(): QuantumError([a_0, a_1]) with self.assertRaises(NoiseError), self.assertKrausWarning(): QuantumError([a_0])
def test_tensor_with_different_type_of_operator(self): """Test tensor with Kraus operator.""" noise_x = QuantumError([((IGate(), [0]), 0.9), ((XGate(), [0]), 0.1)]) meas_kraus = Kraus([np.diag([1, 0]), np.diag([0, 1])]) actual = noise_x.tensor(meas_kraus) expected = QuantumError([([(IGate(), [1]), (meas_kraus.to_instruction(), [0])], 0.9), ([(XGate(), [1]), (meas_kraus.to_instruction(), [0])], 0.1)]) self.assertEqual(actual, expected)
def test_to_quantumchannel_kraus(self): """Test to_quantumchannel for Kraus inputs.""" a_0 = np.array([[1, 0], [0, np.sqrt(1 - 0.3)]], dtype=complex) a_1 = np.array([[0, 0], [0, np.sqrt(0.3)]], dtype=complex) b_0 = np.array([[1, 0], [0, np.sqrt(1 - 0.5)]], dtype=complex) b_1 = np.array([[0, 0], [0, np.sqrt(0.5)]], dtype=complex) target = SuperOp(Kraus([a_0, a_1])).tensor(SuperOp(Kraus([b_0, b_1]))) error = QuantumError([a_0, a_1]).tensor(QuantumError([b_0, b_1])) self.assertEqual(target, error.to_quantumchannel())
def test_equal(self): """Test two quantum errors are equal""" a_i = np.sqrt(0.25) * standard_gate_unitary('id') a_x = np.sqrt(0.25) * standard_gate_unitary('x') a_y = np.sqrt(0.25) * standard_gate_unitary('y') a_z = np.sqrt(0.25) * standard_gate_unitary('z') error1 = QuantumError([a_i, a_x, a_y, a_z], standard_gates=True) error2 = QuantumError([a_i, a_x, a_y, a_z], standard_gates=False) self.assertEqual(error1, error2)
def test_pauli_conversion_unitary(self): """Test conversion of Pauli channel kraus to unitary qobj""" error = QuantumError(self.depol_error(1), standard_gates=False) for j in range(4): instr, _ = error.error_term(j) self.assertEqual(len(instr), 1) self.assertIn(instr[0]['name'], ['unitary', 'id']) self.assertEqual(instr[0]['qubits'], [0]) target = SuperOp(Kraus(self.depol_error(1))) self.assertEqual(target, SuperOp(error))
def test_raise_if_invalid_op_type_for_init(self): """Test exception is raised when input with invalid type are supplied.""" with self.assertRaises(NoiseError): QuantumError(Measure()) # instruction with clbits with self.assertRaises(NoiseError): QuantumError([Reset(), XGate()]) # list of instructions expecting default qubits with self.assertRaises(NoiseError): QuantumError([(Reset(), [0]), XGate()]) # partially supplied
def test_compose_one_with_different_num_qubits(self): """Test compose errors with different number of qubits.""" noise_1q = QuantumError([((IGate(), [0]), 0.9), ((XGate(), [0]), 0.1)]) noise_2q = QuantumError([((IGate(), [0]), 0.8), ((XGate(), [1]), 0.2)]) actual = noise_1q.compose(noise_2q) expected = QuantumError([([(IGate(), [0]), (IGate(), [0])], 0.9 * 0.8), ([(IGate(), [0]), (XGate(), [1])], 0.9 * 0.2), ([(XGate(), [0]), (IGate(), [0])], 0.1 * 0.8), ([(XGate(), [0]), (XGate(), [1])], 0.1 * 0.2)]) self.assertEqual(actual, expected)
def test_expand(self): """Test tensor two quantum errors.""" noise_x = QuantumError([((IGate(), [0]), 0.9), ((XGate(), [0]), 0.1)]) noise_y = QuantumError([((IGate(), [0]), 0.8), ((YGate(), [0]), 0.2)]) actual = noise_y.expand(noise_x) # reversed order of expand expected = QuantumError([([(IGate(), [1]), (IGate(), [0])], 0.9 * 0.8), ([(IGate(), [1]), (YGate(), [0])], 0.9 * 0.2), ([(XGate(), [1]), (IGate(), [0])], 0.1 * 0.8), ([(XGate(), [1]), (YGate(), [0])], 0.1 * 0.2)]) self.assertEqual(actual, expected)
def test_dot(self): """Test dot two quantum errors.""" noise_x = QuantumError([((IGate(), [0]), 0.9), ((XGate(), [0]), 0.1)]) noise_y = QuantumError([((IGate(), [0]), 0.8), ((YGate(), [0]), 0.2)]) actual = noise_y.dot(noise_x) # reversed order of compose expected = QuantumError([([(IGate(), [0]), (IGate(), [0])], 0.9 * 0.8), ([(IGate(), [0]), (YGate(), [0])], 0.9 * 0.2), ([(XGate(), [0]), (IGate(), [0])], 0.1 * 0.8), ([(XGate(), [0]), (YGate(), [0])], 0.1 * 0.2)]) self.assertEqual(actual, expected)
def test_tensor(self): """Test tensor two quantum errors.""" noise_x = QuantumError([((IGate(), [0]), 0.9), ((XGate(), [0]), 0.1)]) noise_y = QuantumError([((IGate(), [0]), 0.8), ((YGate(), [0]), 0.2)]) actual = noise_x.tensor(noise_y) expected = QuantumError([([(IGate(), [1]), (IGate(), [0])], 0.9 * 0.8), ([(IGate(), [1]), (YGate(), [0])], 0.9 * 0.2), ([(XGate(), [1]), (IGate(), [0])], 0.1 * 0.8), ([(XGate(), [1]), (YGate(), [0])], 0.1 * 0.2)]) self.assertEqual(actual, expected)
def test_ideal(self): """Test ideal gates are identified correctly.""" self.assertTrue(QuantumError(IGate()).ideal()) self.assertTrue(QuantumError(UnitaryGate(np.eye(2))).ideal()) self.assertTrue(QuantumError([(IGate(), 0.7), (IGate(), 0.3)]).ideal()) # up to global phase qc = QuantumCircuit(1, global_phase=0.5) qc.i(0) self.assertTrue(QuantumError(qc).ideal()) self.assertTrue(QuantumError(UnitaryGate(-1.0 * np.eye(2))).ideal())
def test_init_with_operators(self): """Test construction with mixture of operators.""" kraus = Kraus([np.sqrt(0.7) * np.eye(2), np.sqrt(0.3) * np.diag([1, -1])]) self.assertEqual(QuantumError(kraus).size, 1) self.assertEqual(QuantumError([(kraus, 0.7), (kraus, 0.3)]).size, 2) self.assertEqual(QuantumError(Pauli("X")).probabilities, [1.0]) self.assertEqual(QuantumError([(Pauli("I"), 0.7), (Pauli("Z"), 0.3)]).size, 2) self.assertEqual(QuantumError([(Pauli("I"), 0.7), (kraus, 0.3)]).size, 2)
def test_expand_both_kraus(self): """Test expand of two kraus errors""" kraus0 = self.kraus_error(0.3) kraus1 = self.kraus_error(0.5) error = QuantumError(kraus0).expand(QuantumError(kraus1)) target = SuperOp(Kraus(kraus0)).expand(Kraus(kraus1)) circ, prob = error.error_term(0) self.assertEqual(prob, 1) self.assertEqual(circ[0]['name'], 'kraus') self.assertEqual(circ[0]['qubits'], [0, 1]) self.assertEqual(target, SuperOp(error))
def test_dot_unitary_and_kraus(self): """Test dot of a unitary and kraus error.""" kraus = self.kraus_error(0.4) unitaries = self.depol_error(0.1) error = QuantumError(unitaries).dot(QuantumError(kraus)) target = SuperOp(Kraus(unitaries)).dot(Kraus(kraus)) circ, prob = error.error_term(0) self.assertEqual(prob, 1) self.assertEqual(circ[0]['name'], 'kraus') self.assertEqual(circ[0]['qubits'], [0]) self.assertEqual(target, SuperOp(error))
def test_compose_kraus_and_unitary(self): """Test compose of a kraus and unitary error.""" kraus = self.kraus_error(0.4) unitaries = self.depol_error(0.1) error = QuantumError(kraus).compose(QuantumError(unitaries)) target = SuperOp(Kraus(kraus)).compose(Kraus(unitaries)) circ, prob = error.error_term(0) self.assertEqual(prob, 1) self.assertEqual(circ[0]['name'], 'kraus') self.assertEqual(circ[0]['qubits'], [0]) self.assertEqual(target, SuperOp(error))
def test_pauli_error_1q_gate_from_string(self): """Test single-qubit pauli error as gate qobj from string label""" paulis = ['I', 'X', 'Y', 'Z'] probs = [0.4, 0.3, 0.2, 0.1] actual = pauli_error(zip(paulis, probs)) expected = QuantumError([(IGate(), 0.4), (XGate(), 0.3), (YGate(), 0.2), (ZGate(), 0.1)]) for i in range(actual.size): circ, prob = actual.error_term(i) expected_circ, expected_prob = expected.error_term(i) self.assertEqual(circ, expected_circ, msg=f"Incorrect {i}-th circuit") self.assertAlmostEqual(prob, expected_prob, msg=f"Incorrect {i}-th probability")
def test_thermal_relaxation_error_t1_equal_t2_1state(self): """Test qobj instructions return for t1=t2""" actual = thermal_relaxation_error(1, 1, 1, 1) expected = QuantumError([ (IGate(), np.exp(-1)), ([(Reset(), [0]), (XGate(), [0])], 1 - np.exp(-1)), ]) for i in range(actual.size): circ, prob = actual.error_term(i) expected_circ, expected_prob = expected.error_term(i) self.assertEqual(circ, expected_circ, msg=f"Incorrect {i}-th circuit") self.assertAlmostEqual(prob, expected_prob, msg=f"Incorrect {i}-th probability")
def test_dot_both_kraus(self): """Test dot of two kraus errors""" kraus0 = self.kraus_error(0.3) kraus1 = self.kraus_error(0.5) error = QuantumError(kraus0).dot(QuantumError(kraus1)) target = SuperOp(Kraus(kraus0)).dot(Kraus(kraus1)) kraus, prob = error.error_term(0) self.assertEqual(prob, 1) self.assertEqual(kraus[0]['name'], 'kraus') self.assertEqual(kraus[0]['qubits'], [0]) self.assertEqual(target, SuperOp(error), msg="Incorrect dot kraus")
def test_to_quantumchannel_kraus(self): """Test to_quantumchannel for Kraus inputs.""" a_0 = np.array([[1, 0], [0, np.sqrt(1 - 0.3)]], dtype=complex) a_1 = np.array([[0, 0], [0, np.sqrt(0.3)]], dtype=complex) b_0 = np.array([[1, 0], [0, np.sqrt(1 - 0.5)]], dtype=complex) b_1 = np.array([[0, 0], [0, np.sqrt(0.5)]], dtype=complex) target = SuperOp(Kraus([a_0, a_1])).tensor(SuperOp(Kraus([b_0, b_1]))) with self.assertWarns( DeprecationWarning, msg=r"Constructing QuantumError .* Kraus channel .* qiskit-aer 0\.10\.0 .*", ): error = QuantumError([a_0, a_1]).tensor(QuantumError([b_0, b_1])) self.assertEqual(target, error.to_quantumchannel())
def test_pauli_error_2q_gate_from_pauli(self): """Test two-qubit pauli error as gate qobj from Pauli obj""" paulis = [qi.Pauli(s) for s in ['XZ', 'YX', 'ZY']] probs = [0.5, 0.3, 0.2] actual = pauli_error(zip(paulis, probs)) expected = QuantumError( [(PauliGate("XZ"), 0.5), (PauliGate("YX"), 0.3), (PauliGate("ZY"), 0.2)] ) for i in range(actual.size): circ, prob = actual.error_term(i) expected_circ, expected_prob = expected.error_term(i) self.assertEqual(circ, expected_circ, msg=f"Incorrect {i}-th circuit") self.assertAlmostEqual(prob, expected_prob, msg=f"Incorrect {i}-th probability")
def test_equal(self): """Test two quantum errors are equal""" with self.assertWarns( DeprecationWarning, msg=r"standard_gate_unitary is deprecated as of qiskit-aer 0\.10\.0.*", ): a_i = np.sqrt(0.25) * standard_gate_unitary('id') a_x = np.sqrt(0.25) * standard_gate_unitary('x') a_y = np.sqrt(0.25) * standard_gate_unitary('y') a_z = np.sqrt(0.25) * standard_gate_unitary('z') with self.assertKrausWarning(): error1 = QuantumError([a_i, a_x, a_y, a_z], standard_gates=True) error2 = QuantumError([a_i, a_x, a_y, a_z], standard_gates=False) self.assertEqual(error1, error2)
def test_dot_both_unitary_standard_gates(self): """Test dot of two unitary standard gate errors""" unitaries0 = self.mixed_unitary_error([0.9, 0.1], ['z', 's']) unitaries1 = self.mixed_unitary_error([0.6, 0.4], ['x', 'y']) error0 = QuantumError(unitaries0, standard_gates=True) error1 = QuantumError(unitaries1, standard_gates=True) error = error0.dot(error1) target = SuperOp(Kraus(unitaries0)).dot(Kraus(unitaries1)) for j in range(4): circ, _ = error.error_term(j) self.assertIn(circ[0]['name'], ['s', 'x', 'y', 'z']) self.assertEqual(circ[0]['qubits'], [0]) self.assertEqual(SuperOp(error), target)
def test_compose_both_unitary_instruction(self): """Test compose of two unitary instruction errors.""" unitaries0 = self.mixed_unitary_error([0.9, 0.1], ['z', 's']) unitaries1 = self.mixed_unitary_error([0.6, 0.4], ['x', 'y']) error0 = QuantumError(unitaries0, standard_gates=False) error1 = QuantumError(unitaries1, standard_gates=False) error = error0.compose(error1) target = SuperOp(Kraus(unitaries0)).compose(Kraus(unitaries1)) for j in range(4): circ, _ = error.error_term(j) self.assertEqual(circ[0]['name'], 'unitary') self.assertEqual(circ[0]['qubits'], [0]) self.assertEqual(SuperOp(error), target)
def test_raise_probabilities_normalized_nonunitary_kraus(self): """Test exception is raised for non-unitary kraus probs greater than 1.""" a_0 = np.sqrt(0.9) * np.array([[1, 0], [0, np.sqrt(1 - 0.3)]], dtype=complex) a_1 = np.sqrt(0.2) * np.array([[0, np.sqrt(0.3)], [0, 0]], dtype=complex) self.assertRaises(NoiseError, lambda: QuantumError([a_0, a_1]))
def test_tensor_both_unitary_standard_gates(self): """Test tensor of two unitary standard gate errors""" unitaries0 = self.mixed_unitary_error([0.9, 0.1], ['z', 's']) unitaries1 = self.mixed_unitary_error([0.6, 0.4], ['x', 'y']) error0 = QuantumError(unitaries0, standard_gates=True) error1 = QuantumError(unitaries1, standard_gates=True) error = error0.tensor(error1) target = SuperOp(Kraus(unitaries0)).tensor(Kraus(unitaries1)) for j in range(4): circ, _ = error.error_term(j) self.assertEqual(len(circ), 2) for instr in circ: self.assertIn(instr['name'], ['s', 'x', 'y', 'z']) self.assertIn(instr['qubits'], [[0], [1]]) self.assertEqual(SuperOp(error), target)
def test_to_quantum_channel(self): """Test conversion into quantum channel.""" meas_kraus = Kraus([np.diag([1, 0]), np.diag([0, 1])]) actual = QuantumError(meas_kraus).to_quantumchannel() expected = SuperOp(np.diag([1, 0, 0, 1])) self.assertEqual(actual, expected)