omnibias.struct.decision
Differentiable dynamic programs for sequences and parses, structured distributions, and finite-temperature bounds.
import omnibias.struct.decisionModule contract & mathematical conventions
omnibias.struct.decision: an embeddable, certified predict-then-optimize decision layer.
A bridge that makes omnibias-struct's ~omnibias.struct.certify_argmax **embeddable in a
network** as a differentiable *decision layer*:
- forward (relaxed decision):
softmax(beta * scores)-- differentiable, so a downstream decision-regret loss backpropagates into whatever produced the scores; - the
beta -> infhard decision:argmax(scores); - the certificate: the closed-form
~omnibias.struct.SelectionCertificate-- the value gapmax <= lse_beta <= max + log(N)/beta, the Gibbs mode-mass concentration lower bound, and (witheps) theL^infargmax-stability radiusmargin / 2.
The backend-neutral numpy helpers (certified_decision, decision_regret,
best_index) live here; the trainable ~omnibias.struct.decision.torch.DecisionLayer
lives in omnibias.struct.decision.torch (needs the torch extra).
Terminology: the beta -> inf annealing is the **feasibility / temperature** sense of
"collapse" (the same axis as omnibias-discrete / omnibias-qubo), **not** the
**founding bias collapse** (the multi-bias delta -> 0 limit to the closed-form derivative
sigma^(K-1)) -- the derivative tower is only the engine that differentiates lse_beta
exactly. This is the measure/mode face of that feasibility axis (a Gibbs law collapsing onto
its mode).
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 module | Canonical reference |
|---|---|
SelectionCertificate | omnibias.struct.SelectionCertificate |
best_index
omnibias.struct.decision.best_indexSource ↗best_index(scores: np.ndarray, *, axis: int=-1) -> np.ndarrayThe hard decision argmax(scores) along axis (the beta -> inf limit).
Parameters
| Name | Type & default | Contract |
|---|---|---|
scorespositional-or-keyword | np.ndarrayRequired | See the operation contract and implementation below. |
axiskeyword-only | intDefault: -1 | See the operation contract and implementation below. |
np.ndarrayExecuted regression · batched certificates and regret
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_batched_certificates_and_regret() -> None:
layer = DecisionLayer(beta=6.0)
scores = torch.tensor([[0.1, 0.9, 0.2], [1.2, 0.0, -0.4]], dtype=torch.float64)
certs = layer.certificates(scores)
assert len(certs) == 2
assert [c.argmax for c in certs] == [1, 0]
rewards = np.array([[0.0, 1.0, 0.5], [2.0, 0.1, 0.0]])
# perfect predictions -> zero regret
reg = decision_regret(scores.numpy(), rewards)
assert np.allclose(reg, 0.0)
# a wrong prediction on row 0 incurs regret 1.0
bad = np.array([[3.0, 0.9, 0.2], [1.2, 0.0, -0.4]])
assert np.isclose(decision_regret(bad, rewards).mean(), 0.5)
assert best_index(rewards, axis=1).tolist() == [1, 0]python -m pytest "packages/omnibias-struct/tests/test_decision_layer.py::test_batched_certificates_and_regret" -qRead the implementation
def best_index(scores: np.ndarray, *, axis: int = -1) -> np.ndarray:
r"""The hard decision ``argmax(scores)`` along ``axis`` (the ``beta -> inf`` limit)."""
idx: np.ndarray = np.asarray(np.argmax(np.asarray(scores, dtype=float), axis=axis))
return idxcertified_decision
omnibias.struct.decision.certified_decisionSource ↗certified_decision(scores: np.ndarray, beta: float, *, eps: float | None=None) -> SelectionCertificateCertify the beta -> inf decision collapse of softmax(beta * scores) (1-D scores).
Thin wrapper over omnibias.struct.certify_argmax: returns the closed-form
SelectionCertificate for a single decision over N options.
Parameters
| Name | Type & default | Contract |
|---|---|---|
scorespositional-or-keyword | np.ndarrayRequired | See the operation contract and implementation below. |
betapositional-or-keyword | floatRequired | See the operation contract and implementation below. |
epskeyword-only | float | NoneDefault: None | See the operation contract and implementation below. |
SelectionCertificateExecuted regression · layer certificate matches functional
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_layer_certificate_matches_functional() -> None:
layer = DecisionLayer(beta=8.0, eps=0.05)
scores = torch.tensor([1.0, -0.5, 0.3], dtype=torch.float64)
soft, cert = layer.certified(scores)
assert torch.allclose(soft, layer.forward(scores))
ref = certified_decision(scores.numpy(), beta=8.0, eps=0.05)
assert cert.argmax == ref.argmax
assert math.isclose(cert.gap_bound, ref.gap_bound, rel_tol=1e-12)
assert math.isclose(cert.p_max, ref.p_max, rel_tol=1e-9)python -m pytest "packages/omnibias-struct/tests/test_decision_layer.py::test_layer_certificate_matches_functional" -qRegression example · certificate is sound and hardens
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_certificate_is_sound_and_hardens() -> None:
scores = np.array([0.2, 1.5, 0.9, -0.3])
n = scores.size
c5 = certified_decision(scores, beta=5.0, eps=0.1)
c50 = certified_decision(scores, beta=50.0, eps=0.1)
assert c5.is_sound and c50.is_sound
# value gap is exactly log(N)/beta and shrinks as beta grows
assert math.isclose(c5.gap_bound, math.log(n) / 5.0, rel_tol=1e-12)
assert c50.gap_bound < c5.gap_bound
# mode mass concentrates toward 1
assert c50.p_max > c5.p_max
assert c50.p_max > 0.999
# decoded mode is the true argmax; robust radius is margin/2
assert c5.argmax == 1
assert math.isclose(c5.robust_radius, c5.margin / 2.0, rel_tol=1e-12)
# margin here is 1.5 - 0.9 = 0.6 > 2*eps = 0.2, so the decode is eps-stable
assert c5.argmax_stable is Truepython -m pytest packages/omnibias-struct/tests/test_decision_layer.py -k test_certificate_is_sound_and_hardens -qRead the implementation
def certified_decision(
scores: np.ndarray, beta: float, *, eps: float | None = None
) -> SelectionCertificate:
r"""Certify the ``beta -> inf`` decision collapse of ``softmax(beta * scores)`` (1-D scores).
Thin wrapper over :func:`omnibias.struct.certify_argmax`: returns the closed-form
:class:`SelectionCertificate` for a single decision over ``N`` options.
"""
return certify_argmax(np.asarray(scores, dtype=float).reshape(-1), beta, eps=eps)decision_regret
omnibias.struct.decision.decision_regretSource ↗decision_regret(scores_hat: np.ndarray, rewards: np.ndarray) -> np.ndarrayPer-sample realized regret of deciding argmax(scores_hat) under true rewards.
regret_i = max_j rewards[i, j] - rewards[i, argmax_j scores_hat[i, j]] (>= 0, 0
when the predicted-best option is truly best). scores_hat and rewards are
(n, N); returns the (n,) regret vector (mean it for the headline number).
Parameters
| Name | Type & default | Contract |
|---|---|---|
scores_hatpositional-or-keyword | np.ndarrayRequired | See the operation contract and implementation below. |
rewardspositional-or-keyword | np.ndarrayRequired | See the operation contract and implementation below. |
np.ndarrayExplicit validation & failure cases
- When
s.shape != r.shape or s.ndim != 2, raisesValueError('scores_hat and rewards must be the same (n, N) shape').
These are explicit source guards. Backend operations may also raise for invalid shapes, dtypes, or unsupported devices.
Executed regression · batched certificates and regret
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_batched_certificates_and_regret() -> None:
layer = DecisionLayer(beta=6.0)
scores = torch.tensor([[0.1, 0.9, 0.2], [1.2, 0.0, -0.4]], dtype=torch.float64)
certs = layer.certificates(scores)
assert len(certs) == 2
assert [c.argmax for c in certs] == [1, 0]
rewards = np.array([[0.0, 1.0, 0.5], [2.0, 0.1, 0.0]])
# perfect predictions -> zero regret
reg = decision_regret(scores.numpy(), rewards)
assert np.allclose(reg, 0.0)
# a wrong prediction on row 0 incurs regret 1.0
bad = np.array([[3.0, 0.9, 0.2], [1.2, 0.0, -0.4]])
assert np.isclose(decision_regret(bad, rewards).mean(), 0.5)
assert best_index(rewards, axis=1).tolist() == [1, 0]python -m pytest "packages/omnibias-struct/tests/test_decision_layer.py::test_batched_certificates_and_regret" -qRead the implementation
def decision_regret(scores_hat: np.ndarray, rewards: np.ndarray) -> np.ndarray:
r"""Per-sample realized regret of deciding ``argmax(scores_hat)`` under true ``rewards``.
``regret_i = max_j rewards[i, j] - rewards[i, argmax_j scores_hat[i, j]]`` (``>= 0``, ``0``
when the predicted-best option is truly best). ``scores_hat`` and ``rewards`` are
``(n, N)``; returns the ``(n,)`` regret vector (mean it for the headline number).
"""
s = np.asarray(scores_hat, dtype=float)
r = np.asarray(rewards, dtype=float)
if s.shape != r.shape or s.ndim != 2:
raise ValueError("scores_hat and rewards must be the same (n, N) shape")
picked = np.argmax(s, axis=1)
realized = r[np.arange(r.shape[0]), picked]
regret: np.ndarray = np.max(r, axis=1) - realized
return regret