A super restrictive WIP beginnings of a library attempting to implement auto-differentiation in Rust.
Auto-differentiation is implemented via 2 attribute procedural macros:
forward_autodiff
```rust
fn functionname(x:f32, y:f32) -> f32 {
let p = 7. * x;
let r = 10. - y;
let q = p * x * 5.;
let v = 2. * p * q + 3. * r;
return v;
}
Expands to:
rust
fn forfunctionname(x: f32, y: f32, derx: f32, dery: f32) -> (f32, f32) {
let a = 7. * x;
let dera = x * 0f32 + 7. * derx;
let b = 3. * x;
let derb = x * 0f32 + 3. * derx;
let c = x + b;
let derc = derx + derb;
let d = y + b;
let derd = dery + derb;
let d = _d + c;
let derd = der_d + derc;
return (d, der_d);
}
```
reverse_autodiff
```rust
fn functionname(x: f32, y: f32) -> f32 {
let a = 7. * x;
let b = 3. * x;
let c = x + b;
let d = y + b + c;
return d;
}
Expands to:
rust
fn revfunctionname(x: f32, y: f32, derd: f32) -> (f32, f32, f32) {
let (x0, x1, x2) = (x.clone(), x.clone(), x.clone());
let (y0,) = (y.clone(),);
let a = 7. * x0;
let b = 3. * x1;
let (b0, b1) = (b.clone(), b.clone());
let c = x2 + b0;
let (c0,) = (c.clone(),);
let d = y0 + b1;
let (d0,) = (d.clone(),);
let d = _d0 + c0;
let (derd0, derc0) = (d.clone(), d.clone());
let derd = derd0;
let (dery0, derb1) = (d.clone(), _d.clone());
let derc = derc0;
let (derx2, derb0) = (c.clone(), c.clone());
let derb = derb0 + derb1;
let derx1 = 3. * b;
let derx0 = 7. * a;
let dery = dery0;
let derx = derx0 + derx1 + derx2;
return (d, derx, dery);
}
```