def test_transformation_by_pauli(self): n = NoiseTransformer() # polarization in the XY plane; we represent via Kraus operators X = self.ops['X'] Y = self.ops['Y'] Z = self.ops['Z'] p = 0.22 theta = numpy.pi / 5 E0 = numpy.sqrt(1 - p) * numpy.array(numpy.eye(2)) E1 = numpy.sqrt(p) * (numpy.cos(theta) * X + numpy.sin(theta) * Y) results = approximate_quantum_error((E0, E1), operator_dict={ "X": X, "Y": Y, "Z": Z }) expected_results = pauli_error([ ('X', p * numpy.cos(theta) * numpy.cos(theta)), ('Y', p * numpy.sin(theta) * numpy.sin(theta)), ('Z', 0), ('I', 1 - p) ]) self.assertErrorsAlmostEqual(expected_results, results) # now try again without fidelity; should be the same n.use_honesty_constraint = False results = approximate_quantum_error((E0, E1), operator_dict={ "X": X, "Y": Y, "Z": Z }) self.assertErrorsAlmostEqual(expected_results, results)
def test_approx_random_mixed_unitary_channel_2q(self): # run without raising any error noise1 = UnitaryGate(random_unitary(4, seed=123)) noise2 = UnitaryGate(random_unitary(4, seed=456)) noise = QuantumError([(noise1, 0.7), (noise2, 0.3)]) for opstr in ['pauli', 'reset']: approximate_quantum_error(noise, operator_string=opstr)
def test_transform(self): X = self.ops['X'] Y = self.ops['Y'] Z = self.ops['Z'] p = 0.34 theta = numpy.pi / 7 E0 = numpy.sqrt(1 - p) * numpy.array(numpy.eye(2)) E1 = numpy.sqrt(p) * (numpy.cos(theta) * numpy.array(X) + numpy.sin(theta) * numpy.array(Y)) results_dict = approximate_quantum_error(Kraus([E0, E1]), operator_dict={ "X": X, "Y": Y, "Z": Z }) results_string = approximate_quantum_error(Kraus([E0, E1]), operator_string='pauli') results_list = approximate_quantum_error(Kraus([E0, E1]), operator_list=[X, Y, Z]) results_tuple = approximate_quantum_error(Kraus([E0, E1]), operator_list=(X, Y, Z)) self.assertErrorsAlmostEqual(results_dict, results_string) self.assertErrorsAlmostEqual(results_string, results_list) self.assertErrorsAlmostEqual(results_list, results_tuple)
def test_reset_2_qubit(self): # approximating amplitude damping using relaxation operators gamma = 0.23 p = (gamma - numpy.sqrt(1 - gamma) + 1) / 2 q = 0 A0 = [[1, 0], [0, numpy.sqrt(1 - gamma)]] A1 = [[0, numpy.sqrt(gamma)], [0, 0]] error_1 = QuantumError([([{'name': 'kraus', 'qubits': [0], 'params': [A0, A1]}, {'name': 'id', 'qubits': [1]} ], 1)]) error_2 = QuantumError([([{'name': 'kraus', 'qubits': [1], 'params': [A0, A1]}, {'name': 'id', 'qubits': [0]} ], 1)]) expected_results_1 = QuantumError([ ([{'name': 'id', 'qubits': [0]}, {'name': 'id', 'qubits': [1]}], 1-p), ([{'name': 'reset', 'qubits': [0]}, {'name': 'id', 'qubits': [1]}],p), ]) expected_results_2 = QuantumError([ ([{'name': 'id', 'qubits': [1]}, {'name': 'id', 'qubits': [0]}], 1 - p), ([{'name': 'reset', 'qubits': [1]}, {'name': 'id', 'qubits': [0]}], p), ]) results_1 = approximate_quantum_error(error_1, operator_string="reset") results_2 = approximate_quantum_error(error_2, operator_string="reset") self.assertErrorsAlmostEqual(results_1, expected_results_1) self.assertErrorsAlmostEqual(results_2, expected_results_2)
def test_approx_random_unitary_channel(self): # run without raising any error noise = Kraus(random_unitary(2, seed=123)) for opstr in ['pauli', 'reset', 'clifford']: approximate_quantum_error(noise, operator_string=opstr) noise = Kraus(random_unitary(4, seed=123)) for opstr in ['pauli', 'reset']: approximate_quantum_error(noise, operator_string=opstr)
def test_errors(self): gamma = 0.23 error = amplitude_damping_error(gamma) # kraus error is legit, transform_channel_operators are not with self.assertRaisesRegex( TypeError, "takes 1 positional argument but 2 were given"): approximate_quantum_error(error, 7) with self.assertRaises(NoiseError): approximate_quantum_error(error, operator_string="seven")
def test_approx_random_unitary_channel_2q(self): noise = Kraus(random_unitary(4, seed=123)) for opstr in ['pauli']: new_result = approximate_quantum_error(noise, operator_string=opstr) old_result = self.old_approximate_quantum_error( noise, operator_string=opstr) self.assertEqual(new_result, old_result) for opstr in ['reset']: new_result = approximate_quantum_error(noise, operator_string=opstr) old_result = self.old_approximate_quantum_error( noise, operator_string=opstr) self.assertGreaterEqual(process_fidelity(noise, new_result), process_fidelity(noise, old_result))
def test_approx_random_mixed_unitary_channel_2q(self): noise1 = UnitaryGate(random_unitary(4, seed=123)) noise2 = UnitaryGate(random_unitary(4, seed=456)) noise = QuantumError([(noise1, 0.7), (noise2, 0.3)]) for opstr in ['pauli']: new_result = approximate_quantum_error(noise, operator_string=opstr) old_result = self.old_approximate_quantum_error( noise, operator_string=opstr) self.assertEqual(new_result, old_result) for opstr in ['reset']: new_result = approximate_quantum_error(noise, operator_string=opstr) old_result = self.old_approximate_quantum_error( noise, operator_string=opstr) self.assertGreaterEqual(process_fidelity(noise, new_result), process_fidelity(noise, old_result))
def test_clifford(self): x_p = 0.1 y_p = 0.2 z_p = 0.3 error = pauli_error([('X', x_p), ('Y', y_p), ('Z', z_p), ('I', 1 - (x_p + y_p + z_p))]) results = approximate_quantum_error(error, operator_string="clifford") self.assertErrorsAlmostEqual(error, results, places=1)
def test_reset(self): # approximating amplitude damping using relaxation operators gamma = 0.23 error = amplitude_damping_error(gamma) p = (gamma - numpy.sqrt(1 - gamma) + 1) / 2 q = 0 expected_results = reset_error(p, q) results = approximate_quantum_error(error, operator_string="reset") self.assertErrorsAlmostEqual(results, expected_results)
def test_paulis_1_and_2_qubits(self): probs = [0.5, 0.3, 0.2] paulis_1q = ['X', 'Y', 'Z'] paulis_2q = ['XI', 'YI', 'ZI'] error_1q = pauli_error(zip(paulis_1q, probs)) error_2q = pauli_error(zip(paulis_2q, probs)) results_1q = approximate_quantum_error(error_1q, operator_string="pauli") results_2q = approximate_quantum_error(error_2q, operator_string="pauli") self.assertErrorsAlmostEqual(error_1q, results_1q) self.assertErrorsAlmostEqual(error_2q, results_2q, places = 2) paulis_2q = ['XY', 'ZZ', 'YI'] error_2q = pauli_error(zip(paulis_2q, probs)) results_2q = approximate_quantum_error(error_2q, operator_string="pauli") self.assertErrorsAlmostEqual(error_2q, results_2q, places=2)
def test_transformation_by_kraus(self): gamma = 0.23 error = amplitude_damping_error(gamma) reset_to_0 = [ numpy.array([[1, 0], [0, 0]]), numpy.array([[0, 1], [0, 0]]) ] reset_to_1 = [ numpy.array([[0, 0], [1, 0]]), numpy.array([[0, 0], [0, 1]]) ] reset_kraus = [Kraus(reset_to_0), Kraus(reset_to_1)] actual = approximate_quantum_error(error, operator_list=reset_kraus) p = (1 + gamma - numpy.sqrt(1 - gamma)) / 2 expected_probs = [1 - p, p, 0] self.assertListAlmostEqual(expected_probs, actual.probabilities) with self.assertWarns(DeprecationWarning): approximate_quantum_error(error, operator_list=[reset_to_0, reset_to_1])
def test_reset_2_qubit(self): # approximating amplitude damping using relaxation operators gamma = 0.23 p = (gamma - numpy.sqrt(1 - gamma) + 1) / 2 A0 = [[1, 0], [0, numpy.sqrt(1 - gamma)]] A1 = [[0, numpy.sqrt(gamma)], [0, 0]] error_1 = QuantumError([([(Kraus([A0, A1]), [0]), (IGate(), [1])], 1)]) error_2 = QuantumError([([(Kraus([A0, A1]), [1]), (IGate(), [0])], 1)]) expected_results_1 = QuantumError([([(IGate(), [0]), (IGate(), [1])], 1 - p), ([(Reset(), [0]), (IGate(), [1])], p)]) expected_results_2 = QuantumError([([(IGate(), [1]), (IGate(), [0])], 1 - p), ([(Reset(), [1]), (IGate(), [0])], p)]) results_1 = approximate_quantum_error(error_1, operator_string="reset") results_2 = approximate_quantum_error(error_2, operator_string="reset") self.assertErrorsAlmostEqual(results_1, expected_results_1) self.assertErrorsAlmostEqual(results_2, expected_results_2)
def test_approx_random_mixed_unitary_channel_1q(self): noise1 = UnitaryGate(random_unitary(2, seed=123)) noise2 = UnitaryGate(random_unitary(2, seed=456)) noise = QuantumError([(noise1, 0.7), (noise2, 0.3)]) for opstr in ['pauli', 'reset']: new_result = approximate_quantum_error(noise, operator_string=opstr) old_result = self.old_approximate_quantum_error( noise, operator_string=opstr) self.assertEqual(new_result, old_result) for opstr in ['clifford']: # cannot compare due to error in old implementation with self.assertRaises(NoiseError): self.old_approximate_quantum_error(noise, operator_string=opstr)
def test_transformation_by_pauli(self): # polarization in the XY plane; we represent via Kraus operators X = self.ops['X'] Y = self.ops['Y'] Z = self.ops['Z'] p = 0.22 theta = numpy.pi / 5 E0 = numpy.sqrt(1 - p) * numpy.array(numpy.eye(2)) E1 = numpy.sqrt(p) * (numpy.cos(theta) * numpy.array(X) + numpy.sin(theta) * numpy.array(Y)) results = approximate_quantum_error(Kraus([E0, E1]), operator_dict={ "X": X, "Y": Y, "Z": Z }) expected_results = pauli_error([ ('X', p * numpy.cos(theta) * numpy.cos(theta)), ('Y', p * numpy.sin(theta) * numpy.sin(theta)), ('Z', 0), ('I', 1 - p) ]) self.assertErrorsAlmostEqual(expected_results, results)
def test_approx_names(self): gamma = 0.23 error = amplitude_damping_error(gamma) results_1 = approximate_quantum_error(error, operator_string="pauli") results_2 = approximate_quantum_error(error, operator_string="Pauli") self.assertErrorsAlmostEqual(results_1, results_2)