方案“申请:不是程序;”在计算导数时

时间:2012-11-08 06:17:42

标签: recursion functional-programming scheme derivative

我是Scheme的新手,正致力于实现随机梯度下降的任务。到目前为止,我相信我的程序结构是正确的,但是我的程序采用函数f(x)的导数给我带来了一些麻烦。在代码底部的“try”循环中,我递归调用(try (func-eval guess)),其中(func-eval guess)使用公式 * x - alpha * f'(x)计算函数局部最小值的下一个猜测)* 其中alpha = 0.1。

我在计算衍生产品时似乎遇到了错误...我正在使用Dr.Racket IDE,它突出显示以下这一行是有问题的: (f (+ x dx)) ...这是我当地衍生程序的第二行:

(define (local-minimal first-guess)

;A way to check a guess
(define(good-enough? val1 val2)
(<(abs(- val1 val2)) 0.00001))

; x_new = x_old - alpha*f'(x)    /// f(x)=(x+1)^2+2  //// alpha = 0.1
(define (func-eval x)
  (- x (* 0.1((derivative (+ 2(expt (+ x 1) 2)) 0.00001)x))))

  (define (derivative f dx)
  (lambda (x)
    (/ (- (f (+ x dx)) (f x))
       dx)))

; trys the guess
(define (try guess)
  (if (good-enough? guess -1)
      guess
      (try (func-eval guess))))
(try first-guess)) 

我收到错误说:

application: not a procedure;
 expected a procedure that can be applied to arguments
  given: 3
  arguments...:
   -1.99999

这是语法错误吗?我以为我可以通过使用(f (+ x dx))来说f(x + dx)....这是否意味着我需要在这些括号中的f之前放置一个运算符?

2 个答案:

答案 0 :(得分:3)

突出显示和错误消息一起告诉你一些有用的东西:derivative正在接收的东西,因为它的第一个参数f不是一个函数,它需要在{{1}中调用}}。论证来自何处?我们可以运行DrRacket的调试器,但是在这里我们可以看看代码 - (f (+ x dx))被调用的唯一位置是derivative的第一行,所以我们必须传递一个数字而不是一个功能。果然,func-eval(绑定(+ 2 (expt (+ x 1) 2)))只是一个数字,尝试应用此错误会产生错误。

答案 1 :(得分:2)

调用derivative时,第一个参数必须是函数。在以下过程调用中,第一个参数中的表达式将计算为数字,而不是函数:

(derivative (+ 2 (expt (+ x 1) 2)) 0.00001)

要解决此问题,请将表达式打包在lambda内,这使其成为实际功能:

(derivative (lambda (x) (+ 2 (expt (+ x 1) 2))) 0.00001)