# Superoperators¶

class qitensor.superop.Superoperator(in_space, out_space, m)

Bases: object

FIXME: need to write documentation.

as_matrix()
classmethod from_function(in_space, f)
```>>> from qitensor import qubit, qudit, Superoperator, CP_Map
>>> ha = qudit('a', 3)
>>> hb = qubit('b')
>>> rho = (ha*hb).random_density()
```
```>>> ET = Superoperator.from_function(ha, lambda x: x.T)
>>> ET
Superoperator( |a><a| to |a><a| )
>>> (ET(rho) - rho.transpose(ha)).norm() < 1e-14
True
```
```>>> Superoperator.from_function(ha, lambda x: x.H)
Traceback (most recent call last):
...
ValueError: function was not linear
```
in_space
out_space
classmethod random(spc_in, spc_out)
classmethod transposer(spc)
```>>> from qitensor import qubit, qudit, Superoperator
>>> ha = qudit('a', 3)
>>> hb = qubit('b')
>>> rho = (ha*hb).random_density()
```
```>>> T = Superoperator.transposer(ha)
>>> T
Superoperator( |a><a| to |a><a| )
>>> (T(rho) - rho.transpose(ha)).norm() < 1e-14
True
```
class qitensor.superop.CP_Map(J, env_space, _complimentary_channel=None)

FIXME: need to write documentation.

C

The complimentary channel.

J

The channel isometry.

Adds two CP maps. The returned map has the same action as E1+E2, but the environment is the direct sum of the component environments.

```>>> import numpy.linalg as linalg
>>> from qitensor import qudit, CP_Map
>>> ha = qudit('a', 2)
>>> hb = qudit('b', 3)
>>> E1 = CP_Map.random(ha, hb, 'hc1')
>>> E2 = CP_Map.random(ha, hb, 'hc2')
>>> X = E1 + E2
>>> linalg.norm(X.as_matrix() - Y.as_matrix()) < 1e-14
True
>>> (E1.env_space, E2.env_space, Y.env_space)
(|hc1>, |hc2>, |hc1+hc2>)
```
assert_cptp()
coherent_information(rho)

Compute S(B)-S(C) after passing the given state through the channel.

classmethod decohere(spc, espc_def=None)
```>>> from qitensor import qudit, CP_Map
>>> ha = qudit('a', 5)
>>> rho = ha.random_density()
>>> E = CP_Map.decohere(ha)
>>> (E(rho) - ha.diag(rho.diag(as_np=True))).norm() < 1e-14
True
```
env_space
classmethod erasure(spc, p, bspc_def=None, espc_def=None)

Create a channel that has probability p of erasing the input, and 1-p of perfectly transmitting the input. The output space has dimension one greater than the input space, and the receiver is notified of erasure via the extra computational basis state. If p=0.5 then the channel is symmetric.

classmethod from_function(in_space, f, espc_def=None)
```>>> from qitensor import qubit, qudit, CP_Map
>>> ha = qudit('a', 3)
>>> hb = qubit('b')
>>> rho = (ha*hb).random_density()
```
```>>> CP_Map.from_function(ha, lambda x: x.T)
Traceback (most recent call last):
...
ValueError: matrix didn't correspond to a completely positive superoperator (min eig=-1.0)
```
```>>> U = ha.random_unitary()
>>> EU = CP_Map.from_function(ha, lambda x: U*x*U.H)
>>> EU
CP_Map( |a><a| to |a><a| )
>>> (EU(rho) - U*rho*U.H).norm() < 1e-14
True
```
classmethod from_kraus(ops, espc_def=None)
classmethod from_matrix(m, spc_in, spc_out, espc_def=None, compact_environ_tol=1e-12)
```>>> from qitensor import qudit, CP_Map
>>> ha = qudit('a', 2)
>>> hb = qudit('b', 3)
>>> hx = qudit('x', 5)
>>> E1 = CP_Map.random(ha*hb, hx)
>>> E2 = CP_Map.random(hx, ha*hb)
>>> m = E2.as_matrix() * E1.as_matrix()
>>> E3 = CP_Map.from_matrix(m, ha*hb, ha*hb)
>>> rho = (ha*hb).random_density()
>>> (E2(E1(rho)) - E3(rho)).norm() < 1e-14
True
```
classmethod identity(spc, espc_def=None)
```>>> from qitensor import qubit, CP_Map
>>> ha = qubit('a')
>>> hb = qubit('b')
>>> rho = (ha*hb).random_density()
>>> E = CP_Map.identity(ha)
>>> (E(rho) - rho).norm() < 1e-14
True
```
is_cptp()
ket()

Returns the channel ket.

```>>> from qitensor import qudit, CP_Map
>>> ha = qudit('a', 2)
>>> hb = qudit('b', 2)
>>> E = CP_Map.random(ha, hb, 'c')
>>> E.J.space
|b,c><a|
>>> E.ket().space
|a,b,c>
>>> F = CP_Map.random(ha, ha, 'c')
>>> F.ket()
Traceback (most recent call last):
...
HilbertError: 'channel ket can only be made if input space is different from output and environment spaces'
```
classmethod noisy(spc, p, espc_def=None)
```>>> from qitensor import qudit, CP_Map
>>> ha = qudit('a', 5)
>>> rho = ha.random_density()
>>> E = CP_Map.noisy(ha, 0.2)
>>> (E(rho) - 0.8*rho - 0.2*ha.fully_mixed()).norm() < 1e-14
True
```
private_information(ensemble)

Compute I(X;B) - I(X;C) where X is a classical ancillary system that records which state of the ensemble was passed through the channel.

classmethod random(spc_in, spc_out, espc_def=None)
classmethod totally_noisy(spc, espc_def=None)
```>>> from qitensor import qudit, CP_Map
>>> ha = qudit('a', 5)
>>> rho = ha.random_density()
>>> E = CP_Map.totally_noisy(ha)
>>> (E(rho) - ha.fully_mixed()).norm() < 1e-14
True
```
classmethod unitary(U, espc_def=None)
```>>> from qitensor import qubit, CP_Map
>>> ha = qubit('a')
>>> hb = qubit('b')
>>> U = ha.random_unitary()
>>> rho = (ha*hb).random_density()
>>> E = CP_Map.unitary(U)
>>> (E(rho) - U*rho*U.H).norm() < 1e-14
True
```

Tensor Subspaces

Groups