Geometry

Site-selection vocabulary — broadcast ("distribution") vs. set ("region") geometries; see Design Philosophy for the conceptual split.

1D only

All geometries address sites on a one-dimensional chain (1:L). Higher-dimensional (2D+) circuit geometries are a planned future direction — see the project ROADMAP.

QuantumCircuitsMPS.AbstractGeometry — Type
AbstractGeometry

Abstract base type for all geometry specifications — the "where" of a gate application (apply!(state, gate, geometry)).

Geometries fall into two families, reported by the is_broadcast(geo) trait:

  • Broadcast ("distribution") geometries expand to $K \ge 1$ independent elements, each receiving its own gate application (and, inside apply_with_prob!, its own coin): AllSites, Bricklayer, EachSite.
  • Set ("region") geometries denote ONE region of sites, a single element: SingleSite, AdjacentPair, Sites, StaircaseLeft/ StaircaseRight, Pointer.

The canonical enumeration for either family is elements(geo, L, bc) -> Vector{Vector{Int}} (physical site indices). Dynamic geometries (staircases, Pointer) are MUTABLE — staircases advance after each application, Pointer moves only via move!.

Geometries always speak PHYSICAL site indices; backends translate to their internal (RAM) indexing via state.phy_ram.

source
QuantumCircuitsMPS.Sites — Type
Sites(sites)

Set geometry: ONE region made of the given sites (a range or collection of distinct Ints, kept in the given order). A gate applied to Sites(c) must have support(gate) == length(c) (see validate_support). A repeated site (e.g. Sites([2, 2])) is rejected: no gate acts on the same site twice within one region, and backends given such a region would produce a non-unitary update.

Expands to a single element [collect(sites)]. For applying a gate independently at each site, use EachSite instead.

source
QuantumCircuitsMPS.EachSite — Type
EachSite(sites)

Broadcast geometry: apply a single-site gate independently at each site in sites (a range or collection of Ints, kept in the given order).

Expands to [[i] for i in sites] — one element per site. Example: SRN bulk eligibility is EachSite(2:L-1).

See also AllSites (all L sites) and Sites (one multi-site region, NOT a broadcast).

source
QuantumCircuitsMPS.Bricklayer — Type
Bricklayer(parity::Symbol)

Geometry for bricklayer gate application pattern.

Nearest-neighbor (NN) modes:

  • :odd parity → pairs (1,2), (3,4), (5,6), ...
  • :even parity → pairs (2,3), (4,5), ... plus (L,1) for PBC
  • :nn parity → ALL NN pairs (combines :odd + :even)

Next-nearest-neighbor (NNN) modes (4 sublayers covering all 12 NNN pairs for L=12):

  • :nnn_odd_1 parity → pairs (1,3), (5,7), (9,11), ... (stride 4, offset 1)
  • :nnn_odd_2 parity → pairs (3,5), (7,9), (11,1), ... (stride 4, offset 3, PBC wrap)
  • :nnn_even_1 parity → pairs (2,4), (6,8), (10,12), ... (stride 4, offset 2)
  • :nnn_even_2 parity → pairs (4,6), (8,10), (12,2), ... (stride 4, offset 4, PBC wrap)
  • :nnn parity → ALL NNN pairs (combines all 4 sublayers)

apply! loops internally over all pairs.

Odd L under periodic boundary conditions

An odd-length ring cannot be tiled by disjoint NN pairs. At odd L with bc = :periodic, no wrap pair is added to either single layer: :odd leaves site L unpaired and :even leaves site 1 unpaired, and the wrap bond (L, 1) is gated by NEITHER layer — an alternating :odd/:even brickwork circuit is effectively open across that bond. A one-time warning is emitted at circuit-build / apply! time (internal helper _warn_bricklayer_odd_pbc); double-check the intended pattern with print_circuit. :nn (ALL NN bonds, not a single layer) still enumerates all L ring bonds and does not warn.

NNN sublayers at L ≡ 2 (mod 4) under periodic boundary conditions

The NNN bonds of an even-L ring form two rings (odd sites and even sites) of length $L/2$. For $L \equiv 0 \pmod 4$ each splits into two disjoint pair layers, so the four sublayers are proper brickwork layers. For $L \equiv 2 \pmod 4$ (L = 6, 10, 14, ...) $L/2$ is odd and no such split exists: the wrap pair (L-1, 1) of :nnn_odd_2 shares site L-1 with its last bulk pair (L-3, L-1), and the wrap pair (L, 2) of :nnn_even_2 shares site L with (L-2, L). The enumeration is kept (every NNN bond is still gated exactly once by :nnn / the four sublayers together), but the two gates sharing a site are applied sequentially in enumeration order, so such a sublayer is not a depth-1 layer and the result depends on that order for non-commuting gates. A one-time warning is emitted at circuit-build / apply! time (same helper). :nnn_odd_1, :nnn_even_1, :nnn, and open boundaries are unaffected.

