Что не так с этой реализацией метода Ньютона в схеме?

Где мой недостаток в следующем коде?

(define (newtons-method2 f guess n)
(define (newton-transform f)
 (lambda (x)
  (- x (/ (f x) ((der f 0.5) x)))))
(let ((next (newton-transform guess)))
(if (= 0 n)
    next
    (newtons-method2 (f next (- n 1))))))

Метод называется "newtons-method2", потому что это была моя вторая попытка написать метод Ньютона на схеме

Моя производная функция выглядит следующим образом:

(define (der f h)
 (lambda (x)
 (/ (- (f(+ x h)) (f x))
    h)))

person John Friedrich    schedule 19.09.2013    source источник
comment
codereview.stackexchange.com /вопросы/1396/   -  person Robert Harvey    schedule 20.09.2013
comment
Вы не сказали нам, почему вы считаете код неправильным. Какой результат вы получаете?   -  person Robert Harvey    schedule 20.09.2013
comment
Мой вывод - несоответствие редкости. Утверждение компилятора говорит, что ожидаемое количество аргументов равно 2, но метод newtons-2 ожидал 1, когда я вызываю функцию рекурсивно. Я также получаю странную строку с надписью #‹procedure:...SE1010-PS4-2.rkt:73:3› 99 Я написал две строки кода под приведенными выше, чтобы проверить свою функцию, и они выглядят следующим образом '( ньютонов-метод2 (лямбда (х) (+ (* 2 х) 1)) 1 100) (ньютонов-метод 2 (лямбда (х) (- (* хх) х 1)) 2 100)'   -  person John Friedrich    schedule 20.09.2013


Ответы (2)


Вероятно, есть несколько проблем, я нашел эти:

(newtons-method2 (f next (- n 1))
->
(f next (- n 1))

это оценка f с параметрами next и n-1, но вы хотите передать все 3 в качестве параметров:

(newtons-method2 f next (- n 1))

Будьте осторожны со скобками, они коренным образом меняют то, что делает программа. То, что они сбалансированы, не означает, что программа делает что-то значимое.

0,5 для дельты — огромное значение, и, скорее всего, это вызовет проблемы при вычислении приближений. как насчет 0.00001?

Научитесь делать правильные отступы, чтобы аргументы располагались друг под другом. Опять же, это связано со скобками. Ваш код почти невозможно прочитать.

Кроме того, вот хорошая реализация с пояснениями из лекций SICP (настоятельно рекомендуется, блестяще): http://www.youtube.com/watch?v=erHp3r6PbJk&list=PL8FE88AA54363BC46 (с 43:14)

person Karoly Horvath    schedule 19.09.2013
comment
Есть идеи, почему я получаю #‹procedure:...untitled:73:3› при компиляции? Что означает эта компиляция? - person John Friedrich; 20.09.2013

Вы не спрашивали об этом, но вот альтернативный метод вычисления квадратного корня:

(define (root n)
  (if (< n 1) (/ (root (* n 4)) 2)
    (if (<= 4 n) (* (root (/ n 4)) 2)
      (let ((x (/ (+ 2. n) 2)))
        (let ((x (/ (+ x (/ n x)) 2)))
          (let ((x (/ (+ x (/ n x)) 2)))
            (let ((x (/ (+ x (/ n x)) 2)))
              (let ((x (/ (+ x (/ n x)) 2)))
                (let ((x (/ (+ x (/ n x)) 2)))
                  x)))))))))

Это нормализует n до диапазона 1 ‹= n ‹ 4, затем разворачивает цикл и выполняет пять итераций с начальной оценкой 2, которая является средним геометрическим диапазоном; можно доказать, что пяти итераций достаточно для арифметики с двойной точностью, поскольку известно, что n находится в ограниченном диапазоне. Используемая формула принадлежит Герону, который предшествует методу Ньютона на 16 веков.

person user448810    schedule 20.09.2013