Skip to content

Commit 56375ba

Browse files
thisiscamclaude
andcommitted
Promote Python-scalar primals to jnp arrays at jet() entry
Several primitive Taylor rules (notably _log1p_taylor) accessed .ndim on the user-supplied primal, which fails when the caller passes a Python float. Convert primals (and series) to jnp arrays once in jet() so every rule can rely on array attributes. Adds parametrized regression test test_python_float_primal across all supported test functions. Also: update author to Cambridge Yang only. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 055b8bc commit 56375ba

4 files changed

Lines changed: 29 additions & 2 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ If you use `jet-array` in academic work, please cite the repository:
280280
```bibtex
281281
@software{jet_array,
282282
title = {jet-array: array-form Taylor-mode automatic differentiation in JAX},
283-
author = {Yang, Cambridge and Li, Dongdong},
283+
author = {Yang, Cambridge},
284284
year = {2026},
285285
url = {https://github.com/thisiscam/jet-array},
286286
}

‎jet_array/__init__.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,11 @@ def jet(fun, primals, series, effective_order=None, **_):
206206
if not treedef_is_leaf(treedef):
207207
raise ValueError(f"term {j} for argument {i} is not an array")
208208

209+
# Promote Python scalars to jnp arrays so that primitive rules can rely
210+
# on .ndim/.shape/.dtype.
211+
primals = tuple(jnp.asarray(p) for p in primals)
212+
series = tuple(jnp.asarray(s) for s in series)
213+
209214
@lu.transformation_with_aux2
210215
def flatten_fun_output(f, store, *args):
211216
ans = f(*args)

‎pyproject.toml‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ license = "Apache-2.0"
88
license-files = ["LICENSE"]
99
authors = [
1010
{ name = "Cambridge Yang", email = "camyang@csail.mit.edu" },
11-
{ name = "Dongdong Li", email = "dli.stats@gmail.com" },
1211
]
1312
keywords = ["jax", "automatic-differentiation", "taylor-mode", "jet", "higher-order-derivatives"]
1413
classifiers = [

‎tests/test_against_jax_jet.py‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,26 @@ def test_identity():
151151
np.testing.assert_allclose(p, 0.7)
152152
np.testing.assert_allclose(s[0], 1.0)
153153
np.testing.assert_allclose(s[1:], jnp.zeros(4), atol=1e-7)
154+
155+
156+
@pytest.mark.parametrize("name,fn", TEST_FUNCTION_PARAMS)
157+
def test_python_float_primal(name, fn):
158+
"""Python float primals are promoted to jnp arrays automatically.
159+
160+
Regression test: rules like _log1p_taylor previously called .ndim on the
161+
primal, which failed for Python floats.
162+
"""
163+
if name == "log1p":
164+
x0 = 0.3
165+
else:
166+
x0 = 0.5
167+
order = 5
168+
series_in = [1.0] + [0.0] * (order - 1)
169+
primal, series = jet(fn, (x0,), (series_in,))
170+
# Compare against the jnp-array path.
171+
series_in_arr = jnp.zeros(order, dtype=jnp.float64).at[0].set(1.0)
172+
primal_ref, series_ref = jet(
173+
fn, (jnp.asarray(x0, dtype=jnp.float64),), (series_in_arr,)
174+
)
175+
np.testing.assert_allclose(primal, primal_ref, rtol=RTOL, atol=ATOL)
176+
np.testing.assert_allclose(series, series_ref, rtol=RTOL, atol=ATOL)

0 commit comments

Comments
 (0)