13个版本

0.5.3 2024年3月17日
0.4.5-rc.12023年7月23日
0.4.4 2023年1月8日
0.4.3 2022年12月9日
0.3.1-alpha.12022年8月29日

#114 in 数学

MIT/Apache

36KB
684

自动微分库

crates.io docs build rust-clippy analyze

AUTOmatic Derivatives & Jacobians by djmaxus and you

功能

单变量

use autodj::prelude::single::*;

let x : DualF64 = 2.0.into_variable();

// Arithmetic operations are required by trait bounds
let _f = x * x + 1.0.into();

// Arithmetic rules itself are defined in `Dual` trait
// on borrowed values for extendability
let f = (x*x).add_impl(&1.0.into());

// Dual can be decomposed into a value-derivative pair
assert_eq!(f.decompose(), (5.0, 4.0));

// fmt::Display resembles Taylor expansion
assert_eq!(format!("{f}"), "5+4∆");

多变量

多元微分基于多个双分量。这种方法不需要重复和“反向”微分。每个偏导数从开始就单独追踪,不进行重复计算。

对于内置的多变量专业化,可以使用.into_variables()方法一致地创建独立变量。

静态变量数量

use autodj::prelude::array::*;

// consistent set of independent variables
let [x, y] : [DualNumber<f64,2>; 2] = [2.0, 3.0].into_variables();

let f = x * (y - 1.0.into());

assert_eq!(f.value()        , & 4.);
assert_eq!(f.dual().as_ref(), &[2., 2.]);
assert_eq!(format!("{f}")   , "4+[2.0, 2.0]∆");

动态变量数量

use autodj::prelude::vector::*;
use std::ops::Add;

let x = vec![1., 2., 3., 4., 5.].into_variables();

let f : DualF64 = x.iter()
                   .map(|x : &DualF64| x.mul_impl(&2.0.into()))
                   .reduce(Add::add)
                   .unwrap();

assert_eq!(f.value(), &30.);

f.dual()
 .as_ref()
 .iter()
 .for_each(|deriv| assert_eq!(deriv, &2.0) );

泛型双数

// A trait with all the behavior defined
use autodj::fluid::Dual;
// A generic data structure which implements Dual
use autodj::solid::DualNumber;

动机

我在计算数学领域进行学术和商业研发。像我们许多人一样,我亲手编写了很多复杂的雅可比矩阵。

有一天,我了解到了基于双数的自动微分。几乎是同一天,我也了解了Rust语言 🦀

然后,我决定

  • 尽可能使其自动化和可靠
  • 使用现代便捷的Rust开发生态系统

项目目标

  • 为学术和商业计算数学家开发开源自动微分库
  • 获得Rust编程经验

预期功能

非常欢迎您提出问题来推动最受欢迎的功能或报告错误。

  • 双数的泛型实现
  • 要微分变量的数量
    • 单个
    • 多个
      • 静态
      • 动态
      • 稀疏
    • 雅可比矩阵(内存中高效布局以立即创建矩阵)
  • 命名变量(基于UUID)
  • 计算跟踪(中间值的偏导数)
  • 第三方Crates支持(作为功能)
    • num-traits
    • 线性代数Crates(nalgebra等)
  • no_std支持
  • 高级功能
    • 除了 f64 以外的任意数字类型
    • 不同双精度类型(例如,单精度和双精度)的互操作性
    • 导数的数值验证(或替换)(按定义)
    • 用于自动扩展常规(即非双精度)函数的宏
    • 可选的导数计算
      • 可能的后向微分
      • 迭代器实现作为可能的惰性评估方法

autodiff 的比较

据我所知,autodj 目前有以下不同之处

  • 开箱即用的多变量
  • 用于静态已知数量的变量的 fmt::Display
  • 许多操作如 .into-variables().eval() 等,从左到右的流程
  • 数字类型限制为 f64
  • 不使用 numnalgebra

如路线图中所注,计划消除一些差异

在这个包中,你可以研究并启动测试目标 /tests/autodiff.rs 来了解一些差异。

cargo test --test autodiff -- --show-output

依赖关系

~1MB
~17K SLoC