Skip to content

tn_noise_learning.topology#

Qubit connectivity on which an LPDO places its virtual bonds.

Topology dataclass #

Topology(
    num_sites: int, edges: tuple[tuple[int, int], ...]
)

Graph of qubit sites 0..num_sites-1 and the edges that carry virtual bonds.

Site integers are the qubit order of the dataset and of the Qiskit circuit. Edges are stored normalised as sorted (i, j) pairs with i < j, without duplicates.

PARAMETER DESCRIPTION
num_sites

number of qubits.

TYPE: int

edges

pairs of sites connected by a bond.

TYPE: tuple[tuple[int, int], ...]

__post_init__ #

__post_init__() -> None

Validate sites and normalise the edge list.

Source code in src/tn_noise_learning/topology.py
43
44
45
46
47
48
49
50
51
52
53
54
def __post_init__(self) -> None:
    """Validate sites and normalise the edge list."""
    if self.num_sites < 1:
        raise ValueError(f"num_sites must be positive, got {self.num_sites}.")
    normalised = set()
    for i, j in self.edges:
        if i == j:
            raise ValueError(f"Self-loop on site {i} is not allowed.")
        if not (0 <= i < self.num_sites and 0 <= j < self.num_sites):
            raise ValueError(f"Edge ({i}, {j}) is outside the site range 0..{self.num_sites - 1}.")
        normalised.add((min(i, j), max(i, j)))
    object.__setattr__(self, "edges", tuple(sorted(normalised)))

chain classmethod #

chain(num_sites: int) -> Topology

Open 1D chain 0 - 1 - ... - (num_sites - 1).

Source code in src/tn_noise_learning/topology.py
56
57
58
59
@classmethod
def chain(cls, num_sites: int) -> Topology:
    """Open 1D chain ``0 - 1 - ... - (num_sites - 1)``."""
    return cls(num_sites, tuple(qtn.edges_1d_chain(num_sites)))

degree #

degree(site: int) -> int

Number of bonds attached to site.

Source code in src/tn_noise_learning/topology.py
79
80
81
def degree(self, site: int) -> int:
    """Number of bonds attached to ``site``."""
    return len(self.neighbors(site))

from_edges classmethod #

from_edges(
    edges: Iterable[tuple[int, int]],
    num_sites: int | None = None,
) -> Topology

Custom topology from an edge list; num_sites defaults to the largest site index plus one.

Source code in src/tn_noise_learning/topology.py
67
68
69
70
71
72
73
@classmethod
def from_edges(cls, edges: Iterable[tuple[int, int]], num_sites: int | None = None) -> Topology:
    """Custom topology from an edge list; ``num_sites`` defaults to the largest site index plus one."""
    pairs = tuple((int(i), int(j)) for i, j in edges)
    if num_sites is None:
        num_sites = 1 + max((max(e) for e in pairs), default=0)
    return cls(num_sites, pairs)

neighbors #

neighbors(site: int) -> tuple[int, ...]

Sites bonded to site, in ascending order.

Source code in src/tn_noise_learning/topology.py
75
76
77
def neighbors(self, site: int) -> tuple[int, ...]:
    """Sites bonded to ``site``, in ascending order."""
    return tuple(sorted(j if i == site else i for i, j in self.edges if site in (i, j)))

square classmethod #

square(rows: int, cols: int) -> Topology

Open 2D square lattice, with site (r, c) mapped row-major to r * cols + c.

Source code in src/tn_noise_learning/topology.py
61
62
63
64
65
@classmethod
def square(cls, rows: int, cols: int) -> Topology:
    """Open 2D square lattice, with site ``(r, c)`` mapped row-major to ``r * cols + c``."""
    edges = [(r1 * cols + c1, r2 * cols + c2) for (r1, c1), (r2, c2) in qtn.edges_2d_square(rows, cols)]
    return cls(rows * cols, tuple(edges))