circle_bundles.O2Cocycle
- class circle_bundles.O2Cocycle(Omega, theta, det, err=None, ref_angle=0.0)[source]
Bases:
objectAn estimated O(2)-valued 1-cochain (typically a cocycle) on a cover nerve.
The primary field is
Omega, a dictionary mapping directed edges to 2×2 matrices:Omega[(j, k)] maps k-coordinates -> j-coordinates.
For convenience and downstream characteristic class computations, we also store determinant signs and rotation angles from a fixed-axis decomposition.
- Parameters:
- Omega
Dict mapping edges (j, k) to 2×2 matrices in O(2).
- Type:
Dict[Tuple[int, int], numpy.ndarray]
- theta
Dict mapping edges (j, k) to angles theta ∈ [0, 2π) such that Omega[(j,k)] = R(theta) * r(ref_angle) under this module’s convention.
- err
Optional dict mapping edges (j, k) to an RMS angular error (radians) on overlaps.
Notes
By default,
estimate_transitions()stores only canonical edges (j<k). Usecomplete_orientations()(orcomplete_edge_orientations()) if you want both directions (j,k) and (k,j).The edge convention is important: Omega[(j,k)] is designed so that it takes vectors in chart k to vectors in chart j.
Examples
Typical usage is via a bundle construction pipeline, but you can also estimate transitions directly from local angles:
cocycle, report = estimate_transitions(U, f, min_points=10) Omega_full = cocycle.complete_orientations().Omega omega_Z2 = cocycle.omega_Z2()
See also
estimate_transitionsFit O(2) transitions from overlap data.
complete_edge_orientationsLow-level helper to fill reversed edges by transposition.
- __init__(Omega, theta, det, err=None, ref_angle=0.0)
Methods
__init__(Omega, theta, det[, err, ref_angle])Return an equivalent cocycle with both edge orientations filled in.
omega_O1()Return the determinant-sign cochain as an O(1) (i.e. {±1}) valued 1-cochain.
omega_Z2()Convert determinants to a Z₂-valued 1-cochain.
orient_if_possible(edges, *[, n_vertices, ...])Attempt to gauge-transform the cocycle so that det=+1 on a chosen 1-skeleton.
restrict(edges)Restrict this cocycle to a specified set of edges.
Return the rotation angles as an R/Z-valued cochain represented in [0, 1).
Attributes
- omega_Z2()[source]
Convert determinants to a Z₂-valued 1-cochain.
- Returns:
Dict mapping edges to values in {0,1}, using the convention: det=+1 ↦ 0 and det=-1 ↦ 1.
- Return type:
omega
- omega_O1()[source]
Return the determinant-sign cochain as an O(1) (i.e. {±1}) valued 1-cochain.
- Returns:
Dict mapping edges to ±1.
- Return type:
omega
- theta_normalized()[source]
Return the rotation angles as an R/Z-valued cochain represented in [0, 1).
The stored
thetavalues are in radians in [0, 2π). This method converts to fractions of a full turn by dividing by 2π and reducing modulo 1.- Returns:
Dict mapping edges to floats in [0,1).
- Return type:
theta01
- restrict(edges)[source]
Restrict this cocycle to a specified set of edges.
- Parameters:
edges (Iterable[Tuple[int, int]]) – Iterable of edges. Edges are canonicalized to (min, max) form.
- Returns:
A new
O2Cocyclecontaining only entries whose edges appear in edges.- Return type:
cocycle_restricted
Notes
Any edge not present in the underlying dicts is silently skipped.
- complete_orientations()[source]
Return an equivalent cocycle with both edge orientations filled in.
For each undirected edge {j,k}, this ensures both directed entries are present:
Omega[(j,k)] maps k->j, Omega[(k,j)] = Omega[(j,k)]^T maps j->k.
Determinants, angles, and errors are also populated for the reversed edges in a way consistent with this module’s decomposition convention.
- Return type:
- orient_if_possible(edges, *, n_vertices=None, require_all_edges_present=True)[source]
Attempt to gauge-transform the cocycle so that det=+1 on a chosen 1-skeleton.
This is an “orientability test” for the determinant-sign cochain on the graph given by edges. We look for an assignment φ_j ∈ {+1, -1} to vertices such that for each undirected edge {j,k}:
φ_j * φ_k = det_{jk},
where det_{jk} is det(Omega_{jk}) on that edge.
If such a φ exists, we build a gauge g_j ∈ O(2) using the fixed reflection axis:
g_j = I if φ_j = +1 g_j = r(ref_angle) if φ_j = -1
and transform transitions by
Omega’_{jk} = g_j * Omega_{jk} * g_k^{-1},
which forces det(Omega’_{jk}) = +1 on all edges in the given 1-skeleton.
- Parameters:
edges (Iterable[Tuple[int, int]]) – The set of edges defining the 1-skeleton on which to test/orient.
n_vertices (int | None) – Number of vertices in the graph. If None, inferred as 1 + max index seen in edges.
require_all_edges_present (bool) – If True, returns (False, self, phi) immediately if any requested edge is missing from this cocycle’s determinant dict. If False, missing edges are ignored.
- Returns:
ok – True if the orientation assignment exists.
cocycle_oriented – If ok is True, the gauge-transformed cocycle; otherwise the original cocycle.
phi – An integer array of shape (n_vertices,) with entries in {+1,-1} giving φ.
- Return type:
Notes
This is useful when you want to reduce an O(2)-bundle problem to an S¹-bundle problem on a subcomplex where the bundle is orientable.