forward API

forward 包把一个作用于对偶数的函数转换为它在某点处的导数。它包含两个标量前向模式驱动函数 diff 和 value_and_diff,并重新导出 Dual。根包重新导出了这两个函数,因此大多数程序以 @autodiff.diff 和 @autodiff.value_and_diff 的形式调用它们。

源码:src/forward/forward.mbt。

导入

import {
  "Luna-Flow/autodiff/forward",
}

驱动函数

value_and_diff

在 x 处对 f 求值,返回值及一阶导数。

pub fn[T : @luna-generic.One] value_and_diff((@dual.Dual[T]) -> @dual.Dual[T], T) -> (T, T)

它调用一次 f(Dual::variable(x)) 并返回 (y.value(), y.tangent())。根据 dual 设计,当 f 由 Dual[T] 的运算构建、并把其他所有输入都视为常数时,这个二元组就是 (f(x),f′(x))(f(x), f'(x))。代价是在对偶数上对 f 求值一次。f 不得检查其参数的切向分量;f 所做的一切都会被求导,包括基于 value() 的分支。

diff

只返回导数 f′(x)f'(x)。

pub fn[T : @luna-generic.One] diff((@dual.Dual[T]) -> @dual.Dual[T], T) -> T

diff(f, x) 是 value_and_diff(f, x) 的第二个分量。

test "scalar drivers" {
  let (value, derivative) = @forward.value_and_diff(x => x * x * x, 2.0)
  assert_eq(value, 8.0)
  assert_eq(derivative, 12.0)
  assert_eq(@forward.diff(x => x.sin(), 0.0), 1.0)
}

重新导出的类型

Dual

pub using @dual {type Dual} 使 @forward.Dual 与 @dual.Dual 成为同一类型;见 dual API。

pub using @dual {type Dual}