omnibias.graph.arrangement.torch
Spectral graph operators and differentiable relaxations for ordering, assignment, and graph-structured learning.
import omnibias.graph.arrangement.torchModule contract & mathematical conventions
Face-Net (torch; theory 02-02). Temperature collapse; subgraph sampling.
Shared formulas do not imply universal floating-point identity. Verify dtype, shape, derivative-order support, and the stated numerical assumptions for the path you use.
FaceNet
omnibias.graph.arrangement.FaceNetSource ↗class FaceNet(nn.Module)Message passing on a discovered arrangement graph. Not a complete lattice.
Parameters
| Name | Type & default | Contract |
|---|---|---|
arrangement_dimpositional-or-keyword | intRequired | See the operation contract and implementation below. |
hiddenpositional-or-keyword | intRequired | See the operation contract and implementation below. |
roundspositional-or-keyword | intRequired | See the operation contract and implementation below. |
betakeyword-only | floatDefault: 5.0 | See the operation contract and implementation below. |
dtypekeyword-only | torch.dtype | NoneDefault: None | See the operation contract and implementation below. |
Executed regression · g6 torch runs
Recorded coverage confirms this test executed the API body. This example belongs to the pinned upstream test suite. It may use fixtures and imports from its full file. Run it from that checkout with its test dependencies installed.
def test_g6_torch_runs() -> None:
pytest.importorskip("torch")
import torch
from omnibias.graph.arrangement.torch import FaceNet
torch.set_default_dtype(torch.float64)
arr = _square()
samples = np.array([[0.0, 0.0], [2.0, 0.0], [0.0, 2.0], [-2.0, 0.0], [0.0, -2.0]])
graph = build_arrangement_graph(arr, samples)
net = FaceNet(2, hidden=4, rounds=2, dtype=torch.float64)
out = net(graph, arr)
assert out.shape[0] == len(graph.cells)
assert torch.isfinite(out).all()python -m pytest "packages/omnibias-graph/tests/test_arrangement.py::test_g6_torch_runs" -qFields & methods
__init__method
__init__(self, arrangement_dim: int, hidden: int, rounds: int, *, beta: float=5.0, dtype: torch.dtype | None=None) -> NoneSee the class contract above and the exact method implementation below.
Parameters
| Name | Type & default | Contract |
|---|---|---|
arrangement_dimpositional-or-keyword | intRequired | See the operation contract and implementation below. |
hiddenpositional-or-keyword | intRequired | See the operation contract and implementation below. |
roundspositional-or-keyword | intRequired | See the operation contract and implementation below. |
betakeyword-only | floatDefault: 5.0 | See the operation contract and implementation below. |
dtypekeyword-only | torch.dtype | NoneDefault: None | See the operation contract and implementation below. |
Returns: None
Validation & failure cases
- When
rounds < 1, raisesValueError('rounds must be >= 1').
Executed regression · g6 torch runs
Recorded coverage confirms this test executed the API body. This example belongs to the pinned upstream test suite. It may use fixtures and imports from its full file. Run it from that checkout with its test dependencies installed.
def test_g6_torch_runs() -> None:
pytest.importorskip("torch")
import torch
from omnibias.graph.arrangement.torch import FaceNet
torch.set_default_dtype(torch.float64)
arr = _square()
samples = np.array([[0.0, 0.0], [2.0, 0.0], [0.0, 2.0], [-2.0, 0.0], [0.0, -2.0]])
graph = build_arrangement_graph(arr, samples)
net = FaceNet(2, hidden=4, rounds=2, dtype=torch.float64)
out = net(graph, arr)
assert out.shape[0] == len(graph.cells)
assert torch.isfinite(out).all()python -m pytest "packages/omnibias-graph/tests/test_arrangement.py::test_g6_torch_runs" -qMethod implementation
def __init__(
self,
arrangement_dim: int,
hidden: int,
rounds: int,
*,
beta: float = 5.0,
dtype: torch.dtype | None = None,
) -> None:
super().__init__()
if rounds < 1:
raise ValueError("rounds must be >= 1")
self.rounds = int(rounds)
self.beta = float(beta)
dt = torch.get_default_dtype() if dtype is None else dtype
in_dim = 2 + int(arrangement_dim)
self.lift = nn.Linear(in_dim, hidden, dtype=dt)
self.msg = nn.Linear(hidden + 1, hidden, dtype=dt)
self.readout = nn.Linear(hidden, 1, dtype=dt)forwardmethod
forward(self, graph: ArrangementGraph, arr: Arrangement) -> TensorSee the class contract above and the exact method implementation below.
Parameters
| Name | Type & default | Contract |
|---|---|---|
graphpositional-or-keyword | ArrangementGraphRequired | See the operation contract and implementation below. |
arrpositional-or-keyword | ArrangementRequired | See the operation contract and implementation below. |
Returns: Tensor
Executed regression · g6 torch runs
Recorded coverage confirms this test executed the API body. This example belongs to the pinned upstream test suite. It may use fixtures and imports from its full file. Run it from that checkout with its test dependencies installed.
def test_g6_torch_runs() -> None:
pytest.importorskip("torch")
import torch
from omnibias.graph.arrangement.torch import FaceNet
torch.set_default_dtype(torch.float64)
arr = _square()
samples = np.array([[0.0, 0.0], [2.0, 0.0], [0.0, 2.0], [-2.0, 0.0], [0.0, -2.0]])
graph = build_arrangement_graph(arr, samples)
net = FaceNet(2, hidden=4, rounds=2, dtype=torch.float64)
out = net(graph, arr)
assert out.shape[0] == len(graph.cells)
assert torch.isfinite(out).all()python -m pytest "packages/omnibias-graph/tests/test_arrangement.py::test_g6_torch_runs" -qMethod implementation
def forward(self, graph: ArrangementGraph, arr: Arrangement) -> Tensor:
feats = torch.tensor(node_features(arr, graph, beta=self.beta), dtype=self.lift.weight.dtype)
h = torch.tanh(self.lift(feats))
n = h.shape[0]
adj = torch.zeros(n, n, dtype=h.dtype)
crossed = torch.zeros(n, n, dtype=h.dtype)
for u, v, k in graph.edges:
adj[u, v] = adj[v, u] = 1.0
crossed[u, v] = crossed[v, u] = float(k)
for _ in range(self.rounds):
msgs = []
for i in range(n):
acc = torch.zeros_like(h[i])
deg = 0.0
for j in range(n):
if float(adj[i, j].detach()) <= 0.0:
continue
cat = torch.cat([h[j], crossed[i, j].reshape(1)])
acc = acc + torch.tanh(self.msg(cat))
deg += 1.0
msgs.append(acc / max(deg, 1.0))
h = h + torch.stack(msgs)
return self.readout(h).squeeze(-1)roundsattribute
rounds = int(rounds)Public instance attribute assigned by __init__. The source assignment is rounds = int(rounds); it describes instance state, not a literal constructor default.
betaattribute
beta = float(beta)Public instance attribute assigned by __init__. The source assignment is beta = float(beta); it describes instance state, not a literal constructor default.
liftattribute
lift = nn.Linear(in_dim, hidden, dtype=dt)Public instance attribute assigned by __init__. The source assignment is lift = nn.Linear(in_dim, hidden, dtype=dt); it describes instance state, not a literal constructor default.
msgattribute
msg = nn.Linear(hidden + 1, hidden, dtype=dt)Public instance attribute assigned by __init__. The source assignment is msg = nn.Linear(hidden + 1, hidden, dtype=dt); it describes instance state, not a literal constructor default.
readoutattribute
readout = nn.Linear(hidden, 1, dtype=dt)Public instance attribute assigned by __init__. The source assignment is readout = nn.Linear(hidden, 1, dtype=dt); it describes instance state, not a literal constructor default.
Read the implementation
class FaceNet(nn.Module):
"""Message passing on a discovered arrangement graph. Not a complete lattice."""
def __init__(
self,
arrangement_dim: int,
hidden: int,
rounds: int,
*,
beta: float = 5.0,
dtype: torch.dtype | None = None,
) -> None:
super().__init__()
if rounds < 1:
raise ValueError("rounds must be >= 1")
self.rounds = int(rounds)
self.beta = float(beta)
dt = torch.get_default_dtype() if dtype is None else dtype
in_dim = 2 + int(arrangement_dim)
self.lift = nn.Linear(in_dim, hidden, dtype=dt)
self.msg = nn.Linear(hidden + 1, hidden, dtype=dt)
self.readout = nn.Linear(hidden, 1, dtype=dt)
def forward(self, graph: ArrangementGraph, arr: Arrangement) -> Tensor:
feats = torch.tensor(node_features(arr, graph, beta=self.beta), dtype=self.lift.weight.dtype)
h = torch.tanh(self.lift(feats))
n = h.shape[0]
adj = torch.zeros(n, n, dtype=h.dtype)
crossed = torch.zeros(n, n, dtype=h.dtype)
for u, v, k in graph.edges:
adj[u, v] = adj[v, u] = 1.0
crossed[u, v] = crossed[v, u] = float(k)
for _ in range(self.rounds):
msgs = []
for i in range(n):
acc = torch.zeros_like(h[i])
deg = 0.0
for j in range(n):
if float(adj[i, j].detach()) <= 0.0:
continue
cat = torch.cat([h[j], crossed[i, j].reshape(1)])
acc = acc + torch.tanh(self.msg(cat))
deg += 1.0
msgs.append(acc / max(deg, 1.0))
h = h + torch.stack(msgs)
return self.readout(h).squeeze(-1)Other public import paths
omnibias.graph.arrangement.FaceNetomnibias.graph.arrangement.torch.FaceNet