def test_apply_1q_random_ptm(self, state_cls, dm_basis, qubit): unity = np.identity(2) unitary = random_unitary_matrix(2, 45) einsum_args = [unity, [0, 3], unity, [1, 4], unity, [2, 5]] einsum_args[2 * qubit] = unitary unitary3q = np.einsum(*einsum_args, optimize=True).reshape(8, 8) dm_before = random_density_matrix(8, seed=46) dm_after = unitary3q @ dm_before @ unitary3q.conj().T assert dm_before.trace() == approx(1) assert dm_after.trace() == approx(1) b = (dm_basis(2), ) bases = b * 3 state0 = state_cls.from_dm(dm_before, bases) state1 = state_cls.from_dm(dm_after, bases) # sanity check for q in range(3): if q != qubit: assert state0.meas_prob(q) == approx(state1.meas_prob(q)) else: assert state0.meas_prob(q) != approx(state1.meas_prob(q)) ptm = kraus_to_ptm(unitary.reshape(1, 2, 2), b, b) state0.apply_ptm(ptm, qubit) assert state0.to_pv() == approx(state1.to_pv())
def test_apply_1q_random_ptm(self, state_cls, dm_basis, qubit): unity = np.identity(2) unitary = random_unitary_matrix(2, 45) einsum_args = [unity, [0, 3], unity, [1, 4], unity, [2, 5]] einsum_args[2*qubit] = unitary unitary3q = np.einsum(*einsum_args, optimize=True).reshape(8, 8) dm_before = random_density_matrix(8, seed=46) dm_after = unitary3q @ dm_before @ unitary3q.conj().T assert dm_before.trace() == approx(1) assert dm_after.trace() == approx(1) b = (dm_basis(2),) bases = b * 3 state0 = state_cls.from_dm(dm_before, bases) state1 = state_cls.from_dm(dm_after, bases) # sanity check for q in range(3): if q != qubit: assert state0.meas_prob(q) == approx(state1.meas_prob(q)) else: assert state0.meas_prob(q) != approx(state1.meas_prob(q)) ptm = kraus_to_ptm(unitary.reshape(1, 2, 2), b, b) state0.apply_ptm(ptm, qubit) assert state0.to_pv() == approx(state1.to_pv())
def test_apply_1q_projecting_ptm(self, pauli_vector_cls, dm_basis, qubit): unitary = random_unitary_matrix(2, 45) b_in = (dm_basis(2), ) b_out = (dm_basis(2).subbasis([1]), ) bases = b_in * 3 dm_before = random_density_matrix(8, seed=46) pv = pauli_vector_cls.from_dm(dm_before, bases) pv_before = pv.to_pv() ix_out = [0, 1, 2] ix_out[qubit] = 3 ptm = kraus_to_ptm(unitary.reshape(1, 2, 2), b_in, b_out) pv_ref = np.einsum(ptm, [3, qubit], pv_before, [0, 1, 2], ix_out) pv.apply_ptm(ptm, qubit) pv.to_pv() == approx(pv_ref)
def test_apply_random_ptm1q_state1q(self, state_cls, dm_basis): unitary = random_unitary_matrix(2, 45) dm_before = random_density_matrix(2, seed=256) dm_after = unitary @ dm_before @ unitary.conj().T assert dm_before.trace() == approx(1) assert dm_after.trace() == approx(1) b = (dm_basis(2), ) state0 = state_cls.from_dm(dm_before, b) state1 = state_cls.from_dm(dm_after, b) # sanity check assert state0.meas_prob(0) != approx(state1.meas_prob(0)) ptm = kraus_to_ptm(unitary.reshape(1, 2, 2), b, b) b_gm = (quantumsim.bases.gell_mann(2), ) ptm2 = ptm_convert_basis(ptm, b, b, b_gm, b_gm) assert np.allclose(ptm2[0, 1:], 0) assert ptm2[0, 0] == approx(1) state0.apply_ptm(ptm, 0) assert state0.to_pv() == approx(state1.to_pv())
def test_apply_random_ptm1q_state1q(self, state_cls, dm_basis): unitary = random_unitary_matrix(2, 45) dm_before = random_density_matrix(2, seed=256) dm_after = unitary @ dm_before @ unitary.conj().T assert dm_before.trace() == approx(1) assert dm_after.trace() == approx(1) b = (dm_basis(2),) state0 = state_cls.from_dm(dm_before, b) state1 = state_cls.from_dm(dm_after, b) # sanity check assert state0.meas_prob(0) != approx(state1.meas_prob(0)) ptm = kraus_to_ptm(unitary.reshape(1, 2, 2), b, b) b_gm = (quantumsim.bases.gell_mann(2),) ptm2 = ptm_convert_basis(ptm, b, b, b_gm, b_gm) assert np.allclose(ptm2[0, 1:], 0) assert ptm2[0, 0] == approx(1) state0.apply_ptm(ptm, 0) assert state0.to_pv() == approx(state1.to_pv())
def test_apply_2q_random_ptm(self, state_cls, dm_basis, qubits): unity = np.identity(2) unitary = random_unitary_matrix(4, 45).reshape(2, 2, 2, 2) decay = np.array([[0.9, 0], [0, 0.7]]) op = decay @ unitary q0, q1 = qubits (q2, ) = tuple(q for q in range(3) if q not in qubits) einsum_args = [op, [q0, q1, q0 + 3, q1 + 3], unity, [q2, q2 + 3]] op3q = np.einsum(*einsum_args, optimize=True).reshape(8, 8) dm_before = random_density_matrix(8, seed=46) dm_after = op3q @ dm_before @ op3q.conj().T assert dm_before.trace() == approx(1) assert dm_after.trace() < 1. b = (dm_basis(2), ) bases = b * 3 state0 = state_cls.from_dm(dm_before, bases) state1 = state_cls.from_dm(dm_after, bases) ptm = kraus_to_ptm(op.reshape(1, 4, 4), b * 2, b * 2) state0.apply_ptm(ptm, *qubits) assert state0.to_pv() == approx(state1.to_pv())
def test_apply_2q_random_ptm(self, state_cls, dm_basis, qubits): unity = np.identity(2) unitary = random_unitary_matrix(4, 45).reshape(2, 2, 2, 2) decay = np.array([[0.9, 0], [0, 0.7]]) op = decay @ unitary q0, q1 = qubits (q2,) = tuple(q for q in range(3) if q not in qubits) einsum_args = [op, [q0, q1, q0+3, q1+3], unity, [q2, q2+3]] op3q = np.einsum(*einsum_args, optimize=True).reshape(8, 8) dm_before = random_density_matrix(8, seed=46) dm_after = op3q @ dm_before @ op3q.conj().T assert dm_before.trace() == approx(1) assert dm_after.trace() < 1. b = (dm_basis(2),) bases = b * 3 state0 = state_cls.from_dm(dm_before, bases) state1 = state_cls.from_dm(dm_after, bases) ptm = kraus_to_ptm(op.reshape(1, 4, 4), b * 2, b * 2) state0.apply_ptm(ptm, *qubits) assert state0.to_pv() == approx(state1.to_pv())