Skip to main content

omnibias.graph.arrangement.torch

0.1.0a2AlphaPython >=3.10AGPL / commercial

Spectral graph operators and differentiable relaxations for ordering, assignment, and graph-structured learning.

import omnibias.graph.arrangement.torch
Module 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.

CLASS

FaceNet​

omnibias.graph.arrangement.FaceNetSource ↗
class FaceNet(nn.Module)

Message passing on a discovered arrangement graph. Not a complete lattice.

Parameters

NameType & defaultContract
arrangement_dimpositional-or-keywordintRequiredSee the operation contract and implementation below.
hiddenpositional-or-keywordintRequiredSee the operation contract and implementation below.
roundspositional-or-keywordintRequiredSee the operation contract and implementation below.
betakeyword-onlyfloatDefault: 5.0See the operation contract and implementation below.
dtypekeyword-onlytorch.dtype | NoneDefault: NoneSee 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" -q

Fields & methods

__init__method
__init__(self, arrangement_dim: int, hidden: int, rounds: int, *, beta: float=5.0, dtype: torch.dtype | None=None) -> None

See the class contract above and the exact method implementation below.

Parameters

NameType & defaultContract
arrangement_dimpositional-or-keywordintRequiredSee the operation contract and implementation below.
hiddenpositional-or-keywordintRequiredSee the operation contract and implementation below.
roundspositional-or-keywordintRequiredSee the operation contract and implementation below.
betakeyword-onlyfloatDefault: 5.0See the operation contract and implementation below.
dtypekeyword-onlytorch.dtype | NoneDefault: NoneSee the operation contract and implementation below.

Returns: None

Validation & failure cases
  • When rounds < 1, raises ValueError('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" -q
Method 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)
View source ↗
forwardmethod
forward(self, graph: ArrangementGraph, arr: Arrangement) -> Tensor

See the class contract above and the exact method implementation below.

Parameters

NameType & defaultContract
graphpositional-or-keywordArrangementGraphRequiredSee the operation contract and implementation below.
arrpositional-or-keywordArrangementRequiredSee 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" -q
Method 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)
View source ↗
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.

View source ↗
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.

View source ↗
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.

View source ↗
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.

View source ↗
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.

View source ↗
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.FaceNet
  • omnibias.graph.arrangement.torch.FaceNet