Skip to content

Latest commit

 

History

History
50 lines (43 loc) · 1.67 KB

README.md

File metadata and controls

50 lines (43 loc) · 1.67 KB

diffomatic

Diffomatic is a demonstration of automatic differentiation algorithms in Rust.

Demo

Forward mode:

use nalgebra::SMatrix;
use diff_lib::forward as fdiff;
use diff_lib::reverse as rdiff;

// API for forward mode
//
// derivative(f, x)
let f1_test = |x: fdiff::DualScalar| x * x;
let f1_result: f64 = fdiff::derivative(f1_test, 2.0);
println!("Derivative of f(x) = x^2 at {} is {}", 2.0, f1_result);

// gradient(f, x)
let f2_test = |x: &[fdiff::DualScalar]| x[0] + x[1];
let f2_result: Vec<f64> = fdiff::gradient(f2_test, vec![1., 2.].as_slice());
println!("Gradient of f(x,y) = x + y at ({}, {}) is {:?}", 1.0, 2.0, f2_result);

// jacobian(f, x)
// f(1) = x^2 * y
// f(2) = x + y
let f3_test = |x: &[fdiff::DualScalar]| {
vec![x[0] * x[0] * x[1], x[0] + x[1]]
};
let f3_result: SMatrix<f64, 2, 2> = fdiff::jacobian(f3_test, vec![1., 2.].as_slice());
println!("Jacobian of f(x,y) = [x^2 * y , x + y] at ({}, {}) is {:?}", 1.0, 2.0, f3_result);

Reverse mode:

// API for reverse mode
let tape = rdiff::Tape::new();
let x = tape.var(1.0);
let y = tape.var(1.0);
let z = -2.0 * x + x * x * x * y + 2.0 * y;
let grad = z.backprop();
println!("dz/dx of z = -2x + x^3 * y + 2y at x=1.0, y=1.0 is {}", grad.wrt(x));
println!("dz/dy of z = -2x + x^3 * y + 2y at x=1.0, y=1.0 is {}", grad.wrt(y));

Other Similar Projects and Credits

Forward mode implementation is based and inspired by:

  • elrnv/autodiff: a forward-diff library with nice features.
  • kophy/autodiff: a small dual-number implementation for forward-diff.

Reverse mode implementation is based on this exellent post by Rufflewind.