def test_multiply(self): """Test multiply method.""" # Random initial state and Stinespring ops rho_init = DensityMatrix(self.rand_rho(2)) val = 0.5 stine1, stine2 = self.rand_matrix(16, 2), self.rand_matrix(16, 2) # Single Stinespring set chan1 = Stinespring(stine1, input_dims=2, output_dims=4) rho_targ = val * (rho_init & chan1) chan = chan1._multiply(val) self.assertEqual(rho_init.evolve(chan), rho_targ) chan = val * chan1 self.assertEqual(rho_init.evolve(chan), rho_targ) # Double Stinespring set chan2 = Stinespring((stine1, stine2), input_dims=2, output_dims=4) rho_targ = val * (rho_init & chan2) chan = chan2._multiply(val) self.assertEqual(rho_init.evolve(chan), rho_targ) chan = val * chan2 self.assertEqual(rho_init.evolve(chan), rho_targ)
def test_compose_front(self): """Test front compose method.""" # Random input test state rho = DensityMatrix(self.rand_rho(2)) # UnitaryChannel evolution chan1 = Chi(self.chiX) chan2 = Chi(self.chiY) chan = chan2.compose(chan1, front=True) target = rho.evolve(Chi(self.chiZ)) output = rho.evolve(chan) self.assertEqual(output, target) # Compose random chi1 = self.rand_matrix(4, 4, real=True) chi2 = self.rand_matrix(4, 4, real=True) chan1 = Chi(chi1, input_dims=2, output_dims=2) chan2 = Chi(chi2, input_dims=2, output_dims=2) target = rho.evolve(chan1).evolve(chan2) chan = chan2.compose(chan1, front=True) output = rho.evolve(chan) self.assertEqual(chan.dim, (2, 2)) self.assertEqual(output, target)
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 = SuperOp(self.sopI) chan2 = SuperOp(self.sopX) # 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) chan = chan2 ^ chan1 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) chan = chan1 ^ chan2 self.assertEqual(chan.dim, (4, 4)) self.assertEqual(rho_init.evolve(chan), rho_targ)
def test_evolve_subsystem(self): """Test subsystem evolve method for operators.""" # Test evolving single-qubit of 3-qubit system for _ in range(5): rho = self.rand_rho(8) state = DensityMatrix(rho) op0 = random_unitary(2) op1 = random_unitary(2) op2 = random_unitary(2) # Test evolve on 1-qubit op = op0 op_full = Operator(np.eye(4)).tensor(op) target = DensityMatrix(np.dot(op_full.data, rho).dot(op_full.adjoint().data)) self.assertEqual(state.evolve(op, qargs=[0]), target) # Evolve on qubit 1 op_full = Operator(np.eye(2)).tensor(op).tensor(np.eye(2)) target = DensityMatrix(np.dot(op_full.data, rho).dot(op_full.adjoint().data)) self.assertEqual(state.evolve(op, qargs=[1]), target) # Evolve on qubit 2 op_full = op.tensor(np.eye(4)) target = DensityMatrix(np.dot(op_full.data, rho).dot(op_full.adjoint().data)) self.assertEqual(state.evolve(op, qargs=[2]), target) # Test evolve on 2-qubits op = op1.tensor(op0) # Evolve on qubits [0, 2] op_full = op1.tensor(np.eye(2)).tensor(op0) target = DensityMatrix(np.dot(op_full.data, rho).dot(op_full.adjoint().data)) self.assertEqual(state.evolve(op, qargs=[0, 2]), target) # Evolve on qubits [2, 0] op_full = op0.tensor(np.eye(2)).tensor(op1) target = DensityMatrix(np.dot(op_full.data, rho).dot(op_full.adjoint().data)) self.assertEqual(state.evolve(op, qargs=[2, 0]), target) # Test evolve on 3-qubits op = op2.tensor(op1).tensor(op0) # Evolve on qubits [0, 1, 2] op_full = op target = DensityMatrix(np.dot(op_full.data, rho).dot(op_full.adjoint().data)) self.assertEqual(state.evolve(op, qargs=[0, 1, 2]), target) # Evolve on qubits [2, 1, 0] op_full = op0.tensor(op1).tensor(op2) target = DensityMatrix(np.dot(op_full.data, rho).dot(op_full.adjoint().data)) self.assertEqual(state.evolve(op, qargs=[2, 1, 0]), target)
def test_expand(self): """Test expand method.""" # Pauli channels paulis = [self.chiI, self.chiX, self.chiY, self.chiZ] targs = 4 * np.eye(16) # diagonals of Pauli channel Chi mats for i, chi1 in enumerate(paulis): for j, chi2 in enumerate(paulis): chan1 = Chi(chi1) chan2 = Chi(chi2) chan = chan1.expand(chan2) # Target for diagonal Pauli channel targ = Chi(np.diag(targs[i + 4 * j])) self.assertEqual(chan.dim, (4, 4)) self.assertEqual(chan, targ) # Completely depolarizing rho = DensityMatrix(np.diag([1, 0, 0, 0])) chan_dep = Chi(self.depol_chi(1)) chan = chan_dep.expand(chan_dep) target = DensityMatrix(np.diag([1, 1, 1, 1]) / 4) output = rho.evolve(chan) self.assertEqual(chan.dim, (4, 4)) self.assertEqual(output, target)
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) self.assertEqual(rho.evolve(chan2 * 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) self.assertEqual(rho.evolve(chan2 * chan1), rho_targ)
def test_dot(self): """Test dot method.""" # Random input test state rho = DensityMatrix(self.rand_rho(2)) # UnitaryChannel evolution chan1 = Chi(self.chiX) chan2 = Chi(self.chiY) target = rho.evolve(Chi(self.chiZ)) output = rho.evolve(chan2.dot(chan1)) self.assertEqual(output, target) output = rho.evolve(chan2 * chan1) self.assertEqual(output, target) # Compose random chi1 = self.rand_matrix(4, 4, real=True) chi2 = self.rand_matrix(4, 4, real=True) chan1 = Chi(chi1, input_dims=2, output_dims=2) chan2 = Chi(chi2, input_dims=2, output_dims=2) target = rho.evolve(chan1).evolve(chan2) output = rho.evolve(chan2.dot(chan1)) self.assertEqual(output, target) output = rho.evolve(chan2 * chan1) self.assertEqual(output, target)
def test_evolve_subsystem(self): """Test subsystem evolve method.""" # Single-qubit random superoperators op_a = SuperOp(self.rand_matrix(4, 4)) op_b = SuperOp(self.rand_matrix(4, 4)) op_c = SuperOp(self.rand_matrix(4, 4)) id1 = SuperOp(np.eye(4)) id2 = SuperOp(np.eye(16)) rho = DensityMatrix(self.rand_rho(8)) # Test evolving single-qubit of 3-qubit system op = op_a # Evolve on qubit 0 full_op = id2.tensor(op_a) rho_targ = rho.evolve(full_op) rho_test = rho.evolve(op, qargs=[0]) self.assertEqual(rho_test, rho_targ) # Evolve on qubit 1 full_op = id1.tensor(op_a).tensor(id1) rho_targ = rho.evolve(full_op) rho_test = rho.evolve(op, qargs=[1]) self.assertEqual(rho_test, rho_targ) # Evolve on qubit 2 full_op = op_a.tensor(id2) rho_targ = rho.evolve(full_op) rho_test = rho.evolve(op, qargs=[2]) self.assertEqual(rho_test, rho_targ) # Test 2-qubit evolution op = op_b.tensor(op_a) # Evolve on qubits [0, 2] full_op = op_b.tensor(id1).tensor(op_a) rho_targ = rho.evolve(full_op) rho_test = rho.evolve(op, qargs=[0, 2]) self.assertEqual(rho_test, rho_targ) # Evolve on qubits [2, 0] full_op = op_a.tensor(id1).tensor(op_b) rho_targ = rho.evolve(full_op) rho_test = rho.evolve(op, qargs=[2, 0]) self.assertEqual(rho_test, rho_targ) # Test 3-qubit evolution op = op_c.tensor(op_b).tensor(op_a) # Evolve on qubits [0, 1, 2] full_op = op rho_targ = rho.evolve(full_op) rho_test = rho.evolve(op, qargs=[0, 1, 2]) self.assertEqual(rho_test, rho_targ) # Evolve on qubits [2, 1, 0] full_op = op_a.tensor(op_b).tensor(op_c) rho_targ = rho.evolve(full_op) rho_test = rho.evolve(op, qargs=[2, 1, 0]) self.assertEqual(rho_test, rho_targ)
def test_negate(self): """Test negate method""" rho_init = DensityMatrix(np.diag([1, 0])) rho_targ = DensityMatrix(np.diag([-0.5, -0.5])) chan = -Stinespring(self.depol_stine(1)) self.assertEqual(rho_init.evolve(chan), rho_targ)