2

私はSchemeの初心者で、確率的勾配降下法を実装する課題に取り組んでいます。これまでのところ、プログラムの構造は正しいと思いますが、関数 f(x) の導関数を取る手順が問題を引き起こしています。コードの最後にある "try" ループで、再帰的(try (func-eval guess))に whereを呼び出して、式*x - alpha*f'(x)* ( alpha = 0.1 )(func-eval guess)を使用して、関数のローカル最小値の次の推測を計算します。

導関数の計算中にエラーが発生したようです... Dr.Racket IDE を使用していますが、次の行が問題として強調表示されています: (f (+ x dx))... これは私のローカル導関数手順の 2 行目です:

(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 の前に演算子を入れる必要があるということですか?

4

2 に答える 2

3

強調表示とエラーメッセージが一緒になって、何か便利なことを伝えています。derivative最初の引数fが関数ではないために受信しているものであり、で呼び出す必要があります(f (+ x dx))。議論はどこから来るのですか?DrRacketのデバッガーを実行することもできますが、ここではコードを見ることができます。derivative呼び出し元はの最初の行だけなfunc-evalので、関数ではなく数値を渡したはずです。案の定、(+ 2 (expt (+ x 1) 2))xバインドされた)は単なる数値であり、これを適用しようとするとエラーが発生します。

于 2012-11-08T07:30:18.563 に答える
2

を呼び出すときderivative、最初の引数は関数でなければなりません。次のプロシージャ コールでは、最初の引数の式が関数ではなく数値に評価されます。

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

これを修正するには、式を 内にパックしlambdaて、実際の関数にします。

(derivative (lambda (x) (+ 2 (expt (+ x 1) 2))) 0.00001)
于 2012-11-08T14:09:52.010 に答える