def aschannel(self) -> 'Channel': """Converts a Gate into a Channel""" N = self.qubit_nb R = 4 tensor = bk.outer(self.tensor, self.H.tensor) tensor = bk.reshape(tensor, [2**N] * R) tensor = bk.transpose(tensor, [0, 3, 1, 2]) return Channel(tensor, self.qubits)
def test_trace(): tensor = bk.astensor(np.asarray([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 2.7, 1], [0, 0, 1, 0.3j]])) tensor = bk.reshape(tensor, (4, 4)) # FIXME astensor should not reshape tr = bk.evaluate(bk.trace(tensor)) print(tr) assert tr - (2.7+0.3j) == ALMOST_ZERO
def sharp(self) -> 'Channel': r"""Return the 'sharp' transpose of the superoperator. The transpose :math:`S^\#` switches the two covariant (bra) indices of the superoperator. (Which in our representation are the 2nd and 3rd super-indices) If :math:`S^\#` is Hermitian, then :math:`S` is a Hermitian-map (i.e. transforms Hermitian operators to hJrmitian operators) Flattening the :math:`S^\#` superoperator to a matrix gives the Choi matrix representation. (See channel.choi()) """ N = self.qubit_nb tensor = self.tensor tensor = bk.reshape(tensor, [2**N] * 4) tensor = bk.transpose(tensor, (0, 2, 1, 3)) tensor = bk.reshape(tensor, [2] * 4 * N) return Channel(tensor, self.qubits)
def chi(self) -> bk.BKTensor: """Return the chi (or process) matrix representation of this superoperator""" N = self.qubit_nb return bk.reshape(self.sharp.tensor, [2**(N * 2)] * 2)
def choi(self) -> bk.BKTensor: """Return the Choi matrix representation of this super operator""" # Put superop axes in [ok, ib, ob, ik] and reshape to matrix N = self.qubit_nb return bk.reshape(self.sharp.tensor, [2**(N * 2)] * 2)