Skip to content

Commit e5b69da

Browse files
queeliusclaude
andcommitted
Release 0.7.0: composable D operator, rename to nabla, MLE skewness vignette
Rename package from dualr to nabla and GitHub repo to queelius/nabla. Add composable total derivative operator D(f, x, order=k) with gradient(), hessian(), jacobian() as thin wrappers. Replace MLE-specific API with general-purpose derivative functions. Add vignette demonstrating third-order derivative tensors for asymptotic MLE skewness analysis on Gamma model with Monte Carlo validation. Add Zenodo and CITATION.cff metadata. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 415e3ec commit e5b69da

41 files changed

Lines changed: 1967 additions & 1466 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.Rbuildignore‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@
1010
^cran-comments\.md$
1111
^CLAUDE\.md$
1212
^tests/bench
13+
^CITATION\.cff$
14+
^\.zenodo\.json$

‎.zenodo.json‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"title": "nabla: Exact Derivatives via Automatic Differentiation",
3+
"description": "Exact automatic differentiation for R functions. Provides a composable derivative operator D that computes gradients, Hessians, Jacobians, and arbitrary-order derivative tensors at machine precision. D(D(f)) gives Hessians, D(D(D(f))) gives third-order tensors for skewness of MLEs, and so on to any order. Works through any R code including loops, branches, and control flow.",
4+
"creators": [
5+
{
6+
"name": "Towell, Alexander",
7+
"affiliation": "Southern Illinois University Edwardsville",
8+
"orcid": "0000-0001-6443-9897"
9+
}
10+
],
11+
"upload_type": "software",
12+
"license": "MIT",
13+
"access_right": "open",
14+
"keywords": [
15+
"automatic differentiation",
16+
"dual numbers",
17+
"forward-mode AD",
18+
"gradient",
19+
"Hessian",
20+
"Jacobian",
21+
"higher-order derivatives",
22+
"R",
23+
"statistics"
24+
],
25+
"related_identifiers": [
26+
{
27+
"identifier": "https://github.com/queelius/nabla",
28+
"relation": "isSupplementTo",
29+
"scheme": "url"
30+
},
31+
{
32+
"identifier": "https://cran.r-project.org/package=nabla",
33+
"relation": "isIdenticalTo",
34+
"scheme": "url"
35+
},
36+
{
37+
"identifier": "https://metafunctor.com",
38+
"relation": "isDocumentedBy",
39+
"scheme": "url"
40+
}
41+
],
42+
"version": "0.7.0"
43+
}

‎CITATION.cff‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
cff-version: 1.2.0
2+
title: "nabla: Exact Derivatives via Automatic Differentiation"
3+
message: "If you use this software, please cite it using these metadata."
4+
type: software
5+
authors:
6+
- family-names: Towell
7+
given-names: Alexander
8+
alias: Alex Towell
9+
email: queelius@gmail.com
10+
orcid: "https://orcid.org/0000-0001-6443-9897"
11+
affiliation: Southern Illinois University Edwardsville
12+
repository-code: "https://github.com/queelius/nabla"
13+
url: "https://metafunctor.com"
14+
abstract: >-
15+
Exact automatic differentiation for R functions. Provides a composable
16+
derivative operator D that computes gradients, Hessians, Jacobians, and
17+
arbitrary-order derivative tensors at machine precision. Works through
18+
any R code including loops, branches, and control flow.
19+
keywords:
20+
- automatic-differentiation
21+
- dual-numbers
22+
- forward-mode
23+
- gradient
24+
- hessian
25+
- jacobian
26+
- higher-order-derivatives
27+
- R
28+
license: MIT
29+
version: 0.7.0
30+
date-released: "2026-02-02"

‎CLAUDE.md‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
44

55
## What This Is
66

7-
`dualr` is an R package for forward-mode automatic differentiation using dual numbers. It provides exact derivatives at machine precision through any R code (loops, branches, control flow) via operator overloading on S4 classes.
7+
`nabla` is an R package for exact automatic differentiation. It provides exact derivatives at machine precision through any R code (loops, branches, control flow) via operator overloading on S4 dual number classes.
88

99
## Build & Test Commands
1010

@@ -46,9 +46,9 @@ The `Collate:` field in DESCRIPTION defines load order — dependencies flow top
4646
2. `dual-arithmetic.R` — Arithmetic operators (+, -, *, /, ^) with derivative rules; Ops/Summary group generics
4747
3. `dual-math.R` — Math/Math2 group generics (trig, exp, log, gamma, etc.); standalone `atan2()`, `log(x, base)`
4848
4. `dual-special.R` — Non-base-generic functions: `erf()`, `erfc()`, `beta()`, `lbeta()`, `psigamma()`
49-
5. `dual-higher.R` — Second-order via nested duals: `dual2_variable()`, `differentiate2()`
50-
6. `mle-helpers.R` — High-level API: `score()`, `hessian()`, `observed_information()`
51-
7. `dualr-package.R` — Package-level roxygen docs
49+
5. `dual-higher.R` — Arbitrary-order via nested duals: `dual_variable_n()`, `deriv_n()`, `differentiate_n()`
50+
6. `derivatives.R` — High-level API: `D()`, `gradient()`, `hessian()`, `jacobian()`
51+
7. `nabla-package.R` — Package-level roxygen docs
5252

5353
### Method Dispatch Pattern
5454

@@ -65,14 +65,14 @@ The fundamental identity: `f(a + b*ε) = f(a) + f'(a)*b*ε` where `ε² = 0`.
6565
- Math functions apply chain rule: `deriv(f(x)) = f'(value(x)) * deriv(x)`
6666
- Second-order derivatives nest duals: `dual(dual(x, 1), dual(1, 0))` — after evaluation, `deriv(deriv(result))` gives f''(x)
6767

68-
### MLE Workflow
68+
### Multi-Parameter Derivatives
6969

70-
`score()` runs p forward passes (one per parameter, seeding deriv=1 on each in turn). `hessian()` uses nested duals with p*(p+1)/2 passes exploiting symmetry. Both use internal `.make_dual_vector()` / `.make_dual2_vector()` for seeding.
70+
`D(f)` is the composable total derivative operator. It returns the derivative of `f` as a new function; `D(D(f))` composes for higher-order derivative tensors. Each application of `D` runs `p` forward passes (one per input dimension) using `.make_dual_vector()` for seeding. `gradient()`, `hessian()`, and `jacobian()` are thin wrappers: `gradient(f, x)` = `D(f, x)`, `hessian(f, x)` = `D(f, x, order=2)`, `jacobian(f, x)` = `D(f, x)`.
7171

7272
## Testing Conventions
7373

7474
- Framework: testthat 3rd edition
75-
- Test files mirror source structure: `test-arithmetic.R`, `test-math.R`, `test-special.R`, `test-higher-order.R`, `test-mle-helpers.R`
75+
- Test files mirror source structure: `test-arithmetic.R`, `test-math.R`, `test-special.R`, `test-higher-order.R`, `test-derivatives.R`
7676
- `test-coverage.R` targets uncovered edge cases specifically
7777
- `test-optimizer-integration.R` tests AD gradients with `optim()` and `nlminb()`
7878
- `tests/testthat/helper-numerical.R` provides `central_difference()`, `numerical_gradient()`, `numerical_hessian()` for verification

‎DESCRIPTION‎

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1-
Package: dualr
2-
Title: Forward-Mode Automatic Differentiation via Dual Numbers
3-
Version: 0.5.0
1+
Package: nabla
2+
Title: Exact Derivatives via Automatic Differentiation
3+
Version: 0.7.0
44
Authors@R: person("Alexander", "Towell",
55
role = c("aut", "cre"),
66
email = "queelius@gmail.com",
77
comment = c(ORCID = "0000-0001-6443-9897"))
8-
URL: https://github.com/queelius/dualr, https://metafunctor.com
9-
BugReports: https://github.com/queelius/dualr/issues
10-
Description: Implements forward-mode automatic differentiation using dual
11-
numbers with S4 classes. Supports exact arbitrary-order derivatives
12-
through recursive nesting of duals, with convenience functions for
13-
maximum likelihood estimation workflows including score vectors,
14-
Hessian matrices, and observed information.
8+
URL: https://github.com/queelius/nabla, https://metafunctor.com
9+
BugReports: https://github.com/queelius/nabla/issues
10+
Description: Exact automatic differentiation for R functions. Provides a
11+
composable derivative operator D that computes gradients, Hessians,
12+
Jacobians, and arbitrary-order derivative tensors at machine precision.
13+
D(D(f)) gives Hessians, D(D(D(f))) gives third-order tensors for
14+
skewness of MLEs, and so on to any order. Works through any R code
15+
including loops, branches, and control flow.
1516
License: MIT + file LICENSE
1617
Encoding: UTF-8
1718
Roxygen: list(markdown = TRUE)
@@ -33,5 +34,5 @@ Collate:
3334
'dual-math.R'
3435
'dual-special.R'
3536
'dual-higher.R'
36-
'mle-helpers.R'
37-
'dualr-package.R'
37+
'derivatives.R'
38+
'nabla-package.R'

‎NAMESPACE‎

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,25 @@
11
# Generated by roxygen2: do not edit by hand
22

3+
export(D)
34
export(beta)
45
export(deriv)
56
export(deriv_n)
6-
export(differentiate2)
77
export(differentiate_n)
88
export(dual)
9-
export(dual2_constant)
10-
export(dual2_variable)
119
export(dual_constant)
1210
export(dual_constant_n)
1311
export(dual_variable)
1412
export(dual_variable_n)
1513
export(dual_vector)
1614
export(erf)
1715
export(erfc)
18-
export(first_deriv)
16+
export(gradient)
1917
export(hessian)
2018
export(is_dual)
19+
export(jacobian)
2120
export(lbeta)
22-
export(observed_information)
2321
export(psigamma)
24-
export(score)
25-
export(score_and_hessian)
26-
export(second_deriv)
2722
export(value)
28-
export(value2)
2923
exportClasses(dual_vector)
3024
exportClasses(dualr)
3125
exportMethods("!")

‎NEWS.md‎

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,43 @@
1-
# dualr 0.5.0
1+
# nabla 0.7.0
2+
3+
* Added vignette "Higher-Order MLE Analysis" demonstrating third-order
4+
derivative tensors (`D(f, x, order = 3)`) for computing asymptotic
5+
skewness of Gamma MLEs, with Monte Carlo validation.
6+
* Renamed package from `dualr` to `nabla`. The S4 class `dualr` retains its
7+
name (it describes the object type — a dual number in R).
8+
* Added composable total derivative operator `D(f)`:
9+
- `D(f)` returns the derivative of `f` as a new function.
10+
- `D(f, x)` evaluates the derivative at `x`.
11+
- `D(f, x, order = k)` applies `D` k times for k-th order derivative tensors.
12+
- `D(D(f))` composes naturally for higher-order derivatives.
13+
- Output tensor shape: each application of `D` appends one n-dimension.
14+
For `f: R^n -> R`: gradient `(n)`, Hessian `(n,n)`, etc.
15+
For `f: R^n -> R^m`: Jacobian `(m,n)`, `(m,n,n)`, etc.
16+
* Unified `gradient()`, `hessian()`, and `jacobian()` as thin wrappers
17+
around `D`, replacing separate seeding strategies with a single composable
18+
mechanism. This simplifies the codebase at the cost of `O(p)` gradient
19+
(was `O(1)` passes) and `O(p^2)` Hessian (was `O(p)` passes).
20+
* Removed deprecated second-order functions: `dual2_variable()`,
21+
`dual2_constant()`, `value2()`, `first_deriv()`, `second_deriv()`,
22+
`differentiate2()`. Use `dual_variable_n()`, `dual_constant_n()`,
23+
`deriv_n()`, and `differentiate_n()` instead.
24+
* Removed internal helpers `.make_grad_vector()` and `.make_grad2_vector()`.
25+
* Updated higher-order vignette to use current API and demonstrate `D` operator.
26+
27+
# nabla 0.6.0
28+
29+
* Replaced MLE-specific API with general-purpose derivative functions:
30+
- `score()` -> `gradient()` — computes the gradient of any scalar-valued
31+
function (still single-pass via vector-valued derivatives).
32+
- `hessian()` — unchanged (already mathematically general).
33+
- `observed_information()` — removed (trivial: just `-hessian()`).
34+
- `score_and_hessian()` -> `jacobian()` — generalized to compute the
35+
full m x p Jacobian matrix of any `f: R^p -> R^m`. Accepts functions
36+
returning lists, numeric vectors, or scalar dualr objects.
37+
* Renamed `R/mle-helpers.R` to `R/derivatives.R`.
38+
* Updated vignettes to use general terminology (gradient/Hessian/Jacobian).
39+
40+
# nabla 0.5.0
241

342
* Generalized to arbitrary-order exact derivatives via recursive nesting.
443
New API: `dual_variable_n()`, `dual_constant_n()`, `deriv_n()`,
@@ -11,7 +50,7 @@
1150
wrappers around the new generalized API.
1251
* Removed benchmarks (speed is not this package's value proposition).
1352

14-
# dualr 0.4.0
53+
# nabla 0.4.0
1554

1655
* `score()` now computes the full gradient in 1 forward pass (was p passes)
1756
using vector-valued derivatives, exploiting the `ANY` slots of the `dualr` class.
@@ -20,13 +59,13 @@
2059
* Internal `.is_scalar_dual()` now also checks `length() == 1L` to correctly
2160
distinguish scalar duals (C++ fast path) from vector-gradient duals (R path).
2261

23-
# dualr 0.3.0
62+
# nabla 0.3.0
2463

2564
* Added Rcpp-based C++ fast paths for first-order dual arithmetic (`+`, `-`, `*`, `/`, `^`), math (`exp`, `sqrt`, `log`), and `sum`. Provides 3-10x speedup on scalar dual operations while preserving full R fallback for nested (second-order) duals.
2665
* New internal `.is_scalar_dual()` predicate gates C++ vs R paths using `is.double()` on slot contents.
2766
* Added `Rcpp` to `Imports` and `LinkingTo`; package now requires C++ compilation.
2867

29-
# dualr 0.2.0
68+
# nabla 0.2.0
3069

3170
* Renamed S4 class from `dual` to `dualr` to avoid conflict with base R's `dual` usage.
3271
* Added dedicated `setMethod` dispatches for hot-path arithmetic (`+`, `-`, `*`, `/`, `^`) and math (`exp`, `sqrt`) operations, bypassing group generic overhead.
@@ -35,7 +74,7 @@
3574
* Standardized `sum()` in `Summary` group generic to use `.as_dual()` promotion, consistent with `prod`, `min`, `max`, and `range`.
3675
* Fixed stale `\code{compositional.mle}` reference in `score()` documentation.
3776

38-
# dualr 0.1.0
77+
# nabla 0.1.0
3978

4079
* Initial CRAN release.
4180
* S4 dual number class with full arithmetic and math function support.

0 commit comments

Comments
 (0)