首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用牛顿法求根

用牛顿法求根
EN

Stack Overflow用户
提问于 2019-12-26 16:37:57
回答 2查看 90关注 0票数 1

我编写newton-method以在elisp中从Scheme示例中找到根,如

代码语言:javascript
复制
#+begin_src emacs-lisp :session sicp :lexical t
(defun deriv(g)
  (lambda (x)
    (/ (- (funcall g (+ x dx)) (funcall g x))
       dx)))

(defvar dx 0.00001)
(defvar tolerance 0.00001)

(defun fixed-point(f guess)
  (defun close-enoughp(v1 v2)
    (< (abs (- v1 v2)) tolerance))
  (let ((next (funcall f guess)))
    (if (close-enoughp guess next)
        next
      (fixed-point f next))))

(defun newton-transform(g)
  (lambda (x)
    (- x (/ (funcall g x) (funcall (funcall #'deriv g) x)))))

(defun newton-method(g guess)
  (fixed-point (funcall #'newton-transform g) guess))

(defun curt(x)
  (newton-method (lambda (y) (- (* y y y) x))
                  1.0))

(curt 12)
#+end_src

#+RESULTS:
: 2.2894284851069058

它工作,但遵守扭曲的代码:

代码语言:javascript
复制
(defun newton-transform(g)
  (lambda (x)
    (- x (/ (funcall g x) (funcall (funcall #'deriv g) x)))))

三个funcall,其中如果更深的闭包,我无法想象糟糕。

用elisp解决这个问题有什么别的办法吗?(我想它不喜欢闭包)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-12-26 20:53:58

可以简化几个函数调用,我们应该实现@sds关于函数名称和约定的建议-如下所示:

代码语言:javascript
复制
(defvar dx 0.00001)
(defvar tolerance 0.00001)

(defun deriv (g)
  (lambda (x)
    (/ (- (funcall g (+ x dx)) (funcall g x))
       dx)))

(defun close-enough-p (v1 v2)
  (< (abs (- v1 v2)) tolerance))

(defun try (f guess)
  (let ((next (funcall f guess)))
    (if (close-enough-p guess next)
      next
      (try f next))))

(defun fixed-point (f first-guess)
  (try f first-guess))

(defun newton-transform (g)
  (lambda (x)
    (- x (/ (funcall g x)
            (funcall (deriv g) x)))))

(defun newton-method (g guess)
  (fixed-point (newton-transform g) guess))

(defun curt (x)
  (newton-method (lambda (y) (- (* y y y) x))
                 1.0))

注意,在调用先前定义和命名的函数(如funcallnewton-transform )时,不需要使用newton-transform

票数 1
EN

Stack Overflow用户

发布于 2019-12-26 18:20:32

newton-transform中,(funcall #'deriv g)(deriv g)是完全相同的,因此可以消除3funcall中的一种,而其他2的确是必要的。

对于newton-method也是如此:用(newton-transform g)替换(funcall #'newton-transform g)

PS。我强烈建议要么将defun close-enoughpdefun fixed-point中移出,要么将其转换为cl-flet。Lisp不是计划。

PPS.close-enoughp应该是close-enough-p

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59491056

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档