def test_no_SchWARMA(self): ARMAs = [SchWARMA.ARMA([], [0])] ARMAs.append(SchWARMA.ARMA([], [0])) ARMAs.append(SchWARMA.ARMA([], [0])) D = { 'I': ch.QuantumChannel(np.array(np.eye(4, dtype=complex))), 'X': ch.QuantumChannel(np.kron(s_x.conj(), s_x)) } sch = SchWARMA.SchWARMA(ARMAs, [s_x, s_y, s_z], D) sch.init_ARMAs self.assertEqual(la.norm(D['I'].choi() - sch['I'].choi()), 0) self.assertEqual(la.norm(D['X'].choi() - sch['X'].choi()), 0)
def test_stiefel_as_matrix(self): stiefel = uniform.stiefel(3, as_channel=False) self.assertTrue(stiefel.shape == (27, 3)) self.assertEqual(type(stiefel), np.ndarray) self.assertEqual(stiefel.dtype, np.complex128) self.assertTrue(ch.QuantumChannel(stiefel, 'stiefel').is_valid())
def test_mixed_basis(self): ARMAs = [SchWARMA.ARMA([.5, .25], [1])] ARMAs.append(SchWARMA.ARMA([], [1])) ARMAs.append(SchWARMA.ARMA([], [1, 1, 1])) D = { 'I': ch.QuantumChannel(np.array(np.eye(4, dtype=complex))), 'X': ch.QuantumChannel(np.kron(s_x.conj(), s_x)) } ad = np.zeros((4, 2), dtype=complex) ad[2, 1] = .1 sch = SchWARMA.SchWARMA(ARMAs, [s_x, 1j * s_y, ad], D) self.assertEqual(sch.N, 2) self.assertTrue( all([la.norm(b + b.conj().T < 1e-9) for b in sch.basis]))
def test_choi_as_matrix(self): choi = uniform.choi(3, as_channel=False) self.assertTrue(choi.shape == (9, 9)) self.assertEqual(type(choi), np.ndarray) self.assertEqual(choi.dtype, np.complex128) self.assertTrue(ch.QuantumChannel(choi, 'choi').is_valid())
def test_bad_init(self): ARMAS = [ SchWARMA.ARMA(np.random.randn(1), np.random.randn(np.random.randint(5)) + 2) for _ in range(3) ] D = {'I': ch.QuantumChannel(np.array(np.eye(4, dtype=complex)))} self.assertRaises(AssertionError, SchWARMA.SchWMA, *[ARMAS, [s_x, s_y, s_z], D])
def test_init(self): ARMAS = [ SchWARMA.ARMA([], np.random.randn(np.random.randint(5)) + 2) for _ in range(3) ] D = {'I': ch.QuantumChannel(np.array(np.eye(4, dtype=complex)))} MA = SchWARMA.SchWMA(ARMAS, [s_x, s_y, s_z], D)
def test_is_unital(self): U1 = uni.choi(2, 1) self.assertTrue(U1.is_unital()) U2 = uni.choi(2, 1) self.assertTrue(U1.is_unital()) mix = np.random.rand() unital_map = ch.QuantumChannel(mix * U1.choi() + (1 - mix) * U2.choi(), 'choi') self.assertTrue(unital_map.is_unital()) gamma = np.random.rand() amp_damp = ch.QuantumChannel( [[[1, 0], [0, np.sqrt(1 - gamma)]], [[0, np.sqrt(gamma)], [0, 0]]], 'kraus') self.assertFalse(amp_damp.is_unital())
def test_choi_real_diagonal(self): choi = .25 * np.eye(4) + 1e-8 * 1j * np.eye(4) D = ch.QuantumChannel(choi, 'choi') diag = np.diag(D._choi.choi) self.assertEqual(la.norm(np.imag(diag)), 0) diag = np.diag(D.choi()) self.assertEqual(la.norm(np.imag(diag)), 0)
def test_liou_to_choi(self): paulis = [ch._sigmaI, ch._sigmaX, ch._sigmaY, ch._sigmaZ] for i, gate in enumerate(paulis): L = np.kron(gate.conj(), gate) D = ch.QuantumChannel(L, 'liou') choi = D.choi() choi_true = ch._vec(gate) * ch._vec(gate).conj().T self.assertEqual(la.norm(choi - choi_true), 0)
def test_kraus_to_all(self): paulis = [ch._sigmaI, ch._sigmaX, ch._sigmaY, ch._sigmaZ] weights = np.random.randn(4) + 1j * np.random.randn(4) weights = weights / la.norm(weights) kraus = [w * p for w, p in zip(weights, paulis)] D = ch.QuantumChannel(kraus, 'kraus') kraus2 = D.kraus() errs = [la.norm(k1 - k2) for k1, k2 in zip(kraus, kraus2)] self.assertEqual(np.max(errs), 0) S = np.zeros((8, 2), dtype=np.complex128) for i in range(4): S[i * 2:(i + 1) * 2, :] = kraus[i] D = ch.QuantumChannel(kraus, 'kraus') S2 = D.stiefel() self.assertEqual(la.norm(S - S2), 0) S = np.zeros((8, 2), dtype=np.complex128) for i in range(4): S[i::4, :] = kraus[i] D = ch.QuantumChannel(kraus, 'kraus') S2 = D.stiefel2() self.assertEqual(la.norm(S - S2), 0) D = ch.QuantumChannel(kraus, 'kraus') L = np.sum([ w.conj() * w * np.kron(p.conj(), p) for w, p in zip(weights, paulis) ], 0) L2 = D.liouvillian() self.assertAlmostEqual(la.norm(L - L2), 0, 15) ptms = [np.eye(4) for _ in paulis] for i in range(1, 4): for j in range(1, 4): if i != j: ptms[i][j, j] = -1 PTM = np.sum([w.conj() * w * p for w, p in zip(weights, ptms)], 0) D = ch.QuantumChannel(kraus, 'kraus') PTM2 = D.ptm() self.assertAlmostEqual(la.norm(PTM - PTM2), 0) choi = np.sum([ w.conj() * w * ch._vec(p) * ch._vec(p).conj().T for w, p in zip(weights, paulis) ], 0) D = ch.QuantumChannel(kraus, 'kraus') choi2 = D.choi() self.assertAlmostEqual(la.norm(choi - choi2), 0) chi = np.diag([w.conj() * w for w in weights]) D = ch.QuantumChannel(kraus, 'kraus') chi2 = D.chi() self.assertAlmostEqual(la.norm(chi - chi2), 0, 15)
def test_liou_to_chi(self): paulis = [ch._sigmaI, ch._sigmaX, ch._sigmaY, ch._sigmaZ] for i, gate in enumerate(paulis): L = np.kron(gate.conj(), gate) D = ch.QuantumChannel(L, 'liou') chi = D.chi() chi_true = np.zeros((4, 4)) chi_true[i, i] = 1 self.assertEqual(la.norm(chi - chi_true), 0)
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)
def unitary_props_sim(self, num_MC, as_channel = True, rgen=np.random): vals = self.schwarmafier.gen_noise_instances(self.circ, num_MC, rgen, self.SPAM) unitary_props = [] for row in vals: resolver = cirq.ParamResolver({str(h):row[i] for i,h in enumerate(self.syms)}) prop = cirq.resolve_parameters(self.noisy_circuit,resolver)._unitary_() if as_channel: prop = ch.QuantumChannel(prop, 'unitary') unitary_props.append(prop) return unitary_props
def test_hamiltonian_basis(self): ARMAs = [SchWARMA.ARMA([.5, .25], [1])] ARMAs.append(SchWARMA.ARMA([], [1])) ARMAs.append(SchWARMA.ARMA([], [1, 1, 1])) D = {'I': ch.QuantumChannel(np.array(np.eye(4, dtype=complex)))} sch = SchWARMA.SchWARMA(ARMAs, [s_x, s_y, s_z], D) self.assertTrue( all([la.norm(b + b.conj().T < 1e-9) for b in sch.basis]))
def test_is_valid_gaps(self): ch1 = uni.choi(2) self.assertTrue(ch1.is_valid()) vals, vecs = la.eigh(ch1.choi()) C = vecs @ np.diag(vals * np.array([1, 1, 1, -1])) @ vecs.conj().T C = ch.QuantumChannel(C, 'choi') self.assertFalse(C.is_valid()) C = ch.QuantumChannel(1.1 * ch1.choi(), 'choi') self.assertFalse(C.is_valid()) C = ch.QuantumChannel(ch1.kraus(), 'kraus') self.assertTrue(C.is_valid()) ks = C.kraus() ks[0] += np.random.randn(2, 2) * .02 C = ch.QuantumChannel(ks, 'kraus') self.assertFalse(C.is_valid())
def test_dual(self): D = uni.choi(N=3) DD = D.dual() DDD = DD.dual() self.assertEqual(la.norm(D.choi() - DDD.choi()), 0) P = ch.QuantumChannel(D.ptm(), 'ptm') PP = P.dual() PPP = PP.dual() self.assertEqual(la.norm(P.ptm() - PPP.ptm()), 0) K = ch.QuantumChannel(D.kraus(), 'kraus') KK = K.dual() KKK = KK.dual() self.assertEqual(la.norm(K.stiefel() - KKK.stiefel()), 0) self.assertAlmostEqual(la.norm(DD.choi() - KK.choi()), 0) self.assertAlmostEqual(la.norm(DD.choi() - PP.choi()), 0)
def test_zero_basis(self): ARMAs = [SchWARMA.ARMA([.5, .25], [1])] ARMAs.append(SchWARMA.ARMA([], [1])) D = {'I': ch.QuantumChannel(np.array(np.eye(4, dtype=complex)))} sch = SchWARMA.SchWARMA(ARMAs, [np.zeros((8, 2)), np.zeros((2, 2))], D) self.assertEqual(sch.N, 2) self.assertTrue(all([b.shape == (8, 8) for b in sch.basis])) self.assertEqual(la.norm(sch['I'].liouvillian() - np.eye(4)), 0)
def test_ptm_to_all(self): paulis = [ch._sigmaI, ch._sigmaX, ch._sigmaY, ch._sigmaZ] weights = np.random.randn(4) + 1j * np.random.randn(4) weights = weights / la.norm(weights) ptms = [np.eye(4) for _ in paulis] for i in range(1, 4): for j in range(1, 4): if i != j: ptms[i][j, j] = -1 PTM = np.sum([w.conj() * w * p for w, p in zip(weights, ptms)], 0) D = ch.QuantumChannel(PTM, 'ptm') PTM2 = D.ptm() self.assertEqual(la.norm(PTM - PTM2), 0) kraus = [w * p for w, p in zip(weights, paulis)] D = ch.QuantumChannel(PTM, 'ptm') kraus2 = D.kraus() #errs = [la.norm(k1-k2) for k1,k2 in zip(kraus,kraus2)] errs = [ np.min([ la.norm(np.kron(k1.conj(), k1) - np.kron(k2.conj(), k2)) for k2 in kraus2 ]) for k1 in kraus ] self.assertAlmostEqual(la.norm(errs), 0, 12) #Skip stiefel since it is tedious due to phase ambiguity #S = np.zeros((8,2),dtype=np.complex128) #for i in range(4): # S[i*2:(i+1)*2,:] = kraus[i] D = ch.QuantumChannel(PTM, 'ptm') S2 = D.stiefel() #errs = [np.min([la.norm(np.kron(k1.conj(),k1)-np.kron(k2.conj(),k2)) for k2 in kraus2]) for k1 in kraus] #self.AssertEqual(la.norm(S-S2),0) D = ch.QuantumChannel(PTM, 'ptm') L = np.sum([ w.conj() * w * np.kron(p.conj(), p) for w, p in zip(weights, paulis) ], 0) L2 = D.liouvillian() self.assertAlmostEqual(la.norm(L - L2), 0, 12) choi = np.sum([ w.conj() * w * ch._vec(p) * ch._vec(p).conj().T for w, p in zip(weights, paulis) ], 0) D = ch.QuantumChannel(PTM, 'ptm') choi2 = D.choi() self.assertAlmostEqual(la.norm(choi - choi2), 0, 12) chi = np.diag([w.conj() * w for w in weights]) D = ch.QuantumChannel(PTM, 'ptm') chi2 = D.chi() self.assertAlmostEqual(la.norm(chi - chi2), 0, 12)
def test_liou_to_ptm(self): paulis = [ch._sigmaI, ch._sigmaX, ch._sigmaY, ch._sigmaZ] for i, gate in enumerate(paulis): L = np.kron(gate.conj(), gate) D = ch.QuantumChannel(L, 'liou') ptm = D.ptm() ptm_true = np.eye(4) if i > 0: for j in range(1, 4): if i != j: ptm_true[j, j] = -1 self.assertEqual(la.norm(ptm - ptm_true), 0)
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_avg(self): D = {'I': ch.QuantumChannel(np.array(np.eye(4, dtype=complex)))} MA = SchWARMA.SchWMA([], [s_z], D) alpha = np.sqrt(.00001) sigma = 1. #1./2. arg = lambda t: alpha**2 * sigma * (np.sqrt(np.pi) * t * sp.erf( t / sigma) + sigma * (np.exp(-t**2 / sigma**2) - 1)) args = np.exp(-2 * np.array([arg(t) for t in range(100)])) #args = (1.-args)/2. MA.fit([(1. - args) / 2.], 5) self.assertEqual(5, len(MA.models[0].b)) self.assertEqual(0, len(MA.models[0].a)) MA.init_ARMAs() MA['I'] L1 = MA.avg(1, [ch.QuantumChannel(s_z, 'unitary').choi()]).liouvillian() tL1 = np.array(np.eye(4, dtype=complex)) tL1[1, 1] = args[1] tL1[2, 2] = args[1] self.assertAlmostEqual(la.norm(L1 - tL1), 0.0, 6) L2 = MA.avg(10, [ch.QuantumChannel(s_z, 'unitary').choi()]).liouvillian() tL2 = np.eye(4, dtype=complex) tL2[1, 1] = args[10] tL2[2, 2] = args[10] self.assertAlmostEqual(la.norm(L2 - tL2), 0.0, 5) #Not a great test, but should be true self.assertLess(la.norm(L2 - tL2), la.norm(tL1**10 - L2))
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_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_3d_fit(self): D = {'I': ch.QuantumChannel(np.array(np.eye(4,dtype=complex)))} AR = SchWARMA.SchWAR([], [s_z], D) alpha = np.sqrt(.00001) sigma = 1.#1./2. arg = lambda t: alpha**2*sigma*(np.sqrt(np.pi)*t*sp.erf(t/sigma)+sigma*(np.exp(-t**2/sigma**2)-1)) args = np.exp(-2*np.array([arg(t) for t in range(100)])) args = (1.-args)/2. #Note now I have brackets on the second argument AR.fit([args, args, args], [3,5,7]) self.assertEqual(3,len(AR.models[0].a)) self.assertEqual(5,len(AR.models[1].a)) self.assertEqual(7,len(AR.models[2].a)) AR.init_ARMAs() L = AR['I']
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_init(self): ARMAs = [SchWARMA.ARMA([.5, .25], [1])] ARMAs.append(SchWARMA.ARMA([], [1])) ARMAs.append(SchWARMA.ARMA([], [1, 1, 1])) D = {'I': ch.QuantumChannel(np.array(np.eye(4, dtype=complex)))} sch = SchWARMA.SchWARMA(ARMAs, [s_x, s_y, s_z], D) xs = [copy.copy(model.x) for model in sch.models] ys = [copy.copy(model.y) for model in sch.models] sch.init_ARMAs() xs2 = [copy.copy(model.x) for model in sch.models] ys2 = [copy.copy(model.y) for model in sch.models] xdiff = np.array([la.norm(x - xx) for x, xx in zip(xs, xs2)]) ydiff = np.array([la.norm(yy) for y, yy in zip(ys, ys2)]) self.assertTrue(np.all(xdiff > 0)) self.assertTrue(np.all(ydiff == 0))
def test_2_qubit_ptm(self): I2 = ch.QuantumChannel(np.eye(4),'unitary') self.assertEqual(la.norm(np.eye(16)-I2.ptm()),0)
def test_2_qutrit_chi(self): I = ch.QuantumChannel(np.eye(3),'unitary')
def cirq_to_total_channel(circ: cirq.Circuit): return ch.QuantumChannel(circ.unitary(), 'unitary')