Число x называется неподвижной точкой (fixed point
) функции f, если оно удовлетворяет равенству:
f(x)=x
В sicp предлагается следующий алгоритм решения данной задачи. Для некоторой функций f можно найти неподвижную точку, многократно вычисляя f(от предыдущего значения функции) до тех пор, пока изменение значения превышает условную пороговую величину(заданную точность):
f(x),f(f(x)),f(f(f (x))),...
Используя эту идею, напишем процедуру двух аргументов - функции и начального значения:
(defn fixed-point [f guess] (defn close-enough? [v1 v2] (< (abs (- v1 v2)) 0.00001)) (let [next (f guess)] (if (close-enough? guess next) next (recur f next))))
Для примера вычислим приближенное значение неподвижной точки функции косинуса:
(ns sicp.clojure.topic-1-3-4 (:use [clojure.contrib.generic.math-functions :only [cos]])) ... (fixed-point cos 1.0) ; -> 0.7390822985224024
Как можно заметить, данный способ имеет ряд недостатков. Если попытаться вычислить значение для функции kx+b
, например, вот так:
=> (fixed-point (fn[x] (+ 0.5 (* 2 x))) 1)
То интерпретатор уходит в глубокое раздумье. Я подвожу к тому, что неплохо бы подумать об альтернативном способе. В прошлый раз мы решали задачу нахождения корней уравнения. Допустим у нас есть некая процедура half-interval-method
трех аргументов - функция и границы интервала, умеющая находить корни уравнения вида f(x)=0. Тогда для нахождения неподвижной точки нужно решить:
f(x)-x=0
Выглядеть это будет так(код
(defn fixed-point [f x1 x2] (half-interval-method (fn[x] (- (f x) x)) x1 x2))
Ну и на последок:
(fixed-point cos 0.0 1.0) 0.7390899658203125 ... (fixed-point (fn[x] (+ 0.5 (* 2 x))) -3 3) -0.5000152587890625
No comments:
Post a Comment