omnibias.core.bell
Coefficient recurrences, activation contracts, jet algebra, and verified arithmetic shared by the numerical backends.
import omnibias.core.bellModule contract & mathematical conventions
Bell polynomials and Faà di Bruno coefficients (pure Python).
This module supplies the combinatorial core of the *multi-layer jet
composition* primitive. It is backend-agnostic (no torch / jax / numpy), in the
same spirit as omnibias.core.polynomials: only integer combinatorics live
here, so the torch and jax jet kernels are bit-identical by construction.
Faà di Bruno's formula expresses the n-th derivative of a composition
b(t) = sigma(u(t)) in terms of the derivatives of sigma and u:
b^{(n)} = \sum_{k=1}^{n} \sigma^{(k)}\!\big(u^{(0)}\big)\, B_{n,k}\!\big(u^{(1)}, u^{(2)}, \dots, u^{(n-k+1)}\big),
where B_{n,k} is the *partial (incomplete) exponential Bell polynomial*
B_{n,k}(x_1,\dots,x_{n-k+1}) = \sum \frac{n!}{j_1!\,j_2!\cdots}\, \prod_{i\ge 1}\Big(\frac{x_i}{i!}\Big)^{j_i},
the sum taken over all non-negative integer sequences (j_i) with
\sum_i j_i = k and \sum_i i\,j_i = n. Each such sequence is a
partition of n into exactly k parts; its coefficient
n! / \big(\prod_i (i!)^{j_i}\, j_i!\big) is an integer.
Representation
A Bell polynomial is returned as a dict mapping an *exponent tuple*
e = (e_1, ..., e_n) (the exponent of x_i = u^{(i)}) to its integer
coefficient. Trailing zeros are kept so every key has length n and the
partial polynomials for different k share the same key space, making
bell_complete a straight merge.
The heavy combinatorics are cached as immutable tuples of (exps, coeff)
pairs; the public functions return fresh dict / list copies so callers
may mutate them safely.
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.
bell_complete
omnibias.core.bell_completeSource ↗bell_complete(n: int) -> dict[ExpKey, int]Complete exponential Bell polynomial B_n = \sum_{k} B_{n,k}.
Returns a dict keyed by exponent tuple of length n. Evaluated at
x_i = 1 for all i it equals the Bell number Bell(n)
(see bell_number).
Parameters
| Name | Type & default | Contract |
|---|---|---|
npositional-or-keyword | intRequired | See the operation contract and implementation below. |
dict[ExpKey, int]Executed regression · complete at ones is bell number
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_complete_at_ones_is_bell_number(n: int) -> None:
total = sum(bell_complete(n).values())
assert total == _BELL[n]python -m pytest "packages/omnibias-core/tests/test_bell.py::test_complete_at_ones_is_bell_number[0]" -qRegression example · complete is sum of partials
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_complete_is_sum_of_partials() -> None:
for n in range(7):
merged: dict[tuple[int, ...], int] = {}
for k in range(n + 1):
for key, coeff in bell_partial(n, k).items():
merged[key] = merged.get(key, 0) + coeff
assert merged == bell_complete(n)python -m pytest packages/omnibias-core/tests/test_bell.py -k test_complete_is_sum_of_partials -qRead the implementation
def bell_complete(n: int) -> dict[ExpKey, int]:
"""Complete exponential Bell polynomial :math:`B_n = \\sum_{k} B_{n,k}`.
Returns a ``dict`` keyed by exponent tuple of length ``n``. Evaluated at
``x_i = 1`` for all ``i`` it equals the Bell number ``Bell(n)``
(see :func:`bell_number`).
"""
return dict(_bell_complete_pairs(n))Other public import paths
omnibias.core.bell_completeomnibias.core.bell.bell_complete
bell_number
omnibias.core.bell_numberSource ↗bell_number(n: int) -> intThe n-th Bell number Bell(n) = B_n(1, 1, ..., 1).
Computed by the **Bell triangle** (Aitken's array): O(n^2) exact
big-integer additions. This returns the identical integer as
sum(bell_complete(n).values()) but without enumerating the p(n)
partition terms of the complete Bell polynomial (which is exponential in
n -- p(100) ~ 1.9e8), so it stays fast for large n.
Parameters
| Name | Type & default | Contract |
|---|---|---|
npositional-or-keyword | intRequired | See the operation contract and implementation below. |
intExecuted regression · bell number matches known
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_bell_number_matches_known(n: int) -> None:
assert bell_number(n) == _BELL[n]python -m pytest "packages/omnibias-core/tests/test_bell.py::test_bell_number_matches_known[0]" -qRegression example · bell number negative raises
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_bell_number_negative_raises() -> None:
with pytest.raises(ValueError, match="must be >= 0"):
bell_number(-1)python -m pytest packages/omnibias-core/tests/test_bell.py -k test_bell_number_negative_raises -qRead the implementation
def bell_number(n: int) -> int:
"""The ``n``-th Bell number ``Bell(n) = B_n(1, 1, ..., 1)``.
Computed by the **Bell triangle** (Aitken's array): ``O(n^2)`` exact
big-integer additions. This returns the identical integer as
``sum(bell_complete(n).values())`` but without enumerating the ``p(n)``
partition terms of the complete Bell polynomial (which is exponential in
``n`` -- ``p(100) ~ 1.9e8``), so it stays fast for large ``n``.
"""
_check_bell_order(n, MAX_BELL_NUMBER_ORDER)
row = [1]
for _ in range(n):
nxt = [row[-1]]
for value in row:
nxt.append(nxt[-1] + value)
row = nxt
return row[0]Other public import paths
omnibias.core.bell_numberomnibias.core.bell.bell_number
bell_partial
omnibias.core.bell_partialSource ↗bell_partial(n: int, k: int) -> dict[ExpKey, int]Partial exponential Bell polynomial B_{n,k}.
Returns a dict mapping an exponent tuple (e_1, ..., e_n) (the
exponent of x_i) to its integer coefficient. B_{0,0} = 1 (key
()); B_{n,k} = 0 (empty dict) when k > n or when exactly one of
n/k is zero.
Examples
B_{n,1} is the single monomial x_n with coefficient 1;
B_{n,n} is x_1^n with coefficient 1.
Parameters
| Name | Type & default | Contract |
|---|---|---|
npositional-or-keyword | intRequired | See the operation contract and implementation below. |
kpositional-or-keyword | intRequired | See the operation contract and implementation below. |
dict[ExpKey, int]Executed regression · bell partial 0 0
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_bell_partial_0_0() -> None:
assert bell_partial(0, 0) == {(): 1}python -m pytest "packages/omnibias-core/tests/test_bell.py::test_bell_partial_0_0" -qRegression example · bell partial zero when k gt n
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_bell_partial_zero_when_k_gt_n() -> None:
assert bell_partial(3, 4) == {}python -m pytest packages/omnibias-core/tests/test_bell.py -k test_bell_partial_zero_when_k_gt_n -qRead the implementation
def bell_partial(n: int, k: int) -> dict[ExpKey, int]:
"""Partial exponential Bell polynomial :math:`B_{n,k}`.
Returns a ``dict`` mapping an exponent tuple ``(e_1, ..., e_n)`` (the
exponent of ``x_i``) to its integer coefficient. ``B_{0,0} = 1`` (key
``()``); ``B_{n,k} = 0`` (empty dict) when ``k > n`` or when exactly one of
``n``/``k`` is zero.
Examples
--------
``B_{n,1}`` is the single monomial ``x_n`` with coefficient 1;
``B_{n,n}`` is ``x_1^n`` with coefficient 1.
"""
return dict(_bell_partial_pairs(n, k))Other public import paths
omnibias.core.bell_partialomnibias.core.bell.bell_partial
faa_di_bruno_terms
omnibias.core.bell.faa_di_bruno_termsSource ↗faa_di_bruno_terms(n: int) -> list[tuple[int, ExpKey, int]]Faà di Bruno decomposition of the n-th composition derivative.
Returns a list of (k, exps, coeff) triples such that
(\sigma \circ u)^{(n)} = \sum (\text{coeff})\;\sigma^{(k)}(u^{(0)})\; \prod_{i=1}^{n} \big(u^{(i)}\big)^{e_i},
where exps = (e_1, ..., e_n). For n = 0 the list is empty (the
zeroth "derivative" is the value sigma(u^{(0)}) itself, handled by the
caller).
Parameters
| Name | Type & default | Contract |
|---|---|---|
npositional-or-keyword | intRequired | See the operation contract and implementation below. |
list[tuple[int, ExpKey, int]]Executed regression · faa di bruno textbook n3
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_faa_di_bruno_textbook_n3() -> None:
s = [0.0, 2.0, 3.0, 4.0]
u = [0.0, 5.0, 7.0, 11.0]
# sigma''' u'^3 + 3 sigma'' u' u'' + sigma' u'''.
expected = 4.0 * 5.0**3 + 3.0 * 3.0 * 5.0 * 7.0 + 2.0 * 11.0
assert _faa_eval(s, u, 3) == expectedpython -m pytest "packages/omnibias-core/tests/test_bell.py::test_faa_di_bruno_textbook_n3" -qRegression example · compose jet matches bell oracle
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_compose_jet_matches_bell_oracle() -> None:
rng = np.random.default_rng(11)
order = 6
u_jet = torch.as_tensor(rng.normal(size=(order + 1, 3)))
sigma_tower = torch.as_tensor(rng.normal(size=(order + 1, 3)))
out = jet_to_tower(compose_jet(u_jet, sigma_tower)).numpy()
u_jet_np = u_jet.numpy()
sigma_np = sigma_tower.numpy()
u_deriv = np.array([math.factorial(i) * u_jet_np[i] for i in range(order + 1)])
expected = np.empty_like(sigma_np)
expected[0] = sigma_np[0]
for n in range(1, order + 1):
acc = np.zeros(u_jet_np.shape[1])
for k, exps, coeff in faa_di_bruno_terms(n):
prod = np.ones(u_jet_np.shape[1])
for i, e in enumerate(exps, start=1):
if e:
prod = prod * u_deriv[i] ** e
acc = acc + coeff * sigma_np[k] * prod
expected[n] = acc
assert np.allclose(out, expected, rtol=1e-10, atol=1e-10)python -m pytest packages/omnibias-torch/tests/test_jet.py -k test_compose_jet_matches_bell_oracle -qRead the implementation
def faa_di_bruno_terms(n: int) -> list[tuple[int, ExpKey, int]]:
"""Faà di Bruno decomposition of the ``n``-th composition derivative.
Returns a list of ``(k, exps, coeff)`` triples such that
.. math::
(\\sigma \\circ u)^{(n)}
= \\sum (\\text{coeff})\\;\\sigma^{(k)}(u^{(0)})\\;
\\prod_{i=1}^{n} \\big(u^{(i)}\\big)^{e_i},
where ``exps = (e_1, ..., e_n)``. For ``n = 0`` the list is empty (the
zeroth "derivative" is the value ``sigma(u^{(0)})`` itself, handled by the
caller).
"""
return list(_faa_di_bruno_pairs(n))