def test_composite_map(self): X = ch.QuantumChannel(ch._sigmaX, 'unitary') I = ch.QuantumChannel(ch._sigmaX, 'unitary') tot = (X ^ X) * (I ^ X) zero = np.zeros((2, 2)) zero[1, 1] = 0 pz = ch.QuantumState(zero, 'dm') one = np.zeros((2, 2)) one[1, 1] = 0 po = ch.QuantumState(one, 'dm') out = np.kron(one, one) out1 = tot * (pz ^ po) out2 = (X * I * pz) ^ (X * X * po) out3 = po ^ po err1 = la.norm(out1.density_matrix() - out) err2 = la.norm(out2.density_matrix() - out) err3 = la.norm(out3.density_matrix() - out) self.assertEqual(err1, 0) self.assertEqual(err2, 0) self.assertEqual(err3, 0)
def test_bv_to_bv(self): bv = np.random.rand(3, 1) if la.norm(bv) > 1: bv = bv / la.norm(bv) self.assertLessEqual(la.norm(bv), 1.) p = ch.QuantumState(bv, 'bv') err1 = la.norm(bv - p.bloch_vector()) self.assertEqual(err1, 0) dv = p.density_vector() p2 = ch.QuantumState(dv, 'dv') err2 = la.norm(bv - p2.bloch_vector()) self.assertAlmostEqual(err2, 0) dm = p.density_matrix() p3 = ch.QuantumState(dm) err3 = la.norm(bv - p3.bloch_vector()) self.assertAlmostEqual(err3, 0) self.assertEqual(err2, err2) w, b = p.state_mixture() p4 = ch.QuantumState((w, b), 'sm') err4 = la.norm(bv - p4.bloch_vector())
def test_dv_to_dv(self): G = np.random.randn(2, 2) + 1j * np.random.randn(2, 2) Q, R = la.qr(G) d = np.random.rand(2) d = d / np.sum(d) Q = np.array(Q) dm = np.dot(Q, np.dot(np.diag(d), Q.conj().T)) dv = ch._vec(dm) p = ch.QuantumState(dv, 'dv') err1 = la.norm(dv - p.density_vector()) self.assertEqual(err1, 0) dm = p.density_matrix() p2 = ch.QuantumState(dm, 'dm') err2 = la.norm(dv - p2.density_vector()) self.assertEqual(err2, 0) bv = p.bloch_vector() self.assertLessEqual(la.norm(bv), 1.) p3 = ch.QuantumState(bv, 'bv') err3 = la.norm(dv - p3.density_vector()) self.assertAlmostEqual(err3, 0, 12) w, b = p.state_mixture() p4 = ch.QuantumState((w, b), 'sm') err4 = la.norm(dv - p4.density_vector()) self.assertAlmostEqual(err4, 0, 12)
def test_CNOT(self): cnot_mat = np.array( [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]], dtype=complex) CNOT = ch.QuantumChannel(cnot_mat, 'unitary') zero = np.zeros((2, 2)) zero[1, 1] = 0 pz = ch.QuantumState(zero, 'dm') one = np.zeros((2, 2)) one[1, 1] = 0 po = ch.QuantumState(one, 'dm') out00 = CNOT * (pz ^ pz) out01 = CNOT * (pz ^ po) out10 = CNOT * (po ^ pz) out11 = CNOT * (po ^ po) err1 = out00.density_matrix() - (pz ^ pz).density_matrix() err2 = out01.density_matrix() - (pz ^ po).density_matrix() err3 = out10.density_matrix() - (po ^ po).density_matrix() err4 = out11.density_matrix() - (po ^ pz).density_matrix() self.assertEqual(la.norm(err1), 0) self.assertEqual(la.norm(err2), 0) self.assertEqual(la.norm(err3), 0) self.assertEqual(la.norm(err4), 0)
def test_bv_dtype(self): D = ch.QuantumState(np.eye(3)[:, 0], 'bv') self.assertEqual(type(D._bv.bloch_vector), type(np.array([]))) #Changed Type self.assertEqual(D._bv.bloch_vector.dtype, np.float64) D = ch.QuantumState(np.eye(3, dtype=np.complex128)[:, 0], 'bv') self.assertEqual(type(D._bv.bloch_vector), type(np.array([]))) #Changed Type self.assertEqual(D._bv.bloch_vector.dtype, np.float64) self.assertEqual(type(D.bloch_vector()), type(np.array([]))) #Changed Type self.assertEqual(D.bloch_vector().dtype, np.float64) self.assertEqual(type(D.density_vector()), type(np.array([]))) #Changed Type self.assertEqual(D.density_vector().dtype, np.complex128) self.assertEqual(type(D.density_matrix()), type(np.array([]))) #Changed Type self.assertEqual(D.density_matrix().dtype, np.complex128) w, b = D.state_mixture() self.assertEqual(type(w), np.ndarray) self.assertEqual(w.dtype, np.float64) self.assertTrue(all([type(bb) == type(np.array([])) for bb in b])) #Changed Type self.assertTrue(all([bb.dtype == np.complex128 for bb in b]))
def test_dm_dtype(self): D = ch.QuantumState(np.eye(2, dtype=np.complex128) * .5, 'dm') self.assertEqual(type(D._dm.density_matrix), type(np.array([]))) #Changed Type self.assertEqual(D._dm.density_matrix.dtype, np.complex128) D = ch.QuantumState(np.eye(2) * .5, 'dm') self.assertEqual(type(D._dm.density_matrix), type(np.array([]))) #Changed Type self.assertEqual(D._dm.density_matrix.dtype, np.complex128) self.assertEqual(type(D.density_matrix()), type(np.array([]))) #Changed Type self.assertEqual(D.density_matrix().dtype, np.complex128) self.assertEqual(type(D.density_vector()), type(np.array([]))) #Changed Type self.assertEqual(D.density_vector().dtype, np.complex128) self.assertEqual(type(D.bloch_vector()), type(np.array([]))) #Changed Type self.assertEqual(D.bloch_vector().dtype, np.float64) w, b = D.state_mixture() self.assertEqual(type(w), np.ndarray) self.assertEqual(w.dtype, np.float64) self.assertTrue(all([type(bb) == type(np.array([])) for bb in b])) #Changed Type self.assertTrue(all([bb.dtype == np.complex128 for bb in b]))
def test_bv_to_dm(self): p = ch.QuantumState(np.array(np.zeros((3, 1))), 'bv') err = la.norm(p.density_matrix() - np.eye(2) / 2.) self.assertEqual(err, 0.) p = ch.QuantumState(np.array([[1], [0], [0]]), 'bv') err = la.norm(p.density_matrix() - .5 * (ch._sigmaX + ch._sigmaI)) self.assertEqual(err, 0.)
def test_sm_to_sm(self): G = np.random.randn(2, 2) + 1j * np.random.randn(2, 2) Q, R = la.qr(G) d = np.random.rand(2) d = d / np.sum(d) Q = np.array(Q) dm = np.dot(Q, np.dot(np.diag(d), Q.conj().T)) w, b = la.eigh(dm) b = [b[:, i][:, np.newaxis] for i in range(b.shape[1])] self.assertAlmostEqual(np.sum(w), 1, 12) p = ch.QuantumState((w, b), 'sm') ww, bb = p.state_mixture() weq = [np.min(np.abs(w1 - ww)) for w1 in w] beq = [np.min([la.norm(b1 - b2) for b2 in bb]) for b1 in b] self.assertEqual(la.norm(weq), 0) self.assertEqual(la.norm(beq), 0) dm = p.density_matrix() p2 = ch.QuantumState(dm, 'dm') ww, bb = p2.state_mixture() weq = [np.min(np.abs(w1 - ww)) for w1 in w] beq = [np.min([la.norm(b1 - b2) for b2 in bb]) for b1 in b] self.assertAlmostEqual(la.norm(weq), 0, 12) self.assertAlmostEqual(la.norm(beq), 0, 12) dv = p.density_vector() p3 = ch.QuantumState(dv, 'dv') ww, bb = p3.state_mixture() weq = [np.min(np.abs(w1 - ww)) for w1 in w] beq = [np.min([la.norm(b1 - b2) for b2 in bb]) for b1 in b] self.assertAlmostEqual(la.norm(weq), 0, 12) self.assertAlmostEqual(la.norm(beq), 0, 12) bv = p.density_vector() p4 = ch.QuantumState(bv, 'dv') ww, bb = p4.state_mixture() weq = [np.min(np.abs(w1 - ww)) for w1 in w] beq = [np.min([la.norm(b1 - b2) for b2 in bb]) for b1 in b] self.assertAlmostEqual(la.norm(weq), 0, 12) self.assertAlmostEqual(la.norm(beq), 0, 12)
def test_partial_trace(self): p0 = np.zeros((2, 2)) p1 = np.zeros((2, 2)) p0[0, 0] = 1 p1[1, 1] = 1 outA = (ch.QuantumState(p0) ^ ch.QuantumState(p1)).TrB() outB = (ch.QuantumState(p0) ^ ch.QuantumState(p1)).TrA() self.assertEqual(la.norm(outA.density_matrix() - p0), 0) self.assertEqual(la.norm(outB.density_matrix() - p1), 0)
def test_missing_inits(self): s = ch.QuantumState([[1, 0, 0, 0]], 'dv') self.assertTrue(s.density_vector().shape[0] == 4 and s.density_vector().shape[1] == 1) s = ch.QuantumState([[1, 0, 0, 0]], 'bv') self.assertTrue(s.bloch_vector().shape[0] == 4 and s.bloch_vector().shape[1] == 1) s = ch.QuantumState([[.5, .5], [[1, 0], [0, 1]]], 'sm') self.assertTrue(s.state_mixture()[1][0].shape[0] == 2 and s.state_mixture()[1][0].shape[1] == 1)
def test_rank_sm(self): s = [.5 - 1e-13, .4 - 5e-13, 1e-13, 5e-13, 0, 0] m = [np.eye(6)[:, i] for i in range(6)] sm = ch.QuantumState((s, m), 'sm') self.assertEqual(sm.rank(), 2) self.assertEqual(sm.rank(tol=1e-13), 3) self.assertEqual(sm.rank(tol=1e-14), 4) sm = ch.QuantumState((s[:4], m[:4]), 'sm') self.assertEqual(sm.rank(), 2) self.assertEqual(sm.rank(tol=1e-13), 3) self.assertEqual(sm.rank(tol=1e-14), 4)
def test_simple(self): zero = np.array(np.eye(2)) zero[1, 1] = 0 p = ch.QuantumState(zero, 'dm') err = la.norm(p.bloch_vector() - np.array([[0], [0], [1]])) self.assertEqual(err, 0) one = np.array(np.eye(2)) one[0, 0] = 0 p = ch.QuantumState(one, 'dm') err = la.norm(p.bloch_vector() - np.array([[0], [0], [-1]])) self.assertEqual(err, 0)
def test_kron(self): p1 = ch.QuantumState(.5 * np.eye(2), 'dm') p2 = ch.QuantumState(.5 * np.eye(2), 'dm') p3 = p1.kron(p2) p4 = p1 ^ p2 err1 = la.norm(p3.density_matrix() - .25 * np.eye(4)) err2 = la.norm(p4.density_matrix() - .25 * np.eye(4)) self.assertEqual(err1, 0) self.assertEqual(err2, 0)
def test_bloch_vector_as_matrix(self): bv = uniform.bloch_vector(4, as_state=False) self.assertTrue(bv.shape == (15, 1)) self.assertLessEqual(la.norm(bv), 1) self.assertEqual(type(bv), np.ndarray) self.assertTrue(ch.QuantumState(bv, 'bv').is_valid())
def test_density_matrix_as_matrix(self): dm = uniform.density_matrix(4, as_state=False) self.assertTrue(dm.shape == (4, 4)) self.assertTrue(type(dm), np.ndarray) self.assertTrue(dm.dtype == np.complex128) self.assertTrue(ch.QuantumState(dm).is_valid())
def test_purity_threshold_dm(self): rho = np.zeros((2, 2)) rho[0, 0] = 1. - 1.e-13 rho[1, 1] = 1.e-13 dm = ch.QuantumState(rho, 'dm') self.assertTrue(dm.is_pure()) self.assertFalse(dm.is_pure(tol=1e-14))
def test_purity_threshold_sm(self): s = (1. - 1e-13, 1e-13) m = (np.eye(2)[:, 1], np.eye(2)[:, 0]) sm = ch.QuantumState((s, m), 'sm') self.assertTrue(sm.is_pure()) self.assertFalse(sm.is_pure(tol=1e-14))
def test_rank_dm(self): dm = np.diag([.5 - 1e-13, .4 - 5e-13, 1e-13, 5e-13, 0, 0]) dm = ch.QuantumState(dm, 'dm') self.assertEqual(dm.rank(), 2) self.assertEqual(dm.rank(tol=1e-13), 3) self.assertEqual(dm.rank(tol=1e-14), 4)
def test_validity_bv(self): bv = np.array([[1 + 1e-13, 0, 0]]).T SO, _ = la.qr(np.random.randn(3, 3)) bv = np.dot(SO, bv) bv = ch.QuantumState(bv, 'bv') self.assertTrue(bv.is_valid()) self.assertFalse(bv.is_valid(tol=1e-14))
def test_bv_to_sm(self): p = ch.QuantumState(np.array(np.zeros((3, 1))), 'bv') b, w = p.state_mixture() self.assertEqual(la.norm(b - .5 * np.ones(2)), 0) err = la.norm(p.density_matrix() - .5 * (np.eye(2))) self.assertEqual(err, 0.)
def test_2_qubit_bv(self): zero = ch.QuantumState([[1,0],[0,0]],'dm') zz = zero^zero #test = np.zeros((15,1)) #test[0] = 1 #self.assertEqual(la.norm(test-zz.bloch_vector()),0) self.assertEqual(la.norm(zz.bloch_vector()),1)
def test_sm_dtype(self): D = ch.QuantumState((1., [np.eye(2, dtype=np.complex128)[:, 0]]), 'sm') self.assertEqual(type(D._sm.weights), np.ndarray) self.assertEqual(D._sm.weights.dtype, np.float64) self.assertTrue( all([type(b) == type(np.array([])) for b in D._sm.basis])) #Changed Type self.assertTrue(all([b.dtype == np.complex128 for b in D._sm.basis])) D = ch.QuantumState((1., [np.eye(2)[:, 0]]), 'sm') self.assertEqual(type(D._sm.weights), np.ndarray) self.assertEqual(D._sm.weights.dtype, np.float64) self.assertTrue( all([type(b) == type(np.array([])) for b in D._sm.basis])) #Changed Type self.assertTrue(all([b.dtype == np.complex128 for b in D._sm.basis])) w, b = D.state_mixture() self.assertEqual(type(w), np.ndarray) self.assertEqual(w.dtype, np.float64) self.assertTrue(all([type(bb) == type(np.array([])) for bb in b])) #Changed Type self.assertTrue(all([bb.dtype == np.complex128 for bb in b])) self.assertEqual(type(D.bloch_vector()), type(np.array([]))) #Changed Type self.assertEqual(D.bloch_vector().dtype, np.float64) self.assertEqual(type(D.density_vector()), type(np.array([]))) #Changed Type self.assertEqual(D.density_vector().dtype, np.complex128) self.assertEqual(type(D.density_matrix()), type(np.array([]))) #Changed Type self.assertEqual(D.density_matrix().dtype, np.complex128)
def test_not_implemented(self): try: ch.QuantumChannel(np.eye(2), 'notanoption') except NotImplementedError: pass chan = ch.QuantumChannel(np.eye(2), 'unitary') state = ch.QuantumState([[1, 0], [0, 0]], 'dm') chan.natural_type = 'not_a_type' try: chan * state except NotImplementedError: pass
def test_map_concatenation(self): zero = np.zeros((2, 2)) zero[1, 1] = 0 p = ch.QuantumState(zero, 'dm') X = ch.QuantumChannel(ch._sigmaX, 'unitary') out = X * X * p out2 = (X * X) * p out3 = X * (X * p) self.assertEqual(la.norm(out.density_matrix() - zero), 0) self.assertEqual(la.norm(out2.density_matrix() - zero), 0) self.assertEqual(la.norm(out3.density_matrix() - zero), 0)
def test_map_X0(self): zero = np.zeros((2, 2)) zero[1, 1] = 0 p = ch.QuantumState(zero, 'dm') X = ch.QuantumChannel(ch._sigmaX, 'unitary') out = X.map(p) out2 = X * p one = np.zeros((2, 2)) one[0, 0] = 0 self.assertEqual(la.norm(out.density_matrix() - one), 0) self.assertEqual(la.norm(out2.density_matrix() - one), 0)
def test_2_qubit_bv_random(self): bv = uniform.bloch_vector(4,pure=True) self.assertAlmostEqual(np.trace(bv.density_matrix()),1,12) dm = uniform.density_matrix(4,rank=1) self.assertAlmostEqual(la.norm(dm.bloch_vector()),1,12) bv2 = ch.QuantumState(dm.bloch_vector(),'bv') dv1 = dm.density_vector() dv2 = bv2.density_vector() self.assertAlmostEqual(la.norm(dm.density_matrix()-bv2.density_matrix()),0,15)
def test_1_qutrit_random_op(self): state = uniform.density_matrix(3) op = uniform.choi(3) out = op*state op2 = ch.QuantumChannel(op.ptm(),'ptm') self.assertAlmostEqual(la.norm(op.choi()-op2.choi()),0,14) bvout = op.ptm()[1:,1:]@state.bloch_vector()+op.ptm()[1:,0,np.newaxis]*1./np.sqrt(2) bvout2 = ch.QuantumState(bvout,'bv') self.assertAlmostEqual(la.norm(out.bloch_vector()-bvout),0,14) self.assertAlmostEqual(la.norm(out.density_matrix()-bvout2.density_matrix()),0,14)
def test_2_qutrit_random_op(self): state = uniform.density_matrix(9) op = uniform.choi(9) out = op*state op2 = ch.QuantumChannel(op.ptm(),'ptm') self.assertAlmostEqual(la.norm(op.choi()-op2.choi()),0,14) #This illustrates the ugliness of wanting a unit sphere bvout = op.ptm()[1:,1:]@state.bloch_vector()+op.ptm()[1:,0,np.newaxis]*1./np.sqrt(8) bvout2 = ch.QuantumState(bvout,'bv') self.assertAlmostEqual(la.norm(out.bloch_vector()-bvout),0,15) self.assertAlmostEqual(la.norm(out.density_matrix()-bvout2.density_matrix()),0,14)
def test_validity_dm_sm(self): dm = np.diag([.5, .5 + 1e-13]) dm = ch.QuantumState(dm, 'dm') self.assertTrue(dm.is_valid()) self.assertFalse(dm.is_valid(tol=1e-14)) sm = ch.QuantumState(dm.state_mixture(), 'sm') self.assertTrue(sm.is_valid()) self.assertFalse(sm.is_valid(tol=1e-14)) dm = np.diag([.5, .5 - 1e-13]) dm = ch.QuantumState(dm, 'dm') self.assertTrue(dm.is_valid()) self.assertFalse(dm.is_valid(tol=1e-14)) sm = ch.QuantumState(dm.state_mixture(), 'sm') self.assertTrue(sm.is_valid()) self.assertFalse(sm.is_valid(tol=1e-14)) dm = np.diag([1, -1e-13]) dm = ch.QuantumState(dm, 'dm') self.assertTrue(dm.is_valid()) self.assertFalse(dm.is_valid(tol=1e-14)) sm = ch.QuantumState(dm.state_mixture(), 'sm') self.assertTrue(sm.is_valid()) self.assertFalse(sm.is_valid(tol=1e-14)) dm = np.diag([1 + 1e-13, -1e-13]) dm = ch.QuantumState(dm, 'dm') self.assertTrue(dm.is_valid()) self.assertFalse(dm.is_valid(tol=1e-14)) sm = ch.QuantumState(sm.state_mixture(), 'sm') self.assertTrue(sm.is_valid()) self.assertFalse(sm.is_valid(tol=1e-14))
def test_missing_ptm_paths(self): ptm1 = uni.choi(2).ptm() ptm2 = uni.choi(2).ptm() ch1 = ch.QuantumChannel(ptm1, 'ptm') ch2 = ch.QuantumChannel(ptm2, 'ptm') out = ch1 * ch2 self.assertEqual(np.linalg.norm(ptm1 @ ptm2 - out.ptm()), 0) bv = ptm1 @ (np.eye(4)[:, 1]) bv[0] = 1.0 rho = ch.QuantumState(bv[1:], 'bv') rho_out = ch2 * rho self.assertAlmostEqual( np.linalg.norm((ptm2 @ bv)[1:, np.newaxis] - rho_out.bloch_vector()), 0)