1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
//! # `xad-rs` — Automatic Differentiation for Rust
//!
//! A fast, ergonomic, type-safe automatic differentiation library for
//! Rust. `xad-rs` is an unofficial port of the C++
//! [XAD](https://github.com/auto-differentiation/xad) library by Xcelerit,
//! and ships all four of the canonical AD flavours in a single crate.
//!
//! Automatic differentiation computes derivatives of arbitrary programs
//! **exactly**, to machine precision, without finite-difference error or
//! symbolic manipulation. `xad-rs` is suitable for quantitative finance,
//! optimisation, machine learning, computational physics, and any setting
//! where gradients or Hessians of non-trivial numerical code are needed.
//!
//! ## Picking a mode
//!
//! | Type | Mode | Order | Seeds | Use when |
//! |---|---|---|---|---|
//! | [`FReal<T>`](freal::FReal) | Forward (tangent) | 1st | 1 direction | few inputs, many outputs |
//! | [`Dual`] | Forward, multi-variable | 1st | `n` in one pass | full gradient in one forward sweep |
//! | [`Dual2<T>`](dual2::Dual2) | Forward, second-order | 1st + 2nd | 1 direction | diagonal Hessian / own-gamma |
//! | [`AReal<T>`](areal::AReal) + [`Tape`] | Reverse (adjoint) | 1st | 1 adjoint seed | many inputs, few outputs (gradients of scalar losses) |
//!
//! Reverse mode is the right choice for `f: Rⁿ → R` with `n` larger than a
//! handful (the break-even vs. forward mode sits around `n ≈ 4` in this
//! crate after the April 2026 perf refactor — see `CHANGELOG.md`). Forward
//! mode is the right choice when there are few inputs (1–3) or many
//! outputs relative to inputs.
//!
//! ## Quick start — reverse mode gradient
//!
//! ```
//! use xad_rs::areal::AReal;
//! use xad_rs::tape::Tape;
//! use xad_rs::math;
//!
//! let mut tape = Tape::<f64>::new(true);
//! tape.activate();
//!
//! // f(x, y) = x² · y + sin(x), at (x, y) = (3, 4)
//! let mut x = AReal::new(3.0);
//! let mut y = AReal::new(4.0);
//! AReal::register_input(std::slice::from_mut(&mut x), &mut tape);
//! AReal::register_input(std::slice::from_mut(&mut y), &mut tape);
//!
//! let mut f = &(&x * &x) * &y + math::ad::sin(&x);
//! AReal::register_output(std::slice::from_mut(&mut f), &mut tape);
//! f.set_adjoint(&mut tape, 1.0);
//! tape.compute_adjoints();
//!
//! // ∂f/∂x = 2xy + cos(x) ≈ 23.010
//! // ∂f/∂y = x² = 9.0
//! let dfdx = x.adjoint(&tape);
//! let dfdy = y.adjoint(&tape);
//! assert!((dfdx - (2.0 * 3.0 * 4.0 + 3.0_f64.cos())).abs() < 1e-12);
//! assert!((dfdy - 9.0).abs() < 1e-12);
//! # xad_rs::tape::Tape::<f64>::deactivate_all();
//! ```
//!
//! ## Quick start — forward mode (multi-variable)
//!
//! Seed all inputs in a single `n`-dimensional [`Dual`] and one forward
//! pass yields the whole gradient:
//!
//! ```
//! use xad_rs::dual::Dual;
//!
//! // f(x, y) = x² · y, at (x, y) = (3, 4)
//! let n = 2;
//! let x = Dual::variable(3.0, 0, n);
//! let y = Dual::variable(4.0, 1, n);
//! let f = &(&x * &x) * &y;
//! assert_eq!(f.real(), 36.0);
//! assert_eq!(f.partial(0), 24.0); // ∂f/∂x = 2xy
//! assert_eq!(f.partial(1), 9.0); // ∂f/∂y = x²
//! ```
//!
//! ## Second-order derivatives
//!
//! ```
//! use xad_rs::dual2::Dual2;
//!
//! // f(x) = x³, at x = 2
//! let x: Dual2<f64> = Dual2::variable(2.0);
//! let y = x * x * x;
//! assert_eq!(y.value(), 8.0); // f(x)
//! assert_eq!(y.first_derivative(), 12.0); // 3x²
//! assert_eq!(y.second_derivative(),12.0); // 6x
//! ```
//!
//! ## Crate naming
//!
//! The crate name on crates.io is **`xad-rs`**; the library target is
//! **`xad_rs`** (Cargo rewrites the hyphen to an underscore), which is
//! what you write in `use` statements:
//!
//! ```ignore
//! use xad_rs::areal::AReal;
//! use xad_rs::tape::Tape;
//! ```
//!
//! ## Modules
//!
//! - [`areal`] — reverse-mode active scalar, records on a [`Tape`]
//! - [`dual`] — forward-mode multi-variable dual number
//! - [`dual2`] — forward-mode second-order dual number
//! - [`freal`] — forward-mode single-variable active scalar
//! - [`math`] — AD-aware transcendental functions (`sin`, `exp`, `erf`, …)
//! for every active type, in `math::ad::*` and `math::fwd::*` submodules
//! - [`tape`] — tape data structure and active-tape thread-local slot
//! - [`jacobian`] — convenience `compute_jacobian_rev` / `compute_jacobian_fwd`
//! - [`hessian`] — convenience `compute_hessian` (scalar-valued functions)
//! - [`traits`] — the [`Scalar`] trait bound
//!
//! The [`adj`], [`adjf`], [`fwd`], and [`fwdf`] submodules re-export the
//! C++ XAD-style type aliases (`ActiveType`, `PassiveType`, `TapeType`)
//! to make porting C++ XAD code mechanical.
//!
//! ## Performance
//!
//! See [`CHANGELOG.md`](https://github.com/sercanatalik/xad-rs/blob/master/CHANGELOG.md)
//! for the full write-up of the 8-stage April 2026 perf refactor. Selected
//! numbers on an Apple M4 Pro (Rust 1.92 release):
//!
//! | Workload | Time | Speedup vs. pre-refactor |
//! |---|---:|---:|
//! | Swap pricer, 30-input reverse mode | 1.86 µs | 4.36× |
//! | FX option, 6-input reverse mode | 682 ns | 2.49× |
//! | FX option, 6-input forward `Dual` | 423 ns | 2.16× |
//! | FX option, `Dual2` spot gamma | 23 ns | 1.57× |
//!
//! Reproducible with `cargo bench`. See `benches/operators.rs` and
//! `benches/pricing.rs` for the Criterion harness.
//!
//! ## License
//!
//! `xad-rs` is licensed under the **GNU Affero General Public License
//! v3.0 or later**, matching upstream XAD. See `LICENSE.md` for the full
//! text.
pub use AReal;
pub use Dual;
pub use Dual2;
pub use FReal;
pub use ;
pub use Scalar;
/// Convenience type aliases matching the C++ XAD interface