# aegir [![Crates.io](https://img.shields.io/crates/v/aegir.svg)](https://crates.io/crates/aegir) [![Build Status](https://travis-ci.org/tspooner/aegir.svg?branch=master)](https://travis-ci.org/tspooner/aegir) [![Coverage Status](https://coveralls.io/repos/github/tspooner/aegir/badge.svg?branch=master)](https://coveralls.io/github/tspooner/aegir?branch=master) ## Overview > Strongly-typed, compile-time autodifferentiation in Rust. `aegir` is an experimental autodifferentiation framework designed to leverage the powerful type-system in Rust and _avoid runtime as much as humanly possible_. The approach taken resembles that of expression templates, as commonly used in linear-algebra libraries written in C++. ### Key Features - Built-in arithmetic, linear-algebraic, trigonometric and special operators. - Infinitely differentiable: _Jacobian, Hessian, etc..._ - Custom DSL for operator expansion. - Decoupled/generic tensor type. ## Installation ```toml [dependencies] aegir = "1.0" ``` ## Example ```rust #[macro_use] extern crate aegir; extern crate rand; use aegir::{Differentiable, Function, Identifier, Node, ids::{X, Y, W}}; db!(Database { x: X, y: Y, w: W }); fn main() { let mut weights = [0.0, 0.0]; let x = X.into_var(); let y = Y.into_var(); let w = W.into_var(); let model = x.dot(w); // Using standard method calls... let sse = model.sub(y).squared(); let adj = sse.adjoint(W); // ...or using aegir! macro let sse = aegir!((model - y) ^ 2); let adj = sse.adjoint(W); for _ in 0..100000 { let [x1, x2] = [rand::random::(), rand::random::()]; let g = adj.evaluate(Database { // Independent variables: x: [x1, x2], // Dependent variable: y: x1 * 2.0 - x2 * 4.0, // Model weights: w: &weights, }).unwrap(); weights[0] -= 0.01 * g[0][0]; weights[1] -= 0.01 * g[0][1]; } println!("{:?}", weights.to_vec()); } ```