noise/kraus.py
class GAD
Generalized amplitude damping (GAD) Kraus operators for a
Provides Kraus operators
A
Construct the GAD lowering Kraus operator
This operator maps population from
def A(order: int, d: int, Y: float, p: float) -> pt.Tensor [static]Implementation
def A(order: int, d: int, Y: float, p: float=0.0) -> pt.Tensor:
k = order
assert isinstance(k, int) and k >= 0, 'k must be int>=0'
assert isinstance(d, int) and d > 0, 'd must be int>0'
obj = pt.zeros((d, d), dtype=C128)
if k < d:
rs = pt.arange(k, d, dtype=pt.float64)
binom = pt.tensor([float(nCr(int(r), k)) for r in range(k, d)], dtype=pt.float64)
vals = binom.sqrt() * (1 - Y) ** ((rs - k) / 2) * Y ** (k / 2)
obj[(rs - k).long(), rs.long()] = vals.to(C128)
return (1 - p) ** 0.5 * objR
Construct the GAD raising Kraus operator
This operator maps population from
def R(k: int, d: int, Y: float, p: float) -> pt.Tensor [static]Implementation
def R(k: int, d: int, Y: float, p: float=0.0) -> pt.Tensor:
obj = pt.zeros((d, d), dtype=C128)
if k < d:
rs = pt.arange(0, d - k, dtype=pt.float64)
binom = pt.tensor([float(nCr(int(d - r - 1), k)) for r in range(d - k)], dtype=pt.float64)
vals = binom * (1 - Y) ** ((d - rs - k - 1) / 2) * Y ** (k / 2)
obj[(rs + k).long(), rs.long()] = vals.to(C128)
return p ** 0.5 * objclass Pauli
Single-qubit Pauli error operators as Kraus operators.
Each method returns
X
Return the bit-flip Kraus operator
def X(p: float) -> pt.Tensor [static]Implementation
def X(p: float) -> pt.Tensor:
return p ** 0.5 * pt.tensor([[0, 1], [1, 0]], dtype=C128)Y
Return the phase+bit-flip Kraus operator
def Y(p: float) -> pt.Tensor [static]Implementation
def Y(p: float) -> pt.Tensor:
return p ** 0.5 * pt.tensor([[0, -1j], [1j, 0]], dtype=C128)Z
Return the phase-flip Kraus operator
def Z(p: float) -> pt.Tensor [static]Implementation
def Z(p: float) -> pt.Tensor:
return p ** 0.5 * pt.tensor([[1, 0], [0, -1]], dtype=C128)I
Return the identity Kraus operator
def I(ps: List[float]) -> pt.Tensor [static]Implementation
def I(ps: List[float]) -> pt.Tensor:
return (1 - sum(ps)) ** 0.5 * pt.tensor([[1, 0], [0, 1]], dtype=C128)class Depolarising
Depolarising channel Kraus operators for a
The channel acts as
ops
Return all
The identity term carries weight
def ops(d: int, p: float) -> List[pt.Tensor] [static]Implementation
def ops(d: int, p: float) -> List[pt.Tensor]:
import cmath
w = cmath.exp(2j * cmath.pi / d)
shift = pt.roll(pt.eye(d, dtype=C128), shifts=-1, dims=1)
clock = pt.diag(pt.tensor([w ** k for k in range(d)], dtype=C128))
weyl = []
for j in range(d):
for k in range(d):
W = pt.linalg.matrix_power(shift, j) @ pt.linalg.matrix_power(clock, k)
weyl.append(W)
result = []
for i, W in enumerate(weyl):
if i == 0:
weight = (1 - p * (d * d - 1) / (d * d)) ** 0.5
else:
weight = (p / (d * d)) ** 0.5
result.append(weight * W)
return resultclass PhaseDamp
Phase damping (dephasing) Kraus operators for a
Kills off-diagonal coherences without energy exchange. For
ops
Return Kraus operators for phase damping on a
def ops(d: int, p: float) -> List[pt.Tensor] [static]Implementation
def ops(d: int, p: float) -> List[pt.Tensor]:
K0 = pt.zeros((d, d), dtype=C128)
K0[0, 0] = 1.0
for j in range(1, d):
K0[j, j] = (1 - p) ** 0.5
result = [K0]
for j in range(1, d):
Kj = pt.zeros((d, d), dtype=C128)
Kj[j, j] = p ** 0.5
result.append(Kj)
return resultclass Reset
Reset channel Kraus operators for a
Collapses the qudit to
ops
Return Kraus operators for the reset channel.
def ops(d: int, p: float) -> List[pt.Tensor] [static]Implementation
def ops(d: int, p: float) -> List[pt.Tensor]:
result = []
for j in range(d):
Kj = pt.zeros((d, d), dtype=C128)
Kj[0, j] = p ** 0.5
result.append(Kj)
result.append((1 - p) ** 0.5 * pt.eye(d, dtype=C128))
return resultclass ThermalRelax
Thermal relaxation channel Kraus operators for a qubit (
Two-parameter model combining
ops
Return 4 Kraus operators for thermal relaxation on a qubit.
Decomposes combined
def ops(T1: float, T2: float, t: float) -> List[pt.Tensor] [static]Implementation
def ops(T1: float, T2: float, t: float) -> List[pt.Tensor]:
import math
e1 = math.exp(-t / T1)
e2 = math.exp(-t / T2)
p1 = 1 - e1
lam = e2 / math.sqrt(e1)
p_phi = (1 - lam) / 2
K0 = pt.tensor([[math.sqrt(1 - p_phi), 0.0], [0.0, math.sqrt((1 - p1) * (1 - p_phi))]], dtype=C128)
K1 = pt.tensor([[0.0, math.sqrt(p1 * (1 - p_phi))], [0.0, 0.0]], dtype=C128)
K2 = pt.tensor([[math.sqrt(p_phi), 0.0], [0.0, -math.sqrt((1 - p1) * p_phi)]], dtype=C128)
K3 = pt.tensor([[0.0, math.sqrt(p1 * p_phi)], [0.0, 0.0]], dtype=C128)
return [K0, K1, K2, K3]