Skip to main content

omnibias.convex.arrangement.jax

0.1.0a2AlphaPython >=3.10AGPL / commercial

Differentiable LP and QP solver paths, barrier methods, KKT sensitivities, and scoped optimality evidence.

import omnibias.convex.arrangement.jax
Module contract & mathematical conventions

JAX twin of arrangement-LP soft membership (theory 03-02).

soft_membership matches the numpy / torch twins at float64 (jax_enable_x64). Soft mode is temperature collapse (beta -> inf, feasibility), not the founding bias collapse (delta -> 0). Do not conflate the two.

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.

Imports & aliases​

These names share a definition with another public module. Follow a name for its full contract, parameters, and examples.

Import from this moduleCanonical reference
DiffModeomnibias.convex.arrangement.DiffMode
LPOutputomnibias.convex.arrangement.LPOutput
LearnedPolytopeomnibias.convex.arrangement.LearnedPolytope
named_pentagonomnibias.convex.arrangement.named_pentagon
soft_cell_gap_boundomnibias.convex.arrangement.soft_cell_gap_bound
solve_arrangement_lpomnibias.convex.arrangement.solve_arrangement_lp
sound_lower_boundomnibias.convex.arrangement.sound_lower_bound
CLASS

LPLayer​

omnibias.convex.arrangement.jax.LPLayerSource ↗
class LPLayer

Learned-polytope LP. mode is returned so the gradient is interpretable.

Parameters

NameType & defaultContract
modepositional-or-keywordDiffModeRequiredSee the operation contract and implementation below.
betakeyword-onlyfloat | NoneDefault: NoneSee the operation contract and implementation below.

Fields & methods

__init__method
__init__(self, mode: DiffMode, *, beta: float | None=None) -> None

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

Parameters

NameType & defaultContract
modepositional-or-keywordDiffModeRequiredSee the operation contract and implementation below.
betakeyword-onlyfloat | NoneDefault: NoneSee the operation contract and implementation below.

Returns: None

Validation & failure cases
  • When self.mode is DiffMode.SOFT and self.beta <= 0.0, raises ValueError('SOFT mode needs beta > 0').
Method implementation
    def __init__(self, mode: DiffMode, *, beta: float | None = None) -> None:
        self.mode = DiffMode(mode)
        self.beta = 8.0 if beta is None else float(beta)
        if self.mode is DiffMode.SOFT and self.beta <= 0.0:
            raise ValueError("SOFT mode needs beta > 0")
View source ↗
forwardmethod
forward(self, polytope: LearnedPolytope, c: Array) -> LPOutput

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

Parameters

NameType & defaultContract
polytopepositional-or-keywordLearnedPolytopeRequiredSee the operation contract and implementation below.
cpositional-or-keywordArrayRequiredSee the operation contract and implementation below.

Returns: LPOutput

Method implementation
    def forward(self, polytope: LearnedPolytope, c: Array) -> LPOutput:
        cv = jnp.asarray(c, dtype=jnp.float64)
        return solve_arrangement_lp(polytope, cv, mode=self.mode, beta=self.beta)
View source ↗
modeattribute
mode = DiffMode(mode)

Public instance attribute assigned by __init__. The source assignment is mode = DiffMode(mode); it describes instance state, not a literal constructor default.

View source ↗
betaattribute
beta = 8.0 if beta is None else float(beta)

Public instance attribute assigned by __init__. The source assignment is beta = 8.0 if beta is None else float(beta); it describes instance state, not a literal constructor default.

View source ↗
Read the implementation
class LPLayer:
    """Learned-polytope LP. ``mode`` is returned so the gradient is interpretable."""

    def __init__(self, mode: DiffMode, *, beta: float | None = None) -> None:
        self.mode = DiffMode(mode)
        self.beta = 8.0 if beta is None else float(beta)
        if self.mode is DiffMode.SOFT and self.beta <= 0.0:
            raise ValueError("SOFT mode needs beta > 0")

    def forward(self, polytope: LearnedPolytope, c: Array) -> LPOutput:
        cv = jnp.asarray(c, dtype=jnp.float64)
        return solve_arrangement_lp(polytope, cv, mode=self.mode, beta=self.beta)
FUNCTION

soft_membership​

omnibias.convex.arrangement.jax.soft_membershipSource ↗
soft_membership(normals: Array, offsets: Array, x: Array, *, beta: float) -> Array

prod_i sigma(beta (b_i - a_i · x)).

Parameters

NameType & defaultContract
normalspositional-or-keywordArrayRequiredSee the operation contract and implementation below.
offsetspositional-or-keywordArrayRequiredSee the operation contract and implementation below.
xpositional-or-keywordArrayRequiredSee the operation contract and implementation below.
betakeyword-onlyfloatRequiredSee the operation contract and implementation below.
ReturnsArray
Executed regression · g6 soft membership parity

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_soft_membership_parity() -> None:
    poly, _c, _opt = named_pentagon()
    x = np.array([1.5, 1.5], dtype=np.float64)
    ref = float(soft_membership(poly, x, beta=5.0))
    torch = pytest.importorskip("torch")
    tw = __import__("omnibias.convex.arrangement.torch", fromlist=["soft_membership"]).soft_membership
    got_t = float(tw(torch.as_tensor(poly.normals), torch.as_tensor(poly.offsets), torch.as_tensor(x), beta=5.0))
    assert math.isclose(got_t, ref, rel_tol=0.0, abs_tol=1e-15)
    jax = pytest.importorskip("jax")
    jax.config.update("jax_enable_x64", True)
    jw = __import__("omnibias.convex.arrangement.jax", fromlist=["soft_membership"]).soft_membership
    got_j = float(np.asarray(jw(poly.normals, poly.offsets, x, beta=5.0)))
    assert math.isclose(got_j, ref, rel_tol=0.0, abs_tol=2e-15)
python -m pytest "packages/omnibias-convex/tests/test_arrangement_lp.py::test_g6_soft_membership_parity" -q
Read the implementation
def soft_membership(normals: Array, offsets: Array, x: Array, *, beta: float) -> Array:
    """``prod_i sigma(beta (b_i - a_i · x))``."""
    a = jnp.asarray(normals, dtype=jnp.float64)
    b = jnp.asarray(offsets, dtype=jnp.float64).reshape(-1)
    xv = jnp.asarray(x, dtype=jnp.float64)
    if xv.ndim == 1:
        slack = b - a @ xv
        return jnp.prod(jax_sigmoid(float(beta) * slack))
    slack = b[None, :] - xv @ a.T
    return jnp.prod(jax_sigmoid(float(beta) * slack), axis=-1)