tn_noise_learning.lpdo#
Locally purified density operator (LPDO) representation of a quantum channel.
Site j holds a Kraus tensor V_j with axes (*bonds to neighbours in ascending order, kraus, out, in).
The channel is Λ(ρ) = Σ_kr V ρ V†; the conjugate half of the network is never stored, it is generated from
the Kraus half by full_network with the index names below.
| leg | Kraus half | conjugate half |
|---|---|---|
| bond on edge (i,j) | v{i}_{j} |
w{i}_{j} |
| kraus (shared) | kr{j} |
kr{j} |
| channel output | kn{j} |
bn{j} |
| channel input | k{j} |
b{j} |
LPDO
dataclass
#
LPDO(topology: Topology, tensors: list[ndarray])
Quantum channel as an LPDO on a topology.
| PARAMETER | DESCRIPTION |
|---|---|
topology
|
site connectivity.
TYPE:
|
tensors
|
one Kraus tensor per site in canonical axis order
|
__post_init__ #
__post_init__() -> None
Validate tensor count, axis counts, physical dimensions and bond sizes.
Source code in src/tn_noise_learning/lpdo.py
108 109 110 111 112 113 114 115 116 117 118 119 120 121 | |
bond_size #
bond_size(site: int, neighbor: int) -> int
Size of the bond leg of site pointing at neighbor.
Source code in src/tn_noise_learning/lpdo.py
138 139 140 | |
distance #
distance(other: LPDO) -> float
Squared normalised Frobenius distance ‖Λ − Λ'‖_F² / 4**num_sites.
Source code in src/tn_noise_learning/lpdo.py
194 195 196 | |
from_group
classmethod
#
from_group(group: Group) -> LPDO
Read an LPDO written by to_group.
Source code in src/tn_noise_learning/lpdo.py
214 215 216 217 218 219 | |
from_network
classmethod
#
from_network(
topology: Topology, kraus_tn: TensorNetwork
) -> LPDO
Rebuild from a Kraus network with the index names of kraus_inds.
Source code in src/tn_noise_learning/lpdo.py
164 165 166 167 168 169 170 171 172 173 | |
identity
classmethod
#
identity(topology: Topology) -> LPDO
Identity channel: one Kraus operator 𝟙 per site, all bonds of size one.
Source code in src/tn_noise_learning/lpdo.py
153 154 155 156 157 158 159 160 161 162 | |
kraus_network #
kraus_network() -> qtn.TensorNetwork
Tensor network of the Kraus half, tagged I{j} and V.
Source code in src/tn_noise_learning/lpdo.py
175 176 177 178 179 180 181 182 | |
load
classmethod
#
load(path: str | Path) -> LPDO
Load from a zarr store written by save.
Source code in src/tn_noise_learning/lpdo.py
225 226 227 228 | |
network #
network() -> qtn.TensorNetwork
Full LPDO network with open legs kn, k (ket) and bn, b (bra) per site.
Source code in src/tn_noise_learning/lpdo.py
184 185 186 | |
random
classmethod
#
random(
topology: Topology,
bond_dim: int,
kraus_dim: int,
seed: int | None = None,
) -> LPDO
Complex Gaussian Kraus tensors scaled so that the expected trace is 2**num_sites.
Source code in src/tn_noise_learning/lpdo.py
142 143 144 145 146 147 148 149 150 151 | |
save #
save(path: str | Path) -> None
Save to a zarr store at path.
Source code in src/tn_noise_learning/lpdo.py
221 222 223 | |
to_dense #
to_dense() -> np.ndarray
Superoperator matrix Σ_m K_m ⊗ conj(K_m) with site 0 most significant (small systems only).
Source code in src/tn_noise_learning/lpdo.py
198 199 200 201 202 203 204 205 | |
to_group #
to_group(group: Group) -> None
Write topology and tensors into an open zarr group.
Source code in src/tn_noise_learning/lpdo.py
207 208 209 210 211 212 | |
trace #
trace() -> float
Trace of the channel's Choi-like network, 2**num_sites for a trace-preserving channel.
Source code in src/tn_noise_learning/lpdo.py
188 189 190 191 192 | |
bond_ind #
bond_ind(i: int, j: int, *, dagger: bool = False) -> str
Virtual bond index on edge (i, j).
Source code in src/tn_noise_learning/lpdo.py
54 55 56 57 | |
dagger_rename #
dagger_rename(topology: Topology) -> dict[str, str]
Index renaming that turns the Kraus half into the conjugate half.
Source code in src/tn_noise_learning/lpdo.py
80 81 82 83 84 85 86 | |
full_network #
full_network(
kraus_tn: TensorNetwork, topology: Topology
) -> qtn.TensorNetwork
Join a Kraus network with its conjugate; works on JAX tracers inside a jitted loss.
Source code in src/tn_noise_learning/lpdo.py
89 90 91 92 | |
input_ind #
input_ind(site: int, *, dagger: bool = False) -> str
Channel input (ket side, or bra side when dagger).
Source code in src/tn_noise_learning/lpdo.py
70 71 72 | |
kraus_ind #
kraus_ind(site: int) -> str
Kraus index shared by V_j and its conjugate.
Source code in src/tn_noise_learning/lpdo.py
60 61 62 | |
kraus_inds #
kraus_inds(
topology: Topology, site: int
) -> tuple[str, ...]
Index names of V_site in canonical axis order.
Source code in src/tn_noise_learning/lpdo.py
75 76 77 | |
output_ind #
output_ind(site: int, *, dagger: bool = False) -> str
Channel output (ket side, or bra side when dagger).
Source code in src/tn_noise_learning/lpdo.py
65 66 67 | |
site_tag #
site_tag(site: int) -> str
Tag shared by the two tensors of site.
Source code in src/tn_noise_learning/lpdo.py
49 50 51 | |