2 unstable releases
new 0.7.0 | Feb 3, 2025 |
---|---|
0.1.0 | Jan 26, 2025 |
#55 in #automatic-differentiation
104 downloads per month
Used in aad
10KB
139 lines
aad - Automatic Adjoint Differentiation Library
A pure Rust automatic differentiation library using reverse-mode adjoint differentiation.
Features
- Supports both f32 and f64: Generic implementation works with any floating-point type implementing
num_traits::Float
. - Reverse-mode autodiff: Efficiently compute gradients for scalar-valued functions with many inputs.
- Operator overloading: Use standard mathematical operators with variables.
- High Performance: Optimized for minimal runtime overhead.
- Benchmarks show competitive performance, often outperforming alternatives in gradient computation ( see Benchmarks).
- Type-agnostic functions: Write generic mathematical code using the
FloatLike
trait. - Derive macros: Automatically generate differentiable functions with
#[autodiff]
macro (requiresderive
feature).
Installation
Add to your Cargo.toml
:
[dependencies]
aad = { version = "0.5.0", features = ["derive"] }
Usage
Basic Example
use aad::Tape;
fn main() {
// Initialize computation tape
let tape = Tape::default();
// Create variables
let [x, y] = tape.create_variables(&[2.0_f64, 3.0_f64]);
// Build computation graph
let z = (x + y) * x.sin();
// Forward pass
println!("z = {:.2}", z.value()); // z = 4.55
// Reverse pass
let gradients = z.compute_gradients();
println!("Gradients: dx = {:.2}, dy = {:.2}",
gradients.get_gradients(&[x, y]));
// Gradients: dx = -1.17, dy = 0.91
}
Using Macros for Automatic Differentiation
Enable the derive
feature and use #[autodiff]
to automatically differentiate functions:
use aad::{Tape, autodiff};
#[autodiff]
fn f(x: f64, y: f64) -> f64 {
5.0 + 2.0 * x + y / 3.0
}
fn main() {
let tape = Tape::default();
let [x, y] = tape.create_variables(&[2.0_f64, 3.0_f64]);
// Compute value and gradients
let z = f(x, y);
let gradients = z.compute_gradients();
println!("Result: {:.2}", z.value()); // 5.0 + 4.0 + 1.0 = 10.00
println!("Gradients: dx = {:.2}, dy = {:.2}",
gradients.get_gradients(&[x, y]));
// Gradients: dx = 2.00, dy = 0.33
}
Benchmarks
Run benchmarks with:
cargo bench --features benchmarks
License
MIT License - see LICENSE
Dependencies
~210–650KB
~15K SLoC