[][src]Crate fwd_ad

Fwd:AD a crate for Forward Auto-Differentiation

This crate allows you to easily write operations on dual numbers and do forward automatic differentiation. It empowers its user to write auto-differentiation code with minimal allocations.

Key selling-points

  1. Clone-free by default. Fwd:AD will never clone memory in its functions (except to_owning()) and std::ops implementations, leveraging Rust's ownership system to ensure correctness memory-wise, and leaving it up to the user to be explicit as to when cloning should happen.
  2. Automatic cloning on demand. If passed the implicit-clone feature, Fwd:AD will implicitly clone Duals when needed. Deciding whether to clone or not is entirely done via the type-system, and hence at compile time.
  3. Generic in memory location: Fwd:AD's structs are generic over a container type, allowing them to be backed by any container of your choice: Vec to rely on the heap, arrays if you're more of a stack-person, or other. For example, it can be used with &mut [f64] to allow an FFI API that won't need to copy memory at its frontier.

Examples

Detailled examples are available in the examples/ directory, but some snippets are reproduced below.

Rosenbrock function minimization

extern crate fwd_ad;
use fwd_ad::*;

// The factor by which we will descend along the gradient.
// Rosenbrock function is pretty steep so its quite small.
const ALPHA : f64 = 1e-3;

fn main() {
    // Create two duals with two derivatives each, as well as
    // closures getdx and getdy to get their corresponding derivative
    generate_duals!{
        x = 0.; @ getdx
        y = 0.; @ getdy
    }
    for _ in 0..10000 {
        let xval : f64 = x.val();
        let yval : f64 = y.val();

        let res = (x.clone() - 1.).powf(2.) + 100.*(y-x.powf(2.)).powf(2.);
        println!("At x={}, y={}, the rosenbrock function is {}",xval, yval, res.val());

        generate_duals!{
            newx = xval - ALPHA*getdx(res.view());
            newy = yval - ALPHA*getdy(res.view());
        }
        x = newx;
        y = newy;
    }
}

Comparision with other (forward) AD rust libraries

The last-update column represent the last time the corresponding crate was checked. Crates may have evolved since.

crateversionmulti-variatehigher-orderlast update
Fwd:AD0.1.0✔️2020-04-29
ad0.1.02020-01-01
autodiff0.1.92019-11-07
descent¹0.3✔️(2nd order?)2018-12-10
dual0.2.02015-12-25
dual_num0.2.72019-04-03
hyperdual²0.3.4✔️2020-02-08
peroxide0.21.7(2nd order)2020-04-21
  1. descent Automatic differentiation seems promising but isn't very documented and is mixed-up with the IP-OPT interface
  2. hyperdual has similar properties to Fwd:AD, except that all operations will allocate when Fwd:AD tries to reuse existing memory

Re-exports

pub use view_and_owning_traits::ROAble;
pub use view_and_owning_traits::RWAble;
pub use view_and_owning_traits::ToOwning;
pub use view_and_owning_traits::ToView;
pub use owning_markers::CompatibleWith;
pub use owning_markers::OwningMode;
pub use owning_markers::RO;
pub use owning_markers::RW;

Modules

instanciations
owning_markers

A module containing marker types used to indicated whether a Dual can write or not in its content.

view_and_owning_traits

Macros

generate_duals

Generate n duals with n derivatives, one for each varable.

Structs

Dual

The struct implementing dual numbers.

Traits

Scalar