13个版本
0.5.3 | 2024年3月17日 |
---|---|
0.4.5-rc.1 | 2023年7月23日 |
0.4.4 | 2023年1月8日 |
0.4.3 | 2022年12月9日 |
0.3.1-alpha.1 | 2022年8月29日 |
#114 in 数学
36KB
684 行
自动微分库
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
- 不使用
num
和nalgebra
包
如路线图中所注,计划消除一些差异
在这个包中,你可以研究并启动测试目标 /tests/autodiff.rs
来了解一些差异。
cargo test --test autodiff -- --show-output
依赖关系
~1MB
~17K SLoC