1个不稳定版本
0.1.0 | 2023年11月12日 |
---|
#1483 在 算法
22KB
651 行
frechet
frechet
实现了简单的双数类型 dual32
和 dual64
,从而提供了基本的自动微分功能。
示例
use frechet::*;
fn p(x: dual32) -> dual32 { x.powf(2.5).atanh() + 1.0 }
fn p_derivative(x: f32) -> f32 { -2.5 * x.powf(1.5)/(x.powi(5) - 1.0) }
// using the `derivative` function
let z1 = derivative(p, 2.0);
// manually
let z2 = p(2.0.as_dual_variable()).d;
// exact derivative
let z3 = p_derivative(2.0);
assert!((z1 - z3).abs() < f32::EPSILON);
assert!((z2 - z3).abs() < f32::EPSILON);
lib.rs
:
frechet
是一个库,提供了与标准浮点类型接口相似的简单双数类型。此外,还提供了一个小的接口来抽象导数的计算。
关于双数的复习
一个双数 $z$ 表示为“实部” $x$ 和“虚部” $y$ 的和,写作 $z = x + yj$,其中 $j$ 是纯符号的,遵循规则 $j^2 = 0$。例如,在双数 $X + j$ 上评估多项式 $P(X)=3X^2-X+1$ 得到 $$P(X+j)=3X^2-X+1 + (6X-1)j = P(X) + P^\prime(X)j.$$ 这促使将任何(可微的)实函数 $f$ 扩展到双数:$$f(x+yj) = f(x) + yf^\prime(x)j.$$
示例
use frechet::*;
fn p(x: dual32) -> dual32 { x.powf(2.5).atanh() + 1.0 }
fn p_derivative(x: f32) -> f32 { -2.5 * x.powf(1.5)/(x.powi(5) - 1.0) }
// using the `derivative` function
let z1 = derivative(p, 2.0);
// manually
let z2 = p(2.0.as_dual_variable()).d;
// exact derivative
let z3 = p_derivative(2.0);
assert!((z1 - z3).abs() < f32::EPSILON);
assert!((z2 - z3).abs() < f32::EPSILON);