def test_multiply(self): """Test multiply method.""" chan = PTM(self.ptmI) val = 0.5 targ = PTM(val * self.ptmI) self.assertEqual(chan._multiply(val), targ) self.assertEqual(val * chan, targ)
def test_copy(self): """Test copy method""" mat = np.eye(4) orig = PTM(mat) cpy = orig.copy() cpy._data[0, 0] = 0.0 self.assertFalse(cpy == orig)
def test_subtract(self): """Test subtract method.""" mat1 = 0.5 * self.ptmI mat2 = 0.5 * self.depol_ptm(1) targ = PTM(mat1 - mat2) chan1 = PTM(mat1) chan2 = PTM(mat2) self.assertEqual(chan1.subtract(chan2), targ) self.assertEqual(chan1 - chan2, targ)
def test_add(self): """Test add method.""" mat1 = 0.5 * self.ptmI mat2 = 0.5 * self.depol_ptm(1) targ = PTM(mat1 + mat2) chan1 = PTM(mat1) chan2 = PTM(mat2) self.assertEqual(chan1.add(chan2), targ) self.assertEqual(chan1 + chan2, targ)
def test_tensor(self): """Test tensor method.""" rho0, rho1 = np.diag([1, 0]), np.diag([0, 1]) rho_init = DensityMatrix(np.kron(rho0, rho0)) chan1 = PTM(self.ptmI) chan2 = PTM(self.ptmX) # X \otimes I chan = chan2.tensor(chan1) rho_targ = DensityMatrix(np.kron(rho1, rho0)) self.assertEqual(chan.dim, (4, 4)) self.assertEqual(rho_init.evolve(chan), rho_targ) # I \otimes X chan = chan1.tensor(chan2) rho_targ = DensityMatrix(np.kron(rho0, rho1)) self.assertEqual(chan.dim, (4, 4)) self.assertEqual(rho_init.evolve(chan), rho_targ) # Completely depolarizing chan_dep = PTM(self.depol_ptm(1)) chan = chan_dep.tensor(chan_dep) rho_targ = DensityMatrix(np.diag([1, 1, 1, 1]) / 4) self.assertEqual(chan.dim, (4, 4)) self.assertEqual(rho_init.evolve(chan), rho_targ)
def test_expand(self): """Test expand method.""" rho0, rho1 = np.diag([1, 0]), np.diag([0, 1]) rho_init = np.kron(rho0, rho0) chan1 = PTM(self.ptmI) chan2 = PTM(self.ptmX) # X \otimes I chan = chan1.expand(chan2) rho_targ = np.kron(rho1, rho0) self.assertEqual(chan.dim, (4, 4)) self.assertAllClose(chan._evolve(rho_init), rho_targ) # I \otimes X chan = chan2.expand(chan1) rho_targ = np.kron(rho0, rho1) self.assertEqual(chan.dim, (4, 4)) self.assertAllClose(chan._evolve(rho_init), rho_targ) # Completely depolarizing chan_dep = PTM(self.depol_ptm(1)) chan = chan_dep.expand(chan_dep) rho_targ = np.diag([1, 1, 1, 1]) / 4 self.assertEqual(chan.dim, (4, 4)) self.assertAllClose(chan._evolve(rho_init), rho_targ)
def test_power(self): """Test power method.""" # 10% depolarizing channel p_id = 0.9 depol = PTM(self.depol_ptm(1 - p_id)) # Compose 3 times p_id3 = p_id**3 chan3 = depol.power(3) targ3 = PTM(self.depol_ptm(1 - p_id3)) self.assertEqual(chan3, targ3)
def test_copy(self): """Test copy method""" mat = np.eye(4) with self.subTest("Deep copy"): orig = PTM(mat) cpy = orig.copy() cpy._data[0, 0] = 0.0 self.assertFalse(cpy == orig) with self.subTest("Shallow copy"): orig = PTM(mat) clone = copy.copy(orig) clone._data[0, 0] = 0.0 self.assertTrue(clone == orig)
def test_multiply_except(self): """Test multiply method raises exceptions.""" chan = PTM(self.ptmI) self.assertRaises(QiskitError, chan._multiply, 's') self.assertRaises(QiskitError, chan.__rmul__, 's') self.assertRaises(QiskitError, chan._multiply, chan) self.assertRaises(QiskitError, chan.__rmul__, chan)
def test_clone(self): """Test clone method""" mat = np.eye(4) orig = PTM(mat) clone = copy.copy(orig) clone._data[0, 0] = 0.0 self.assertTrue(clone == orig)
def qchannel_to_qiskit(representation): """ Create a qiskit representation of quantum channel from a myqlm representation of a quantum channel. Args: representation: (QuantumChannel) myqlm representation of a quantum channel. Returns: (Kraus|Choi|Chi|SuperOp|PTM): qiskit representation of a quantum channel. """ rep = representation.representation # Find what representation it is. # Then create the corresponding matrix and shape it like qiskit is expecting it. # Finally, create the qiskit representation from that matrix. if rep in (RepresentationType.PTM, RepresentationType.CHOI): matri = representation.matrix data_re = [] data_im = [] for i in range(matri.nRows): for j in range(matri.nCols): data_re.append(matri.data[i * matri.nRows + j].re + 0.j) data_im.append(matri.data[i * matri.nRows + j].im) data = np.array(data_re) data.imag = np.array(data_im) data = data.reshape((matri.nRows, matri.nCols)) return PTM(data) if (rep == RepresentationType.PTM) else Choi(data) if rep in (RepresentationType.CHI, RepresentationType.SUPEROP): final_data = [] for matri in representation.basis: data_re = [] data_im = [] for i in range(matri.nRows): for j in range(matri.nCols): data_re.append(matri.data[i * matri.nRows + j].re + 0.j) data_im.append(matri.data[i * matri.nRows + j].im) data = np.array(data_re) data.imag = np.array(data_im) data = data.reshape((matri.nRows, matri.nCols)) final_data.append(data) if rep == RepresentationType.CHI: return Chi(final_data) if len(final_data) > 1 else Chi(final_data[0]) return SuperOp(final_data) if len(final_data) > 1 else SuperOp(final_data[0]) if rep == RepresentationType.KRAUS: final_data = [] for matri in representation.kraus_ops: data_re = [] data_im = [] for i in range(matri.nRows): for j in range(matri.nCols): data_re.append(matri.data[i * matri.nRows + j].re + 0.j) data_im.append(matri.data[i * matri.nRows + j].im) data = np.array(data_re) data.imag = np.array(data_im) data = data.reshape((matri.nRows, matri.nCols)) final_data.append(data) return Kraus(final_data) return None
def test_init(self): """Test initialization""" mat4 = np.eye(4) / 2.0 chan = PTM(mat4) self.assertAllClose(chan.data, mat4) self.assertEqual(chan.dim, (2, 2)) mat16 = np.eye(16) / 4 chan = PTM(mat16) self.assertAllClose(chan.data, mat16) self.assertEqual(chan.dim, (4, 4)) # Wrong input or output dims should raise exception self.assertRaises(QiskitError, PTM, mat16, input_dims=2, output_dims=4) # Non multi-qubit dimensions should raise exception self.assertRaises( QiskitError, PTM, np.eye(6) / 2, input_dims=3, output_dims=2)
def test_from_qiskit(self): """ Test quantum channels created from qiskit are equals to quantum channels created by qiskit -> to myqlm -> to qiskit """ circuit = QuantumCircuit(3) circuit.h(0) circuit.cx(0, 1) circuit.x(2) self.assertEqual( Kraus(circuit), qchannel_to_qiskit(qiskit_to_qchannel(Kraus(circuit)))) self.assertEqual(Chi(circuit), qchannel_to_qiskit(qiskit_to_qchannel(Chi(circuit)))) self.assertEqual(Choi(circuit), qchannel_to_qiskit(qiskit_to_qchannel(Choi(circuit)))) self.assertEqual( SuperOp(circuit), qchannel_to_qiskit(qiskit_to_qchannel(SuperOp(circuit)))) self.assertEqual(PTM(circuit), qchannel_to_qiskit(qiskit_to_qchannel(PTM(circuit))))
def test_dot(self): """Test dot method.""" # Random input test state rho = DensityMatrix(self.rand_rho(2)) # UnitaryChannel evolution chan1 = PTM(self.ptmX) chan2 = PTM(self.ptmY) rho_targ = rho.evolve(PTM(self.ptmZ)) self.assertEqual(rho.evolve(chan2.dot(chan1)), rho_targ) # Compose random ptm1 = self.rand_matrix(4, 4, real=True) ptm2 = self.rand_matrix(4, 4, real=True) chan1 = PTM(ptm1, input_dims=2, output_dims=2) chan2 = PTM(ptm2, input_dims=2, output_dims=2) rho_targ = rho.evolve(chan1).evolve(chan2) self.assertEqual(rho.evolve(chan2.dot(chan1)), rho_targ)
def test_from_myqlm_ptm(self): """ Test all combinations of ptm quantum channel between myqlm and qiskit """ arr = np.arange(4 * 4, dtype=complex).reshape((4, 4)) matri = array_to_matrix(arr) qchannel = QuantumChannel(representation=RepresentationType.PTM, arity=1, matrix=matri) qiskit_qchannel = PTM(arr) self.assertEqual(qchannel, qiskit_to_qchannel(qchannel_to_qiskit(qchannel))) self.assertEqual(qiskit_qchannel, qchannel_to_qiskit(qchannel)) self.assertEqual(qchannel, qiskit_to_qchannel(qiskit_qchannel))
def test_compose_front(self): """Test deprecated front compose method.""" # Random input test state rho = DensityMatrix(self.rand_rho(2)) # UnitaryChannel evolution chan1 = PTM(self.ptmX) chan2 = PTM(self.ptmY) chan = chan2.compose(chan1, front=True) rho_targ = rho.evolve(PTM(self.ptmZ)) self.assertEqual(rho.evolve(chan), rho_targ) # Compose random ptm1 = self.rand_matrix(4, 4, real=True) ptm2 = self.rand_matrix(4, 4, real=True) chan1 = PTM(ptm1, input_dims=2, output_dims=2) chan2 = PTM(ptm2, input_dims=2, output_dims=2) rho_targ = rho.evolve(chan1).evolve(chan2) chan = chan2.compose(chan1, front=True) self.assertEqual(chan.dim, (2, 2)) self.assertEqual(rho.evolve(chan), rho_targ)
def test_equal(self): """Test __eq__ method""" mat = self.rand_matrix(4, 4, real=True) self.assertEqual(PTM(mat), PTM(mat))
def test_circuit_init(self): """Test initialization from a circuit.""" circuit, target = self.simple_circuit_no_measure() op = PTM(circuit) target = PTM(target) self.assertEqual(op, target)
def test_negate(self): """Test negate method""" chan = PTM(self.ptmI) targ = PTM(-self.ptmI) self.assertEqual(-chan, targ)
def test_compose(self): """Test compose method.""" # Random input test state rho = self.rand_rho(2) # UnitaryChannel evolution chan1 = PTM(self.ptmX) chan2 = PTM(self.ptmY) chan = chan1.compose(chan2) targ = PTM(self.ptmZ)._evolve(rho) self.assertAllClose(chan._evolve(rho), targ) # 50% depolarizing channel chan1 = PTM(self.depol_ptm(0.5)) chan = chan1.compose(chan1) targ = PTM(self.depol_ptm(0.75))._evolve(rho) self.assertAllClose(chan._evolve(rho), targ) # Compose random ptm1 = self.rand_matrix(4, 4, real=True) ptm2 = self.rand_matrix(4, 4, real=True) chan1 = PTM(ptm1, input_dims=2, output_dims=2) chan2 = PTM(ptm2, input_dims=2, output_dims=2) targ = chan2._evolve(chan1._evolve(rho)) chan = chan1.compose(chan2) self.assertEqual(chan.dim, (2, 2)) self.assertAllClose(chan._evolve(rho), targ) chan = chan1 @ chan2 self.assertEqual(chan.dim, (2, 2)) self.assertAllClose(chan._evolve(rho), targ)
def test_add_except(self): """Test add method raises exceptions.""" chan1 = PTM(self.ptmI) chan2 = PTM(np.eye(16)) self.assertRaises(QiskitError, chan1._add, chan2) self.assertRaises(QiskitError, chan1._add, 5)
def test_sub_qargs(self): """Test subtract method with qargs.""" mat = self.rand_matrix(8**2, 8**2) mat0 = self.rand_matrix(4, 4) mat1 = self.rand_matrix(4, 4) op = PTM(mat) op0 = PTM(mat0) op1 = PTM(mat1) op01 = op1.tensor(op0) eye = PTM(self.ptmI) with self.subTest(msg='qargs=[0]'): value = op - op0([0]) target = op - eye.tensor(eye).tensor(op0) self.assertEqual(value, target) with self.subTest(msg='qargs=[1]'): value = op - op0([1]) target = op - eye.tensor(op0).tensor(eye) self.assertEqual(value, target) with self.subTest(msg='qargs=[2]'): value = op - op0([2]) target = op - op0.tensor(eye).tensor(eye) self.assertEqual(value, target) with self.subTest(msg='qargs=[0, 1]'): value = op - op01([0, 1]) target = op - eye.tensor(op1).tensor(op0) self.assertEqual(value, target) with self.subTest(msg='qargs=[1, 0]'): value = op - op01([1, 0]) target = op - eye.tensor(op0).tensor(op1) self.assertEqual(value, target) with self.subTest(msg='qargs=[0, 2]'): value = op - op01([0, 2]) target = op - op1.tensor(eye).tensor(op0) self.assertEqual(value, target) with self.subTest(msg='qargs=[2, 0]'): value = op - op01([2, 0]) target = op - op0.tensor(eye).tensor(op1) self.assertEqual(value, target)
def test_compose_front(self): """Test front compose method.""" # Random input test state rho = self.rand_rho(2) # UnitaryChannel evolution chan1 = PTM(self.ptmX) chan2 = PTM(self.ptmY) chan = chan2.compose(chan1, front=True) targ = PTM(self.ptmZ)._evolve(rho) self.assertAllClose(chan._evolve(rho), targ) # Compose random ptm1 = self.rand_matrix(4, 4, real=True) ptm2 = self.rand_matrix(4, 4, real=True) chan1 = PTM(ptm1, input_dims=2, output_dims=2) chan2 = PTM(ptm2, input_dims=2, output_dims=2) targ = chan2._evolve(chan1._evolve(rho)) chan = chan2.compose(chan1, front=True) self.assertEqual(chan.dim, (2, 2)) self.assertAllClose(chan._evolve(rho), targ)
def test_subtract_except(self): """Test subtract method raises exceptions.""" chan1 = PTM(self.ptmI) chan2 = PTM(np.eye(16)) self.assertRaises(QiskitError, chan1.subtract, chan2) self.assertRaises(QiskitError, chan1.subtract, 5)
def test_evolve(self): """Test evolve method.""" input_psi = [0, 1] input_rho = [[0, 0], [0, 1]] # Identity channel chan = PTM(self.ptmI) target_rho = np.array([[0, 0], [0, 1]]) self.assertAllClose(chan._evolve(input_psi), target_rho) self.assertAllClose(chan._evolve(np.array(input_psi)), target_rho) self.assertAllClose(chan._evolve(input_rho), target_rho) self.assertAllClose(chan._evolve(np.array(input_rho)), target_rho) # Hadamard channel chan = PTM(self.ptmH) target_rho = np.array([[1, -1], [-1, 1]]) / 2 self.assertAllClose(chan._evolve(input_psi), target_rho) self.assertAllClose(chan._evolve(np.array(input_psi)), target_rho) self.assertAllClose(chan._evolve(input_rho), target_rho) self.assertAllClose(chan._evolve(np.array(input_rho)), target_rho) # Completely depolarizing channel chan = PTM(self.depol_ptm(1)) target_rho = np.eye(2) / 2 self.assertAllClose(chan._evolve(input_psi), target_rho) self.assertAllClose(chan._evolve(np.array(input_psi)), target_rho) self.assertAllClose(chan._evolve(input_rho), target_rho) self.assertAllClose(chan._evolve(np.array(input_rho)), target_rho)
def test_is_cptp(self): """Test is_cptp method.""" self.assertTrue(PTM(self.depol_ptm(0.25)).is_cptp()) # Non-CPTP should return false self.assertFalse( PTM(1.25 * self.ptmI - 0.25 * self.depol_ptm(1)).is_cptp())
def test_power_except(self): """Test power method raises exceptions.""" chan = PTM(self.depol_ptm(1)) # Non-integer power raises error self.assertRaises(QiskitError, chan.power, 0.5)
def test_compose_except(self): """Test compose different dimension exception""" self.assertRaises(QiskitError, PTM(np.eye(4)).compose, PTM(np.eye(16))) self.assertRaises(QiskitError, PTM(np.eye(4)).compose, 2)
def test_compose(self): """Test compose method.""" # Random input test state rho = DensityMatrix(self.rand_rho(2)) # UnitaryChannel evolution chan1 = PTM(self.ptmX) chan2 = PTM(self.ptmY) chan = chan1.compose(chan2) rho_targ = rho.evolve(PTM(self.ptmZ)) self.assertEqual(rho.evolve(chan), rho_targ) # 50% depolarizing channel chan1 = PTM(self.depol_ptm(0.5)) chan = chan1.compose(chan1) rho_targ = rho.evolve(PTM(self.depol_ptm(0.75))) self.assertEqual(rho.evolve(chan), rho_targ) # Compose random ptm1 = self.rand_matrix(4, 4, real=True) ptm2 = self.rand_matrix(4, 4, real=True) chan1 = PTM(ptm1, input_dims=2, output_dims=2) chan2 = PTM(ptm2, input_dims=2, output_dims=2) rho_targ = rho.evolve(chan1).evolve(chan2) chan = chan1.compose(chan2) self.assertEqual(chan.dim, (2, 2)) self.assertEqual(rho.evolve(chan), rho_targ) chan = chan1 & chan2 self.assertEqual(chan.dim, (2, 2)) self.assertEqual(rho.evolve(chan), rho_targ)