omnibias-difference 0.1.0a2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,268 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright (C) 2026 Derivon
3
+ r"""omnibias-difference -- the founding ``delta -> 0`` register for discrete calculus.
4
+
5
+ This package is the **founding bias collapse** the library is named for: ``K``
6
+ biases on a difference stencil (spread ``delta``), with signs
7
+ ``s_k = (-1)^(K-k) C(K-1, k-1) / delta^(K-1)``, so
8
+
9
+ .. math::
10
+
11
+ f_K(z) = \sum_k s_k\,\sigma(z + b_k) \;\longrightarrow\; \sigma^{(K-1)}(z + b_{\text{mean}})
12
+ \qquad \text{as } \delta \to 0.
13
+
14
+ The many biases coalesce and the finite difference *becomes* the derivative
15
+ ``sigma^(K-1)``. The closed-form tower evaluates that limit **exactly**, with no
16
+ ``1/delta^(K-1)`` catastrophic cancellation.
17
+
18
+ This is a ``delta -> 0`` limit yielding a smooth **derivative** -- it is **not**
19
+ **temperature collapse** -- the ``beta -> inf`` *feasibility penalty* of
20
+ ``omnibias-convex`` / ``-control`` / ``-routing`` (a 0/1 step). Same word, opposite limit: **do not
21
+ conflate** the two (see the ``omnibias-core-concepts`` skill and
22
+ ``docs/derivatives.md``).
23
+
24
+ Honesty labels used throughout: **closed-form** (the sigma / sech / tanh towers
25
+ and the exact integer/rational special-number coefficients) and **numerical**
26
+ (the finite-difference estimate and any floating-point asymptotic). There is no
27
+ ``autodiff-exact`` path in this package.
28
+
29
+ The pure-Python core (:mod:`omnibias.difference._core`) imports only
30
+ ``omnibias.core.*``. The optional :mod:`omnibias.difference.torch` /
31
+ :mod:`omnibias.difference.jax` twins add a bit-identical finite-difference
32
+ stencil operator and require the respective backend.
33
+
34
+ .. important::
35
+
36
+ **Bit-parity with the PyTorch twin requires 64-bit JAX** --
37
+ ``jax.config.update("jax_enable_x64", True)`` before the first JAX array is
38
+ created (or ``JAX_ENABLE_X64=1``). JAX otherwise truncates to ``float32``
39
+ while PyTorch uses ``float64``, so the twins stay internally consistent but
40
+ agree only to ``float32`` tolerance. Where a value feeds a threshold, a
41
+ rounding step or an ``argmax``, that is enough to change the decision rather
42
+ than just the last digits. See :mod:`omnibias.jax.precision`.
43
+ """
44
+
45
+ from __future__ import annotations
46
+
47
+ from importlib.metadata import PackageNotFoundError as _PkgNotFound
48
+ from importlib.metadata import version as _pkg_version
49
+
50
+ from omnibias.difference._core import (
51
+ DerivativeEnclosure,
52
+ DerivativeProofVerdict,
53
+ DerivBound,
54
+ DifferenceEstimate,
55
+ FiniteDifferenceCertificate,
56
+ IrregularStencil,
57
+ RationalIdentityVerdict,
58
+ ShefferClass,
59
+ StencilRequest,
60
+ TransferEstimate,
61
+ accuracy_order,
62
+ appell_sequence,
63
+ apply_irregular_stencil,
64
+ associated_sequence,
65
+ bell_asymptotic_relative_error,
66
+ bell_dobinski_enclosure,
67
+ bell_number,
68
+ bell_number_asymptotic,
69
+ bell_number_asymptotic_refined,
70
+ bernoulli_asymptotic,
71
+ bernoulli_enclosure,
72
+ bernoulli_number,
73
+ bernoulli_polynomial,
74
+ bernoulli_recurrence_identity,
75
+ bernoulli_sign_certificate,
76
+ binomial_coefficient,
77
+ binomial_transform,
78
+ catalan_asymptotic,
79
+ cauchy_product,
80
+ certified_derivative_enclosure,
81
+ certified_fd_error,
82
+ certified_fd_error_general,
83
+ certified_irregular_error,
84
+ check_derivative_certificate,
85
+ check_identity_certificate,
86
+ compose_series,
87
+ compositional_inverse,
88
+ connection_constants,
89
+ delta_operator_apply,
90
+ derivative_sign_certificate,
91
+ dirichlet_beta_odd_enclosure,
92
+ dominant_pole_coefficient_asymptotic,
93
+ euler_asymptotic,
94
+ euler_enclosure,
95
+ euler_number,
96
+ euler_polynomial,
97
+ euler_recurrence_identity,
98
+ eulerian_number,
99
+ exponential_generating_coeffs,
100
+ falling_factorial_coeffs,
101
+ falling_to_monomial,
102
+ finite_difference_estimate,
103
+ forward_difference,
104
+ inverse_binomial_transform,
105
+ is_poised_exact,
106
+ log_bell_number_asymptotic,
107
+ log_bell_number_asymptotic_refined,
108
+ monomial_to_falling,
109
+ newton_forward_coeffs,
110
+ newton_forward_value,
111
+ offsets_exact,
112
+ ordinary_from_exponential,
113
+ pade_approximant,
114
+ pade_certified_remainder,
115
+ pade_evaluate,
116
+ pade_evaluate_interval,
117
+ physical_weights,
118
+ pincherle_derivative,
119
+ polya_screen,
120
+ power_sum_coeffs,
121
+ rational_ogf_coefficients,
122
+ rational_ogf_growth_base,
123
+ rational_series,
124
+ rational_value_identity,
125
+ recommended_bell_fallback_n,
126
+ riordan_array,
127
+ riordan_inverse,
128
+ riordan_product,
129
+ rising_factorial_coeffs,
130
+ series_reciprocal,
131
+ sheffer_classify,
132
+ sheffer_sequence,
133
+ shift_polynomial,
134
+ sigma_deriv_bound,
135
+ signs_exact,
136
+ singular_template_coefficient,
137
+ solve_irregular_stencil,
138
+ stencil_offsets,
139
+ stencil_signs,
140
+ stirling_first_signed,
141
+ stirling_first_signed_row,
142
+ stirling_first_unsigned,
143
+ stirling_second,
144
+ stirling_second_asymptotic,
145
+ stirling_second_row,
146
+ thiele_evaluate,
147
+ thiele_interpolation,
148
+ transfer_theorem,
149
+ umbral_composition,
150
+ umbral_functional,
151
+ zeta_int_enclosure,
152
+ zeta_negative_odd_identity,
153
+ )
154
+
155
+ try:
156
+ __version__ = _pkg_version("omnibias-difference")
157
+ except _PkgNotFound: # pragma: no cover - bare source checkout
158
+ __version__ = "0.0.0+unknown"
159
+
160
+ # Limit family exposed as package metadata.
161
+ __lineage__ = "bias collapse"
162
+
163
+ __all__ = [
164
+ "DerivBound",
165
+ "DerivativeEnclosure",
166
+ "DerivativeProofVerdict",
167
+ "DifferenceEstimate",
168
+ "FiniteDifferenceCertificate",
169
+ "IrregularStencil",
170
+ "RationalIdentityVerdict",
171
+ "ShefferClass",
172
+ "StencilRequest",
173
+ "TransferEstimate",
174
+ "__lineage__",
175
+ "__version__",
176
+ "accuracy_order",
177
+ "appell_sequence",
178
+ "apply_irregular_stencil",
179
+ "associated_sequence",
180
+ "bell_asymptotic_relative_error",
181
+ "bell_dobinski_enclosure",
182
+ "bell_number",
183
+ "bell_number_asymptotic",
184
+ "bell_number_asymptotic_refined",
185
+ "bernoulli_asymptotic",
186
+ "bernoulli_enclosure",
187
+ "bernoulli_number",
188
+ "bernoulli_polynomial",
189
+ "bernoulli_recurrence_identity",
190
+ "bernoulli_sign_certificate",
191
+ "binomial_coefficient",
192
+ "binomial_transform",
193
+ "catalan_asymptotic",
194
+ "cauchy_product",
195
+ "certified_derivative_enclosure",
196
+ "certified_fd_error",
197
+ "certified_fd_error_general",
198
+ "certified_irregular_error",
199
+ "check_derivative_certificate",
200
+ "check_identity_certificate",
201
+ "compose_series",
202
+ "compositional_inverse",
203
+ "connection_constants",
204
+ "delta_operator_apply",
205
+ "derivative_sign_certificate",
206
+ "dirichlet_beta_odd_enclosure",
207
+ "dominant_pole_coefficient_asymptotic",
208
+ "euler_asymptotic",
209
+ "euler_enclosure",
210
+ "euler_number",
211
+ "euler_polynomial",
212
+ "euler_recurrence_identity",
213
+ "eulerian_number",
214
+ "exponential_generating_coeffs",
215
+ "falling_factorial_coeffs",
216
+ "falling_to_monomial",
217
+ "finite_difference_estimate",
218
+ "forward_difference",
219
+ "inverse_binomial_transform",
220
+ "is_poised_exact",
221
+ "log_bell_number_asymptotic",
222
+ "log_bell_number_asymptotic_refined",
223
+ "monomial_to_falling",
224
+ "newton_forward_coeffs",
225
+ "newton_forward_value",
226
+ "offsets_exact",
227
+ "ordinary_from_exponential",
228
+ "pade_approximant",
229
+ "pade_certified_remainder",
230
+ "pade_evaluate",
231
+ "pade_evaluate_interval",
232
+ "physical_weights",
233
+ "pincherle_derivative",
234
+ "polya_screen",
235
+ "power_sum_coeffs",
236
+ "rational_ogf_coefficients",
237
+ "rational_ogf_growth_base",
238
+ "rational_series",
239
+ "rational_value_identity",
240
+ "recommended_bell_fallback_n",
241
+ "riordan_array",
242
+ "riordan_inverse",
243
+ "riordan_product",
244
+ "rising_factorial_coeffs",
245
+ "series_reciprocal",
246
+ "sheffer_classify",
247
+ "sheffer_sequence",
248
+ "shift_polynomial",
249
+ "sigma_deriv_bound",
250
+ "signs_exact",
251
+ "singular_template_coefficient",
252
+ "solve_irregular_stencil",
253
+ "stencil_offsets",
254
+ "stencil_signs",
255
+ "stirling_first_signed",
256
+ "stirling_first_signed_row",
257
+ "stirling_first_unsigned",
258
+ "stirling_second",
259
+ "stirling_second_asymptotic",
260
+ "stirling_second_row",
261
+ "thiele_evaluate",
262
+ "thiele_interpolation",
263
+ "transfer_theorem",
264
+ "umbral_composition",
265
+ "umbral_functional",
266
+ "zeta_int_enclosure",
267
+ "zeta_negative_odd_identity",
268
+ ]
@@ -0,0 +1,245 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright (C) 2026 Derivon
3
+ """Pure-Python core of :mod:`omnibias.difference` (imports only ``omnibias.core.*``).
4
+
5
+ The founding ``delta -> 0`` bias-collapse math: backend-neutral finite-difference
6
+ stencils, certified finite-difference -> derivative extraction, the special-number
7
+ readers (Stirling / Bernoulli / Euler off the closed-form towers), umbral / Sheffer
8
+ calculus, and the leading asymptotics.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from omnibias.difference._core.asymptotics import (
14
+ bell_number_asymptotic,
15
+ bernoulli_asymptotic,
16
+ euler_asymptotic,
17
+ log_bell_number_asymptotic,
18
+ stirling_second_asymptotic,
19
+ )
20
+ from omnibias.difference._core.bernoulli import (
21
+ bernoulli_number,
22
+ bernoulli_polynomial,
23
+ power_sum_coeffs,
24
+ )
25
+ from omnibias.difference._core.certify import (
26
+ DerivativeProofVerdict,
27
+ check_derivative_certificate,
28
+ derivative_sign_certificate,
29
+ )
30
+ from omnibias.difference._core.euler import (
31
+ euler_number,
32
+ euler_polynomial,
33
+ eulerian_number,
34
+ )
35
+ from omnibias.difference._core.extraction import (
36
+ DerivativeEnclosure,
37
+ DerivBound,
38
+ DifferenceEstimate,
39
+ FiniteDifferenceCertificate,
40
+ certified_derivative_enclosure,
41
+ certified_fd_error,
42
+ certified_fd_error_general,
43
+ finite_difference_estimate,
44
+ sigma_deriv_bound,
45
+ )
46
+ from omnibias.difference._core.generating import (
47
+ TransferEstimate,
48
+ bell_asymptotic_relative_error,
49
+ bell_dobinski_enclosure,
50
+ bell_number_asymptotic_refined,
51
+ bernoulli_enclosure,
52
+ catalan_asymptotic,
53
+ cauchy_product,
54
+ dirichlet_beta_odd_enclosure,
55
+ dominant_pole_coefficient_asymptotic,
56
+ euler_enclosure,
57
+ exponential_generating_coeffs,
58
+ log_bell_number_asymptotic_refined,
59
+ ordinary_from_exponential,
60
+ rational_ogf_coefficients,
61
+ rational_ogf_growth_base,
62
+ recommended_bell_fallback_n,
63
+ singular_template_coefficient,
64
+ transfer_theorem,
65
+ zeta_int_enclosure,
66
+ )
67
+ from omnibias.difference._core.identities import (
68
+ RationalIdentityVerdict,
69
+ bernoulli_recurrence_identity,
70
+ bernoulli_sign_certificate,
71
+ check_identity_certificate,
72
+ euler_recurrence_identity,
73
+ rational_value_identity,
74
+ zeta_negative_odd_identity,
75
+ )
76
+ from omnibias.difference._core.irregular import (
77
+ IrregularStencil,
78
+ StencilRequest,
79
+ apply_irregular_stencil,
80
+ certified_irregular_error,
81
+ is_poised_exact,
82
+ physical_weights,
83
+ polya_screen,
84
+ solve_irregular_stencil,
85
+ )
86
+ from omnibias.difference._core.pade import (
87
+ pade_approximant,
88
+ pade_certified_remainder,
89
+ pade_evaluate,
90
+ pade_evaluate_interval,
91
+ rational_series,
92
+ thiele_evaluate,
93
+ thiele_interpolation,
94
+ )
95
+ from omnibias.difference._core.sheffer import (
96
+ associated_sequence,
97
+ delta_operator_apply,
98
+ pincherle_derivative,
99
+ sheffer_sequence,
100
+ shift_polynomial,
101
+ umbral_composition,
102
+ umbral_functional,
103
+ )
104
+ from omnibias.difference._core.stencil import (
105
+ accuracy_order,
106
+ offsets_exact,
107
+ signs_exact,
108
+ stencil_offsets,
109
+ stencil_signs,
110
+ )
111
+ from omnibias.difference._core.stirling import (
112
+ bell_number,
113
+ falling_factorial_coeffs,
114
+ rising_factorial_coeffs,
115
+ stirling_first_signed,
116
+ stirling_first_signed_row,
117
+ stirling_first_unsigned,
118
+ stirling_second,
119
+ stirling_second_row,
120
+ )
121
+ from omnibias.difference._core.umbral import (
122
+ ShefferClass,
123
+ appell_sequence,
124
+ binomial_coefficient,
125
+ binomial_transform,
126
+ compose_series,
127
+ compositional_inverse,
128
+ connection_constants,
129
+ falling_to_monomial,
130
+ forward_difference,
131
+ inverse_binomial_transform,
132
+ monomial_to_falling,
133
+ newton_forward_coeffs,
134
+ newton_forward_value,
135
+ riordan_array,
136
+ riordan_inverse,
137
+ riordan_product,
138
+ series_reciprocal,
139
+ sheffer_classify,
140
+ )
141
+
142
+ __all__ = [
143
+ "DerivBound",
144
+ "DerivativeEnclosure",
145
+ "DerivativeProofVerdict",
146
+ "DifferenceEstimate",
147
+ "FiniteDifferenceCertificate",
148
+ "IrregularStencil",
149
+ "RationalIdentityVerdict",
150
+ "ShefferClass",
151
+ "StencilRequest",
152
+ "TransferEstimate",
153
+ "accuracy_order",
154
+ "appell_sequence",
155
+ "apply_irregular_stencil",
156
+ "associated_sequence",
157
+ "bell_asymptotic_relative_error",
158
+ "bell_dobinski_enclosure",
159
+ "bell_number",
160
+ "bell_number_asymptotic",
161
+ "bell_number_asymptotic_refined",
162
+ "bernoulli_asymptotic",
163
+ "bernoulli_enclosure",
164
+ "bernoulli_number",
165
+ "bernoulli_polynomial",
166
+ "bernoulli_recurrence_identity",
167
+ "bernoulli_sign_certificate",
168
+ "binomial_coefficient",
169
+ "binomial_transform",
170
+ "catalan_asymptotic",
171
+ "cauchy_product",
172
+ "certified_derivative_enclosure",
173
+ "certified_fd_error",
174
+ "certified_fd_error_general",
175
+ "certified_irregular_error",
176
+ "check_derivative_certificate",
177
+ "check_identity_certificate",
178
+ "compose_series",
179
+ "compositional_inverse",
180
+ "connection_constants",
181
+ "delta_operator_apply",
182
+ "derivative_sign_certificate",
183
+ "dirichlet_beta_odd_enclosure",
184
+ "dominant_pole_coefficient_asymptotic",
185
+ "euler_asymptotic",
186
+ "euler_enclosure",
187
+ "euler_number",
188
+ "euler_polynomial",
189
+ "euler_recurrence_identity",
190
+ "eulerian_number",
191
+ "exponential_generating_coeffs",
192
+ "falling_factorial_coeffs",
193
+ "falling_to_monomial",
194
+ "finite_difference_estimate",
195
+ "forward_difference",
196
+ "inverse_binomial_transform",
197
+ "is_poised_exact",
198
+ "log_bell_number_asymptotic",
199
+ "log_bell_number_asymptotic_refined",
200
+ "monomial_to_falling",
201
+ "newton_forward_coeffs",
202
+ "newton_forward_value",
203
+ "offsets_exact",
204
+ "ordinary_from_exponential",
205
+ "pade_approximant",
206
+ "pade_certified_remainder",
207
+ "pade_evaluate",
208
+ "pade_evaluate_interval",
209
+ "physical_weights",
210
+ "pincherle_derivative",
211
+ "polya_screen",
212
+ "power_sum_coeffs",
213
+ "rational_ogf_coefficients",
214
+ "rational_ogf_growth_base",
215
+ "rational_series",
216
+ "rational_value_identity",
217
+ "recommended_bell_fallback_n",
218
+ "riordan_array",
219
+ "riordan_inverse",
220
+ "riordan_product",
221
+ "rising_factorial_coeffs",
222
+ "series_reciprocal",
223
+ "sheffer_classify",
224
+ "sheffer_sequence",
225
+ "shift_polynomial",
226
+ "sigma_deriv_bound",
227
+ "signs_exact",
228
+ "singular_template_coefficient",
229
+ "solve_irregular_stencil",
230
+ "stencil_offsets",
231
+ "stencil_signs",
232
+ "stirling_first_signed",
233
+ "stirling_first_signed_row",
234
+ "stirling_first_unsigned",
235
+ "stirling_second",
236
+ "stirling_second_asymptotic",
237
+ "stirling_second_row",
238
+ "thiele_evaluate",
239
+ "thiele_interpolation",
240
+ "transfer_theorem",
241
+ "umbral_composition",
242
+ "umbral_functional",
243
+ "zeta_int_enclosure",
244
+ "zeta_negative_odd_identity",
245
+ ]
@@ -0,0 +1,101 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright (C) 2026 Derivon
3
+ r"""Leading asymptotics of the analytic-combinatorics coefficients (pure ``math``).
4
+
5
+ Closed-form leading asymptotics for the numbers extracted off the towers. Each is
6
+ the genuine leading term (relative error ``-> 0`` as the index grows); the exact
7
+ values and a high-precision ``mpmath`` cross-check live in the tests.
8
+
9
+ * **Bernoulli** ``B_{2m} ~ (-1)^{m+1} 2 (2m)! / (2 pi)^{2m}`` (fast: relative
10
+ error ``O(2^{-2m})``).
11
+ * **Euler (secant)** ``E_{2m} ~ (-1)^m 2^{2m+2} (2m)! / pi^{2m+1}`` (fast).
12
+ * **Stirling second kind, fixed ``k``** ``S(n, k) ~ k^n / k!`` as ``n -> inf``.
13
+ * **Bell numbers** -- the Dobinski saddle-point form
14
+ ``B_n ~ e^{n/r - 1} n! / (r^n sqrt(2 pi n (r+1)))`` with ``r = W(n)`` (Lambert
15
+ W); relative error ``~1%`` by ``n = 30`` and shrinking.
16
+
17
+ Values are returned as ``float`` and are computed in log space where possible, so
18
+ they stay finite far past the point where ``(2m)!`` would overflow a double; the
19
+ Bell helper also exposes its logarithm for very large ``n``.
20
+ """
21
+
22
+ from __future__ import annotations
23
+
24
+ from math import exp, lgamma, log, pi
25
+
26
+
27
+ def bernoulli_asymptotic(n: int) -> float:
28
+ r"""Signed leading asymptotic of ``B_n`` (even ``n = 2m >= 2`` only).
29
+
30
+ ``B_{2m} ~ (-1)^{m+1} 2 (2m)! / (2 pi)^{2m}``.
31
+ """
32
+ if n < 2 or n % 2 == 1:
33
+ raise ValueError(f"Bernoulli asymptotic is defined for even n >= 2, got {n}")
34
+ m = n // 2
35
+ log_mag = log(2.0) + lgamma(n + 1) - n * log(2.0 * pi)
36
+ return (-1.0) ** (m + 1) * exp(log_mag)
37
+
38
+
39
+ def euler_asymptotic(n: int) -> float:
40
+ r"""Signed leading asymptotic of the Euler (secant) number ``E_n`` (even ``n = 2m >= 2``).
41
+
42
+ ``E_{2m} ~ (-1)^m 2^{2m+2} (2m)! / pi^{2m+1}``.
43
+ """
44
+ if n < 2 or n % 2 == 1:
45
+ raise ValueError(f"Euler asymptotic is defined for even n >= 2, got {n}")
46
+ m = n // 2
47
+ log_mag = (2 * m + 2) * log(2.0) + lgamma(n + 1) - (2 * m + 1) * log(pi)
48
+ return (-1.0) ** m * exp(log_mag)
49
+
50
+
51
+ def stirling_second_asymptotic(n: int, k: int) -> float:
52
+ r"""Fixed-``k`` leading asymptotic ``S(n, k) ~ k^n / k!`` as ``n -> inf``."""
53
+ if k < 1:
54
+ raise ValueError(f"k must be >= 1, got {k}")
55
+ if n < 0:
56
+ raise ValueError(f"n must be >= 0, got {n}")
57
+ return exp(n * log(k) - lgamma(k + 1))
58
+
59
+
60
+ def _lambert_w(x: float) -> float:
61
+ """Principal real branch ``W(x)`` for ``x >= 0`` (Halley iteration)."""
62
+ if x < 0.0:
63
+ raise ValueError(f"_lambert_w supports x >= 0 only, got {x}")
64
+ if x == 0.0:
65
+ return 0.0
66
+ w = log(1.0 + x) # globally safe start for x > 0
67
+ for _ in range(100):
68
+ ew = exp(w)
69
+ f = w * ew - x
70
+ denom = ew * (w + 1.0) - (w + 2.0) * f / (2.0 * w + 2.0)
71
+ w_next = w - f / denom
72
+ if abs(w_next - w) <= 1e-16 * (1.0 + abs(w_next)):
73
+ return w_next
74
+ w = w_next
75
+ return w
76
+
77
+
78
+ def log_bell_number_asymptotic(n: int) -> float:
79
+ r"""Natural log of the Bell-number saddle-point asymptotic (safe for large ``n``)."""
80
+ if n < 1:
81
+ raise ValueError(f"n must be >= 1, got {n}")
82
+ r = _lambert_w(float(n))
83
+ return (n / r - 1.0) + lgamma(n + 1) - n * log(r) - 0.5 * log(2.0 * pi * n * (r + 1.0))
84
+
85
+
86
+ def bell_number_asymptotic(n: int) -> float:
87
+ r"""Dobinski saddle-point asymptotic of the Bell number ``Bell(n)``.
88
+
89
+ ``Bell(n) ~ e^{n/r - 1} n! / (r^n sqrt(2 pi n (r+1)))`` with ``r = W(n)``. Use
90
+ :func:`log_bell_number_asymptotic` when ``n`` is large enough to overflow.
91
+ """
92
+ return exp(log_bell_number_asymptotic(n))
93
+
94
+
95
+ __all__ = [
96
+ "bell_number_asymptotic",
97
+ "bernoulli_asymptotic",
98
+ "euler_asymptotic",
99
+ "log_bell_number_asymptotic",
100
+ "stirling_second_asymptotic",
101
+ ]
@@ -0,0 +1,69 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright (C) 2026 Derivon
3
+ r"""Bernoulli numbers read off the closed-form ``tanh`` tower (exact rationals).
4
+
5
+ The odd derivatives of ``tanh`` at the origin are the (signed) **tangent
6
+ numbers** ``tanh^(2m-1)(0)``, read straight off the constant term of the exact
7
+ ``tanh`` derivative-tower polynomial
8
+ (:func:`omnibias.core.verified.coeffs.tanh_poly_coeffs_exact`). The Taylor series
9
+ ``tanh(x) = sum_{m>=1} 2^{2m}(2^{2m}-1) B_{2m}/(2m)! x^{2m-1}`` then gives the
10
+ even Bernoulli numbers exactly:
11
+
12
+ .. math::
13
+
14
+ B_{2m} = \tanh^{(2m-1)}(0)\;\frac{2m}{2^{2m}\,(2^{2m}-1)}.
15
+
16
+ Convention: ``B_0 = 1``, ``B_1 = -1/2`` (the "first Bernoulli number"; matches
17
+ ``mpmath.bernoulli``), and ``B_{2m+1} = 0`` for ``m >= 1``.
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ from fractions import Fraction
23
+ from math import comb
24
+
25
+ from omnibias.core.verified.coeffs import bernoulli_number_exact
26
+
27
+
28
+ def bernoulli_number(n: int) -> Fraction:
29
+ """The ``n``-th Bernoulli number ``B_n`` (exact ``Fraction``; ``B_1 = -1/2``).
30
+
31
+ A thin re-export of :func:`omnibias.core.verified.coeffs.bernoulli_number_exact`
32
+ -- the shared source of truth also consumed by the certified Euler-Maclaurin
33
+ engine -- so the Bernoulli numbers are defined once (off the ``tanh`` tower) and
34
+ never forked per package.
35
+ """
36
+ return bernoulli_number_exact(n)
37
+
38
+
39
+ def bernoulli_polynomial(n: int) -> tuple[Fraction, ...]:
40
+ r"""Coefficients of the Bernoulli polynomial ``B_n(x) = sum_k C(n,k) B_{n-k} x^k``.
41
+
42
+ Returns ``(c_0, ..., c_n)`` with ``B_n(x) = sum_k c_k x^k``. This is an Appell
43
+ sequence: ``B_n'(x) = n B_{n-1}(x)`` and ``B_n(0) = B_n``.
44
+ """
45
+ if n < 0:
46
+ raise ValueError(f"n must be >= 0, got {n}")
47
+ return tuple(Fraction(comb(n, k)) * bernoulli_number(n - k) for k in range(n + 1))
48
+
49
+
50
+ def power_sum_coeffs(p: int) -> tuple[Fraction, ...]:
51
+ r"""Faulhaber coefficients of ``S_p(N) = sum_{i=0}^{N-1} i^p`` as a polynomial in ``N``.
52
+
53
+ Returns ``(c_0, ..., c_{p+1})`` with ``S_p(N) = sum_j c_j N^j``, via
54
+ ``S_p(N) = (B_{p+1}(N) - B_{p+1}) / (p + 1)``. (Sum runs to ``N - 1``, the
55
+ convention matched to ``B_1 = -1/2``.)
56
+ """
57
+ if p < 0:
58
+ raise ValueError(f"p must be >= 0, got {p}")
59
+ out = [Fraction(0)] * (p + 2)
60
+ for k in range(1, p + 2):
61
+ out[k] = Fraction(comb(p + 1, k)) * bernoulli_number(p + 1 - k) / Fraction(p + 1)
62
+ return tuple(out)
63
+
64
+
65
+ __all__ = [
66
+ "bernoulli_number",
67
+ "bernoulli_polynomial",
68
+ "power_sum_coeffs",
69
+ ]