scheme - 方案 - 使用表格的导数
问题描述
我正在尝试使用下面的代码获得方案中的导数。谁能告诉我哪里出错了?我一直试图弄清楚一段时间。
(define d3
(λ (e)
(cond ((number? e) 0)
((equal? e 'x) 1)
(else
;; We handle only BINARY ops here, and only + and *
(let ((op (car e)) (args (cdr e)))
(apply (lookup op d-op-table) args))))))
(define d-op-table
(list(list '+ (λ (u v) (+ (d3 u) (d3 v))))
(list '+ (λ (u1 v1)
(list '(* u1 (d v1)))(list '(* (d u1) v1))))))
(define lookup
(λ (op table)
(if (equal? op (caar table))
(cadar table)
(lookup op (cdr table)))))
当我运行该函数时,我收到以下错误。我输入,(d3'(* 2 x))。
caar: contract violation
expected: (cons/c pair? any/c)
given: '()
解决方案
查找表不正确,有时您评估表达式,但其他人您只是引用它们,而不评估它们。例如,'(* u1 (d v1))
将只计算为'(* u1 (d v1))
,实际上并未计算导数!乘法的情况看起来特别糟糕,它甚至没有正确的搜索键*
。
这更接近您的意图,请注意您需要更多的工作来实际检测哪些表达式可以简化 - 例如:(* 0 x)
is 0
,但这应该足以让您开始:
(define d-op-table
(list (list '+ (λ (u v) (list '+ (d3 u) (d3 v))))
(list '* (λ (u v)
(list '+
(list '* u (d3 v))
(list '* (d3 u) v))))))
现在您的示例有效:
(d3 '(* 2 x))
=> '(+ (* 2 1) (* 0 x))
如果你想写一个真正有用的微分程序,最好看看SICP。
推荐阅读
- angularjs - 如何在角度js中获取数组中特定列的最大值
- sql - 多个日期之间的平均时间
- c# - 正则表达式不会覆盖旧值
- php - 如何将 PHP 页面包含到另一个页面的 div 中?
- javascript - 如何使用 jquery 和 lodash 去抖动输入
- javascript - 拖放文件上传
- linux - 如何在 Windows 上为导入的 Laravel 项目重新配置 GIT 并部署到 Linux 服务器
- java - 从 Hadoop 工具传回多个值
- c# - WCF 客户端应用程序开始不断收到超时异常
- php - 如何在 Eclipse PHP 上使用 PDO MySQL 并在 PHP CLI 应用程序中运行?