source
QuantumCircuitsMPS.StaircaseLeft — Type
StaircaseLeft(start_position::Int; range::Int=1)

Staircase that moves left: applies at (pos, pos+range), then decrements pos.

Arguments

  • start_position: Initial position
  • range: Distance between sites (default 1 for nearest neighbors)

Examples

StaircaseLeft(4)           # NN: (4,5), (3,4), (2,3), ...
StaircaseLeft(4; range=2)  # NNN: (4,6), (3,5), (2,4), ...
source
QuantumCircuitsMPS.StaircaseRight — Type
StaircaseRight(start_position::Int; range::Int=1)

Staircase that moves right: applies at (pos, pos+range), then advances pos.

Arguments

  • start_position: Initial position
  • range: Distance between sites (default 1 for nearest neighbors)

Examples

StaircaseRight(1)           # NN: (1,2), (2,3), ...
StaircaseRight(1; range=2)  # NNN: (1,3), (2,4), ...
source
QuantumCircuitsMPS.Pointer — Type
Pointer(start_position::Int)

A bidirectional pointer that can move left or right. Unlike StaircaseLeft/StaircaseRight which are unidirectional, Pointer supports explicit direction control via move!().

For two-qubit gates, the pair is (position, position+1) with PBC wrap.

source
QuantumCircuitsMPS.move! — Function
move!(p::Pointer, direction::Symbol, L::Int, bc::Symbol=:periodic)

Move the pointer in the specified direction.

  • direction = :left → position decreases (wraps L → 1 for PBC)
  • direction = :right → position increases (wraps 1 → L for PBC)

This is the PUBLIC API for pointer movement, unlike advance!() which is internal.

source
QuantumCircuitsMPS.elements — Function
elements(geo::AbstractGeometry, L::Int, bc::Symbol) -> Vector{Vector{Int}}

Canonical element enumeration for a geometry: each inner vector is the sites for one gate application. This is the SINGLE source of truth consolidating the former get_pairs / get_compound_elements duplicates.

Broadcast geometries return $K \ge 1$ elements in their documented canonical order (API contract — RNG coin consumption follows this order):

  • AllSites() → [[1], [2], ..., [L]]
  • EachSite(c) → [[i] for i in c] (collection order)
  • Bricklayer(parity) → pairs exactly as documented in the README parity table (e.g. :odd → [[1,2],[3,4],...]; :even → [[2,3],...,[L,1]] for PBC at even L; :nn = :odd then :even plus the (L,1) wrap bond; :nnn = sublayers 1,2,3,4). At odd L, single layers (:odd, :even) leave one site unpaired rather than double-touching a site — see the parity branches below. The NNN wrap sublayers :nnn_odd_2 / :nnn_even_2 under PBC at $L \equiv 2 \pmod 4$ are NOT disjoint: the wrap pair shares a site with the last bulk pair ((L-3,L-1),(L-1,1) resp. (L-2,L),(L,2)), because the odd-site and even-site NNN rings then have odd length $L/2$; the enumeration is kept as an API contract. Both cases emit a one-time warning at circuit-build / apply! time (helper _warn_bricklayer_odd_pbc in Geometry/static.jl — deliberately NOT called here: elements sits in performance-critical loops).

Set geometries return a single element [[sites...]]:

  • SingleSite(i) → [[i]]
  • AdjacentPair(i) → [[i, i+1]] (PBC wrap at L)
  • Sites(c) → [collect(c)]
  • StaircaseLeft/Right → [[pos, pos+range]] at the CURRENT position (PBC wrap via mod1; OBC out-of-bounds throws ArgumentError)
  • Pointer → [[pos, pos+1]] at the current position (PBC wrap at L)
source
QuantumCircuitsMPS.element_count — Function
element_count(geo::AbstractGeometry, L::Int, bc::Symbol) -> Int

Number of elements (K) that geo expands to via elements. Broadcast geometries give $K \ge 1$; set geometries always give 1. Used by builder validation (equal-K rule across stochastic outcomes).

source
QuantumCircuitsMPS.is_broadcast — Function
is_broadcast(geo::AbstractGeometry) -> Bool

Trait: true for broadcast ("distribution") geometries that expand to multiple independent elements (AllSites, Bricklayer, EachSite); false for set ("region") geometries that denote a single region (SingleSite, AdjacentPair, Sites, StaircaseLeft/StaircaseRight, Pointer).

source