Last active
December 11, 2015 21:39
-
-
Save mjg123/4663990 to your computer and use it in GitHub Desktop.
Lazy approach to approximating square roots in clojure using Newton-Raphson. For BrisFunctional.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
line 21 sidesteps the fact that Math/abs doesn't work for clojure's Rational (ie fractional) datatype. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Newton-Raphson is a method for finding the square-root of a number by starting with a guess | |
;; then producing a next (better) guess, and iterating that process. | |
(defn next-guess [target guess] | |
(/ (+ guess (/ target guess)) 2)) | |
;; Because iterate is produces a lazy seq, so this function does too | |
(defn approximations [target starting-guess] | |
(iterate | |
(partial next-guess target) | |
starting-guess)) | |
;; (approximations 64 1) | |
;; => (1 65/2 4481/260 24405761/2330120 943126559710721/113736703642640 ... | |
;; an infinite list of better-and-better approximations | |
;; We want to consume the sequence until two successive terms are close enough together | |
;; preferably without "holding onto the head" of the sequence. | |
;; helpfully calculates the absolute difference between 2 numbers | |
(defn adiff [a b] (if (< a b) (- b a) (- a b))) | |
(defn consume-until-sated [guess-seq epsilon] | |
(if (> epsilon (adiff (first guess-seq) (second guess-seq))) | |
(* 1.0 (second guess-seq)) | |
(recur (rest guess-seq) epsilon))) | |
;; this finds the first pair where the difference is less than epsilon and | |
;; returns the second value from that pair (as a decimal for convenience): | |
;; | |
;; (consume-until-sated (approximations 64 1) 1) | |
;; => 8.005147977880979 | |
;; | |
;; (actually 1717394123983378202652077194241/214536212038641785250721486880, the 6th approximation) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment