Skip to content

Commit bb1d636

Browse files
committed
PAPER: Add citations and trade-off discussion (JOSS jonaspleyer #100)
Address all four checkboxes in jonaspleyer's paper review: * Cite LAPACK [@lapack] (Anderson et al., LAPACK Users' Guide, 3rd ed., SIAM 1999) at the single body mention of LAPACK on line 61. * Cite ndarray [@ndarray] (rust-ndarray developers, v0.17.2) in the Table 1 caption and in the new architecture trade-off sentence. * Add a one-sentence trade-off note to the Architecture paragraph spelling out the two known downsides of the flat Vec<f64> layout (compile-time dimension checking versus nalgebra; N-dimensional generalization versus ndarray), per the reviewer request to discuss "possible known downsides of the matrix memory layout". * Add an Enzyme [@enzyme] paragraph to the State of the field (Moses & Churavy, NeurIPS 2020) framed as complementary: Peroxide provides high-order forward derivatives while Enzyme adds the reverse-mode AD that Peroxide currently does not. Also cite OpenBLAS [@openblas] (OpenBLAS developers, v0.3.33) at the existing OpenBLAS mention; the previous draft attached BLAS / LAPACK citations to that mention, which read as a citation of OpenBLAS even though it referred to the underlying standards. The dedicated @openblas software entry resolves the ambiguity. The stand-alone @blas entry is dropped because the word "BLAS" does not appear in body text on its own. Word count is kept under the prior baseline (1573 words, down from 1594) by compressing the Research Impact Statement and the Validation section. The most visible compressions: * The author's own work paragraph in Research Impact is rewritten as a single sentence with each citation attached to its purpose. * Download / star counts are refreshed to today's crates.io / GitHub values rounded conservatively (over 1,100,000 downloads, 700 stars). * The truncation/cancellation argument in Validation now states the trade-off without spelling out the O(h^p) and O(eps/h^k) expressions, which can be looked up via [@press2007]. Verified with the openjournals/inara docker image: 6-page PDF builds, all four new bib entries appear correctly both inline and in the reference list.
1 parent 0976ee4 commit bb1d636

2 files changed

Lines changed: 54 additions & 16 deletions

File tree

‎paper/paper.bib‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,3 +303,40 @@ @software{parquet
303303
url = {https://parquet.apache.org/},
304304
year = {2026}
305305
}
306+
307+
@book{lapack,
308+
author = {Anderson, E. and Bai, Z. and Bischof, C. and Blackford, S. and Demmel, J. and Dongarra, J. and Du Croz, J. and Greenbaum, A. and Hammarling, S. and McKenney, A. and Sorensen, D.},
309+
title = {{LAPACK} Users' Guide},
310+
edition = {Third},
311+
publisher = {Society for Industrial and Applied Mathematics},
312+
address = {Philadelphia, PA},
313+
year = {1999},
314+
isbn = {0-89871-447-8},
315+
doi = {10.1137/1.9780898719604}
316+
}
317+
318+
@software{openblas,
319+
author = {{OpenBLAS developers}},
320+
title = {{OpenBLAS}: An optimized {BLAS} library},
321+
url = {https://github.com/OpenMathLib/OpenBLAS},
322+
version = {0.3.33},
323+
year = {2026}
324+
}
325+
326+
@software{ndarray,
327+
author = {{rust-ndarray developers}},
328+
title = {{ndarray}: an n-dimensional array for general elements and for numerics in {Rust}},
329+
url = {https://github.com/rust-ndarray/ndarray},
330+
version = {0.17.2},
331+
year = {2026}
332+
}
333+
334+
@inproceedings{enzyme,
335+
author = {Moses, William S. and Churavy, Valentin},
336+
title = {Instead of rewriting foreign code for machine learning, automatically synthesize fast gradients},
337+
booktitle = {Advances in Neural Information Processing Systems},
338+
volume = {33},
339+
year = {2020},
340+
pages = {12472--12485},
341+
url = {https://arxiv.org/abs/2010.01709}
342+
}

‎paper/paper.md‎

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ bibliography: paper.bib
4545

4646
# Summary
4747

48-
Peroxide is a numerical computing library for the Rust programming language that integrates eight domains within a single crate: linear algebra, ordinary differential equation (ODE) solving, adaptive quadrature, spline interpolation with exact polynomial calculus, root-finding, forward-mode automatic differentiation (AD), statistics, and multi-format DataFrame I/O.
48+
Peroxide is a Rust numerical computing library that integrates eight domains in one crate: linear algebra, ordinary differential equation (ODE) solving, adaptive quadrature, spline interpolation with exact polynomial calculus, root-finding, forward-mode automatic differentiation (AD), statistics, and multi-format DataFrame I/O.
4949
We designed Peroxide for applied scientists, engineers, and students who need a cohesive numerical environment in Rust without assembling a multi-crate dependency graph.
50-
A dual-module API provides progressive disclosure: the `prelude` module offers sensible defaults, while the `fuga` module exposes explicit algorithm selection, addressing Rust's lack of default function arguments.
50+
A dual-module API offers `prelude` defaults and a `fuga` module for explicit algorithm selection, addressing Rust's lack of default function arguments.
5151
Peroxide is released under the MIT/Apache-2.0 dual license and archived on Zenodo [@peroxide].
5252

5353
# Statement of need
@@ -58,12 +58,12 @@ In Python, SciPy [@scipy] and NumPy [@numpy] consolidate these capabilities unde
5858
In Rust, they are scattered across specialized crates, each with its own type conventions and trait hierarchies.
5959

6060
\autoref{tab:comparison} surveys the Rust numerical ecosystem.
61-
Specialist crates excel individually: diffsol [@diffsol] provides ODE/DAE solvers with sensitivity analysis; faer [@faer] offers pure-Rust linear algebra competitive with LAPACK; nalgebra [@nalgebra] provides matrix abstractions widely adopted across the ecosystem; argmin [@argmin] supplies over 20 optimization algorithms; Polars [@polars] dominates tabular data processing.
61+
Specialist crates excel individually: diffsol [@diffsol] provides ODE/DAE solvers with sensitivity analysis; faer [@faer] offers pure-Rust linear algebra competitive with LAPACK [@lapack]; nalgebra [@nalgebra] provides matrix abstractions widely adopted across the ecosystem; argmin [@argmin] supplies over 20 optimization algorithms; Polars [@polars] dominates tabular data processing.
6262
russell [@russell] covers the broadest range among alternatives (ODE solvers, quadrature, root-finding, and statistics) but lacks AD, spline calculus, and DataFrame support.
6363
No single crate spans all eight domains shown in \autoref{tab:comparison}.
6464
Peroxide fills this integration gap.
6565

66-
: Feature coverage of Rust numerical libraries. Each entry reflects the crate's own API, including optional feature flags; a dash indicates the feature is absent. Crates providing only N-dimensional array abstractions without numerical algorithms (e.g., ndarray) are omitted. \label{tab:comparison}
66+
: Feature coverage of Rust numerical libraries. Each entry reflects the crate's own API, including optional feature flags; a dash indicates the feature is absent. Crates providing only N-dimensional array abstractions without numerical algorithms (e.g., ndarray [@ndarray]) are omitted. \label{tab:comparison}
6767

6868
| | Peroxide | diffsol | russell | faer | nalgebra | argmin | num-dual | Polars |
6969
|---------------------|:--------:|:-------:|:-------:|:----:|:--------:|:------:|:--------:|:------:|
@@ -77,13 +77,15 @@ Peroxide fills this integration gap.
7777
| DataFrame I/O | $\checkmark$ | — | — | — | — | — | — | $\checkmark$ |
7878

7979
We do not claim superiority over any specialist crate within its domain.
80-
Peroxide's contribution is the integration itself, enabled by design abstractions that connect domains: a `ButcherTableau` trait with blanket implementation that unifies all Runge-Kutta methods through compile-time constants, a `Calculus` trait that supports exact differentiation and integration of piecewise polynomial splines, const-generic dimensional typing in the root-finding interface, and a `Real` trait that allows AD-derived derivatives to flow into optimization and root-finding routines without glue code.
80+
Peroxide's contribution is the integration itself, enabled by design abstractions: a `ButcherTableau` trait unifies Runge-Kutta methods via compile-time constants, a `Calculus` trait supports exact differentiation and integration of piecewise polynomial splines, const-generic typing constrains root-finding dimensions, and a `Real` trait carries AD-derived derivatives into optimization and root-finding without glue code.
8181

8282
# State of the field
8383

8484
In automatic differentiation specifically, a review of available Rust AD crates on crates.io indicates that, to our knowledge, Peroxide is the only library combining const-generic derivative order, normalized Taylor coefficient storage, and true Taylor-mode propagation with $O(N^2)$ cost per elementary operation.
8585
Most alternatives provide dual numbers up to second or third order with fixed type hierarchies [@numdual] or nested generics with exponential cost at higher orders [@autodiff_elrnv].
8686
The ad-trait crate [@adtrait] offers both forward and reverse modes but is limited to first-order derivatives.
87+
Enzyme [@enzyme] performs AD as an LLVM compiler pass and supports both forward and reverse modes.
88+
The two libraries are complementary: Peroxide provides high-order forward derivatives, while Enzyme adds reverse-mode AD.
8789

8890
For ODE solving, diffsol [@diffsol] is the most feature-rich Rust crate, providing BDF and SDIRK methods with sensitivity analysis.
8991
Peroxide's `ButcherTableau` trait-based architecture is a complementary approach: it encodes Runge-Kutta methods as compile-time constants, making it straightforward for users to add new methods by defining only coefficient arrays.
@@ -92,7 +94,8 @@ Peroxide's `ButcherTableau` trait-based architecture is a complementary approach
9294

9395
**Architecture.**
9496
We store matrices as a flat `Vec<f64>` with a `Shape` enum (`Row`/`Col`) that controls logical layout without copying data.
95-
This design trades the rich type-level dimensionality of nalgebra for a memory model that maps directly to both the pure-Rust `matrixmultiply` crate [@matrixmultiply] and, when the `O3` feature flag is enabled, to OpenBLAS, passing raw pointers with stride and transpose flags in both cases without intermediate type conversions.
97+
This design trades the rich type-level dimensionality of nalgebra for a memory model that maps directly to both the pure-Rust `matrixmultiply` crate [@matrixmultiply] and, when the `O3` feature flag is enabled, to OpenBLAS [@openblas], passing raw pointers with stride and transpose flags without intermediate type conversions.
98+
The trade-offs are that matrix dimensions are not enforced at compile time (unlike nalgebra's typed `Matrix<f64, R, C>`) and the layout does not extend to N-dimensional tensors as `ndarray` [@ndarray] does.
9699
A `Real` trait abstracts over `f64` and `AD` (= `Jet<2>`), so the same function can compute both values and derivatives.
97100

98101
**Automatic differentiation.**
@@ -144,20 +147,18 @@ let area = integrate(|x| x.sin(), (0.0, PI), GaussLegendre(15));
144147

145148
# Research impact statement
146149

147-
Peroxide has been publicly available on crates.io since 2018 and has accumulated over 1,050,000 total downloads (as reported by crates.io) and 677 GitHub stars.
148-
Independent researchers have adopted Peroxide in peer-reviewed work: @comitini2025 used Peroxide's Gauss-Kronrod quadrature as the numerical integration backend for their QCD screened massive expansion calculations, and @steuteville2024 identified Peroxide as one of the three most widely used Rust ODE solver packages in a survey conducted at the U.S. National Renewable Energy Laboratory.
149-
The author's own research has also relied on Peroxide: @neural_hamilton employed its implicit Gauss-Legendre ODE solver for symplectic reference solutions, @hyperboliclr used it for dataset generation, and @jho2026 used its Gauss-Kronrod quadrature (G7K15R) and cubic Hermite spline interpolation for primordial black hole axion spectral computations.
150+
Peroxide has been on crates.io since 2018, with over 1,100,000 downloads and 700 GitHub stars.
151+
Independent researchers have adopted Peroxide in peer-reviewed work: @comitini2025 used its Gauss-Kronrod quadrature for QCD screened massive expansion calculations, and @steuteville2024 identified Peroxide as one of the three most widely used Rust ODE solver packages in a survey conducted at the U.S. National Renewable Energy Laboratory.
152+
The author's own work has used Peroxide's implicit Gauss-Legendre ODE solver for symplectic reference solutions [@neural_hamilton], for dataset generation [@hyperboliclr], and for primordial black hole axion spectra via Gauss-Kronrod quadrature and cubic Hermite splines [@jho2026].
150153
The Zenodo archive [@peroxide] ensures long-term citability and reproducibility.
151154

152155
# Validation
153156

154-
We maintain a test suite of 26 test modules.
155-
The AD module alone contains 115 unit tests verifying `Jet<N>` at orders $N = 1$ through $10$ against symbolic reference values.
156-
Across all tested functions and derivative orders, `Jet<N>` achieves relative errors at the level of machine epsilon ($\sim 10^{-15}$); in contrast, central finite-difference approximations degrade to relative errors exceeding $10^{0}$ by order four due to the fundamental tension between truncation error $O(h^p)$ and cancellation error $O(\varepsilon_{\mathrm{mach}} / h^k)$ [@press2007].
157-
ODE integrators are tested against problems with known analytic solutions.
158-
Continuous integration runs via GitHub Actions on every push.
159-
The repository provides 41 standalone examples, and API documentation with KaTeX-rendered mathematics is published on [docs.rs/peroxide](https://docs.rs/peroxide).
160-
Community guidelines and contribution instructions are available in the repository's `CONTRIBUTING.md`.
157+
We maintain a test suite of 26 modules; the AD module alone has 115 unit tests verifying `Jet<N>` at orders $N = 1$ through $10$ against symbolic reference values.
158+
`Jet<N>` achieves machine-epsilon relative errors ($\sim 10^{-15}$) across all tested orders, while central finite differences degrade to $O(1)$ by order four due to the truncation/cancellation trade-off [@press2007].
159+
ODE integrators are tested against analytic solutions, with continuous integration on every push via GitHub Actions.
160+
The repository provides 41 standalone examples; API documentation (with KaTeX-rendered mathematics) is published on [docs.rs/peroxide](https://docs.rs/peroxide).
161+
Community guidelines are available in `CONTRIBUTING.md`.
161162

162163
# Limitations
163164

0 commit comments

Comments
 (0)