【问题标题】:AD Reflection - How does it work?AD 反射 - 它是如何工作的?
【发布时间】:2017-05-10 10:36:34
【问题描述】:

我看过ad 包,我了解它是如何通过提供class Floating 的不同实例然后实现衍生规则来自动区分的。

但在示例中

Prelude Debug.SimpleReflect Numeric.AD> diff atanh x
recip (1 - x * x) * 1

我们看到它可以将函数表示为ASTs,并将它们显示为带有变量名的字符串。

我想知道他们是怎么做到的,因为当我写的时候:

f :: Floating a => a -> a
f x = x^2

无论我提供什么实例,我都会得到一个函数 f :: Something -> Something 而不是 f :: ASTf :: String 之类的表示

实例无法“知道”参数是什么。

他们是怎么做到的?

【问题讨论】:

  • ad 包使用了很多魔法底层和很多自定义类型类。实际上不是关于ad,但你可以观看这个关于设计AutomaticDifferentiation库的视频:youtube.com/watch?v=q1DUKEOUoxA&t=4322s
  • 请注意,要获得recip (1 - x * x) * 1,您必须将diff atanh 应用于x。简单的x 不张扬,但它是您在这里看到的魔法的核心。

标签: haskell reflection typeclass instances automatic-differentiation


【解决方案1】:

实际上,它与 AD 包无关,与 diff atanh x 中的 x 无关。

要看到这一点,让我们定义自己的 AST 类型

data AST = AST :+ AST
         | AST :* AST
         | AST :- AST
         | Negate AST
         | Abs AST
         | Signum AST
         | FromInteger Integer
         | Variable String

我们可以为这个类型定义一个Num实例

instance Num (AST) where
  (+) = (:+)
  (*) = (:*)
  (-) = (:-)
  negate = Negate
  abs = Abs
  signum = Signum
  fromInteger = FromInteger

还有一个Show 实例

instance Show (AST) where
  showsPrec p (a :+ b) = showParen (p > 6) (showsPrec 6 a . showString " + " . showsPrec 6 b)
  showsPrec p (a :* b) = showParen (p > 7) (showsPrec 7 a . showString " * " . showsPrec 7 b)
  showsPrec p (a :- b) = showParen (p > 6) (showsPrec 6 a . showString " - " . showsPrec 7 b)
  showsPrec p (Negate a) = showParen (p >= 10) (showString "negate " . showsPrec 10 a)
  showsPrec p (Abs a) = showParen (p >= 10) (showString "abs " . showsPrec 10 a)
  showsPrec p (Signum a) = showParen (p >= 10) (showString "signum " . showsPrec 10 a)
  showsPrec p (FromInteger n) = showsPrec p n
  showsPrec _ (Variable v) = showString v

所以现在如果我们定义一个函数:

f :: Num a => a -> a
f a = a ^ 2

和一个 AST 变量:

x :: AST
x = Variable "x"

我们可以运行该函数来生成整数值或 AST 值:

λ f 5
25
λ f x
x * x

如果我们希望能够将我们的 AST 类型与您的函数 f :: Floating a => a -> a; f x = x^2 一起使用,我们需要扩展其定义以允许我们实现 Floating (AST)

【讨论】:

  • 值得注意的是,Debug.SimpleReflect 模块是示例中x 的来源。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-23
  • 1970-01-01
  • 2021-09-26
  • 2011-03-18
相关资源
最近更新 更多