13

我听说 McCarthy 发明 Lisp 的最初动机之一是编写一个用于自动区分的系统。尽管如此,我的谷歌搜索并没有产生任何库/宏来执行此操作。是否有任何 Scheme/Common Lisp/Clojure 库(宏)用于获取函数 F 并返回计算 F 导数的函数 dF/dx?

我希望它支持具有多个参数的 F。用户将选择其中哪个是要区分的 x。理想情况下,微分器甚至适用于向量值 F 和 x。

编辑:有几个人提到了符号分化。符号微分和自动微分之间的区别是一个微妙的区别,但它在维基百科中得到了很好的总结,尤其是在这张图片中。这种区别在 lisp 中没有那么明显,其中符号表达式可以按原样转换为工作程序,但仍然存在潜在的困难:

符号微分要求被微分的表达式由已知导数的运算组成。例如,有人提到了 SICP 的宏示例,该示例通过简单的性别来搅动(+ y (* (x y))),并使用链式法则,以及如何区分+和的知识*,返回代表导数的性别。我需要它来处理诸如(* (foo x y) (bar x)), where之类的表达式,foo并且bar可能反过来调用其他函数,这些函数的导数在微分时是未知的。

如果有一种方法可以将表达式 like(foo x y)替换为它的函数体,用xy以一种卫生的方式替换任何对参数的提及,这将是很好的。有没有?

此外,以上都没有解决向量值函数相对于向量值参数微分时出现的复杂性......这是大多数自微分实现所针对的。

4

7 回答 7

8

阿列克谢·拉杜尔写道:

嗯,Scmutils 中有自动微分系统

http://groups.csail.mit.edu/mac/users/gjs/6946/linux-install.htm

(巧合的是,它也进行了符号区分)。我不知道任何其他已发布的实现,尽管您可以查看http://autodiff.org/

在经典力学的结构和解释的附录中也有一个很好的解释如何自己实现它

http://mitpress.mit.edu/sicm/

以及在学术文献中。特别是前向模式并不难,尽管您必须小心避免扰动混淆。您可以查阅 Barak Pearlmutter 和 Jeffrey Mark Siskind 的出版物,他们正在合作开发一种包含 AD 的高性能 Lisp 变体,并且一直在围绕相关问题发表文章。

http://scholar.google.com/scholar?q=Barak+Pearlmutter+and+Jeffrey+Mark+Siskind

于 2011-02-04T20:30:49.627 回答
4

还有另外两个包,都用于 Scheme 中的自动微分。第二个是在第一个的基础上,但被重新设计为鸡蛋。这些支持正向和反向模式。

于 2013-04-10T12:35:26.870 回答
3

如果您正在寻找一个符号系统,您可以尝试最大值(或此处)。它在许多 Common-Lisp/OS 平台组合上运行,但更像是一个完整的系统而不是库。

控制台输出还可以,但与texmacs结合使用时可以产生非常漂亮的输出。

Maxima 5.23.2 http://maxima.sourceforge.net
using Lisp GNU Common Lisp (GCL) GCL 2.6.8 (a.k.a. GCL)
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1) diff(sin(1/x),x);
                                        1
                                     cos(-)
                                         x
(%o1)                              - ------
                                        2
                                       x

编辑

好的,看来我误解了这个问题。一些谷歌搜索表明,这里的 SCMUTILS 中有一些工具,下载这里,用户手册这里(见 p24 起)。

于 2011-02-03T23:19:45.687 回答
2

scmutlis现在已被移植到 Clojure可能很有趣。还有很多工作要做,但 SICM 书第一章中的代码似乎运行良好。

微分例程和运算符在我所做的少量测试中似乎也不错,而且它甚至没有一些似乎已经潜入到更高版本的 scmutils 中的错误。

我认为 scmutils 涵盖了 OP 的重新区分需求,因为它将正确处理已知和未知(文字)函数的派生。此页面提供了查看它是否符合要求所需的详细信息: SICM - Derivatives - Notation

在 JVM 上运行的优点之一是,如果需要,它将作为独立运行,甚至不需要安装 Clojure!

它非常接近最初的 Scheme,对 Clojure 语法做出了最小的让步。

你可以在这里看到它: https ://github.com/littleredcomputer/sicmutils#sicmutils

===

附录:这里是一个在 SicmUtils Clojure 包中自动微分的例子。这是一个在各个网站上流传的常见例子,要区分的代码是

    function f(x)
      y = x;
      for i=1...100
        y = sin(x+y);
      return y

在 Clojurifying 之后我们有

   > (defn inner [y] (fn[x] (sin (+ x y))))
   > (defn f100 [x] (nth (iterate (inner x) x) 100))
   ;; value of derivative at 6
   > ((D f100) 6)
    => 0.51603111348625
   ;; value of the 4th derivative at 1
   > (((expt D 4) f100) 1)
    => -1.7853200839806143
于 2016-01-24T04:55:51.967 回答
1

是常见的 lisp 中的 AD 实现。

于 2011-04-28T23:25:54.700 回答
1

值得一试 Deriva,它对 Clojure 和 Java 进行自动微分:

您可能还对 expresso 感兴趣,它更多地是关于数值表达式操作,但仍具有一些差异化功能,并且可能适用于大多数 AD 用例:

于 2013-11-04T05:41:22.190 回答
-1

谷歌“lisp 符号微分”,你会发现很多例子,例如

http://mitpress.mit.edu/sicp/full-text/sicp/book/node39.html

于 2011-02-03T23:34:18.303 回答