From 6fb1e034aaa29b683b37e2f8d6fc2c715f6e10b0 Mon Sep 17 00:00:00 2001 From: CJ Date: Sun, 7 Jul 2024 18:52:24 +0900 Subject: [PATCH] Finish 1.3.3 --- .vscode/tasks.json | 3 + README.md | 185 ++++++++++++++---- chapter-1/1.3/1.35.scm | 4 +- chapter-1/1.3/1.36.scm | 20 +- chapter-1/1.3/1.37.scm | 3 +- chapter-1/1.3/1.38.scm | 3 +- chapter-1/1.3/1.39.scm | 8 +- .../1.3/{cont-frac.scm => cont-frac.lib.scm} | 0 chapter-1/1.3/fixed-point.lib.scm | 10 + chapter-1/1.3/fixed-point.scm | 25 ++- chapter-1/1.3/half-interval.scm | 1 + chapter-1/1.3/test-fixed-point.scm | 15 -- 12 files changed, 196 insertions(+), 81 deletions(-) rename chapter-1/1.3/{cont-frac.scm => cont-frac.lib.scm} (100%) create mode 100644 chapter-1/1.3/fixed-point.lib.scm delete mode 100644 chapter-1/1.3/test-fixed-point.scm diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 34b0273..91776bd 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -9,6 +9,9 @@ "kind": "build", "isDefault": true }, + "options": { + "cwd": "${fileDirname}" + }, "presentation": { "echo": true, "reveal": "always", diff --git a/README.md b/README.md index 2c18e1e..552b2fd 100644 --- a/README.md +++ b/README.md @@ -14,46 +14,54 @@ Useful links: TOC: -- [Review of Structure and Interpretation of Computer Programs](#review-of-structure-and-interpretation-of-computer-programs) - - [Setup](#setup) - - [Sublime Text](#sublime-text) - - [VS Code](#vs-code) - - [Chrome](#chrome) - - [Chapter 1: Building Abstractions with Procedures](#chapter-1-building-abstractions-with-procedures) - - [1.1: The Elements of Programming](#11-the-elements-of-programming) - - [1.2: Procedures and the Processes They Generate](#12-procedures-and-the-processes-they-generate) - - [1.3: Formulating Abstractions with Higher-Order Procedures](#13-formulating-abstractions-with-higher-order-procedures) - - [Exercise](#exercise) - - [1.1](#11) - - [1.2](#12) - - [1.3](#13) - - [1.4](#14) - - [1.5](#15) - - [1.6](#16) - - [1.7](#17) - - [1.8](#18) - - [1.9](#19) - - [1.10](#110) - - [1.11](#111) - - [1.12](#112) - - [1.13](#113) - - [1.14](#114) - - [1.15](#115) - - [1.16](#116) - - [1.17](#117) - - [1.18](#118) - - [1.19](#119) - - [1.20](#120) - - [1.21](#121) - - [1.22](#122) - - [1.23](#123) - - [1.24](#124) - - [1.25](#125) - - [1.26](#126) - - [1.27](#127) - - [1.28](#128) - - [1.29](#129) - - [1.30](#130) +- [Setup](#setup) + - [Sublime Text](#sublime-text) + - [VS Code](#vs-code) + - [Chrome](#chrome) +- [Chapter 1: Building Abstractions with Procedures](#chapter-1-building-abstractions-with-procedures) + - [1.1: The Elements of Programming](#11-the-elements-of-programming) + - [1.2: Procedures and the Processes They Generate](#12-procedures-and-the-processes-they-generate) + - [1.3: Formulating Abstractions with Higher-Order Procedures](#13-formulating-abstractions-with-higher-order-procedures) +- [Exercise](#exercise) + - [1.1](#11) + - [1.2](#12) + - [1.3](#13) + - [1.4](#14) + - [1.5](#15) + - [1.6](#16) + - [1.7](#17) + - [1.8](#18) + - [1.9](#19) + - [1.10](#110) + - [1.11](#111) + - [1.12](#112) + - [1.13](#113) + - [1.14](#114) + - [1.15](#115) + - [1.16](#116) + - [1.17](#117) + - [1.18](#118) + - [1.19](#119) + - [1.20](#120) + - [1.21](#121) + - [1.22](#122) + - [1.23](#123) + - [1.24](#124) + - [1.25](#125) + - [1.26](#126) + - [1.27](#127) + - [1.28](#128) + - [1.29](#129) + - [1.30](#130) + - [1.31](#131) + - [1.32](#132) + - [1.33](#133) + - [1.34](#134) + - [1.35](#135) + - [1.36](#136) + - [1.37](#137) + - [1.38](#138) + - [1.39](#139) ## Setup @@ -108,6 +116,9 @@ exit $code "kind": "build", "isDefault": true }, + "options": { + "cwd": "${fileDirname}" + }, "presentation": { "echo": true, "reveal": "always", @@ -279,6 +290,19 @@ Install [Markdown Viewer](https://chromewebstore.google.com/detail/markdown-view - Procedures that manipulate procedures are called **higher-order procedures**. - Procedures as Arguments - We can write a general [sum](./chapter-1/1.3/sum.scm) to express the concept of summation itself rather than particular sums. + - `sum` and `product` are both special cases of a still more general notion called `accumulate` +- Constructing Procedures Using `Lambda` + - In general, `lambda` is used to create procedures in the same way as `define`, except that no name is specified for the procedure + - A `let` expression is simply syntactic sugar for the underlying lambda application +- Procedures as General Methods + - [Half-interval method](./chapter-1/1.3/half-interval.scm) + - > The half-interval method is a simple but powerful technique for finding roots of an equation `f(x) = 0`, where f is a continuous function. + > --- page67 + - [Fixed points](./chapter-1/1.3/fixed-point.scm) + - > A number x is called a *fixed point* of a function f if x satisfies the equation f(x) = x. For some functions f we can locate a fixed point by beginning with an initial guess and applying f repeatedly. + > --- page68 + - Finded square root y of number x equals to finding a fixed point of the function `y = x/y` + - But the naive search does not converge, we need to use a technique called **average damping** to transform the function to be `y = 1/2(y + x/y)`, and this is the Newton's method. ## Exercise @@ -702,3 +726,84 @@ We can see that Carmichael numbers which fool the Fermat test now can be correct ### 1.33 [1.33.scm](./chapter-1/1.3/1.33.scm). + +### 1.34 + +We will get an error: *The object 2 is not applicable*. + +```scheme +(f f) +-> (f 2) +-> (2 2) +; 2 is not a procedure. +``` + +### 1.35 + +[1.35.scm](./chapter-1/1.3/1.35.scm). + +### 1.36 + +[1.36.scm](./chapter-1/1.3/1.36.scm). + +We can clearly see that *average damping* can significantly reduce required steps to find the fixed point. + +``` bash +=== normal approach === +-> 2.#1 +-> 9.965784284662087#2 +-> 3.004472209841214#3 +-> 6.279195757507157#4 +-> 3.759850702401539#5 +-> 5.215843784925895#6 +-> 4.182207192401397#7 +-> 4.8277650983445906#8 +-> 4.387593384662677#9 +-> 4.671250085763899#10 +-> 4.481403616895052#11 +-> 4.6053657460929#12 +-> 4.5230849678718865#13 +-> 4.577114682047341#14 +-> 4.541382480151454#15 +-> 4.564903245230833#16 +-> 4.549372679303342#17 +-> 4.559606491913287#18 +-> 4.552853875788271#19 +-> 4.557305529748263#20 +-> 4.554369064436181#21 +-> 4.556305311532999#22 +-> 4.555028263573554#23 +-> 4.555870396702851#24 +-> 4.555315001192079#25 +-> 4.5556812635433275#26 +-> 4.555439715736846#27 +-> 4.555599009998291#28 +-> 4.555493957531389#29 +-> 4.555563237292884#30 +-> 4.555517548417651#31 +-> 4.555547679306398#32 +-> 4.555527808516254#33 +-> 4.555540912917957#34 +=== average damping === +-> 2.#1 +-> 5.9828921423310435#2 +-> 4.922168721308343#3 +-> 4.628224318195455#4 +-> 4.568346513136242#5 +-> 4.5577305909237005#6 +-> 4.555909809045131#7 +-> 4.555599411610624#8 +-> 4.5555465521473675#9 +``` + +### 1.37 + +[1.37.scm](./chapter-1/1.3/1.37.scm). + +### 1.38 + +[1.38.scm](./chapter-1/1.3/1.38.scm). + +### 1.39 + +[1.39.scm](./chapter-1/1.3/1.39.scm). diff --git a/chapter-1/1.3/1.35.scm b/chapter-1/1.3/1.35.scm index 4d649e4..aaeca70 100644 --- a/chapter-1/1.3/1.35.scm +++ b/chapter-1/1.3/1.35.scm @@ -1,5 +1,3 @@ -(define tolerance 0.00001) - -(load "fixed-point.scm") +(load "fixed-point.lib.scm") (display (fixed-point (lambda (x) (+ 1 (/ 1 x))) 1.0)) diff --git a/chapter-1/1.3/1.36.scm b/chapter-1/1.3/1.36.scm index 4284535..1730c90 100644 --- a/chapter-1/1.3/1.36.scm +++ b/chapter-1/1.3/1.36.scm @@ -1,24 +1,28 @@ -(define tolerance 0.00001) - (define (fixed-point f first-guess) + (define tolerance 0.00001) (define (close-enough? x y) (< (abs (- x y)) tolerance)) - (define (try guess) + (define (try steps guess) (display "-> ") (display guess) + (display "#") + (display steps) (newline) (let ((next (f guess))) (if (close-enough? guess next) guess - (try next)))) - (try first-guess)) + (try (+ steps 1) next)))) + (try 1 first-guess)) (define (average x y) (/ (+ x y) 2)) -; Noraml approach -(fixed-point (lambda (x) (/ (log 1000) (log x))) 2.0) +; noraml approach +(display "=== normal approach ===") (newline) +(fixed-point (lambda (x) (/ (log 1000) (log x))) 2.0) -; Using average damping +; use average damping +(display "=== average damping ===") +(newline) (fixed-point (lambda (x) (average x (/ (log 1000) (log x)))) 2.0) diff --git a/chapter-1/1.3/1.37.scm b/chapter-1/1.3/1.37.scm index 3b576b8..63e8357 100644 --- a/chapter-1/1.3/1.37.scm +++ b/chapter-1/1.3/1.37.scm @@ -1,13 +1,12 @@ ; φ = 1.618033 ; 1/φ = 0.618033 -(load "cont-frac.scm") +(load "cont-frac.lib.scm") ;; k = 11 is enough to be accurate to 4 decimal places (display "recursive:\n") (display (cont-frac-recursive (lambda (i) 1.0) (lambda (i) 1.0) 11)) - (newline) (display "iterative:\n") diff --git a/chapter-1/1.3/1.38.scm b/chapter-1/1.3/1.38.scm index 0f237da..b4fbd2f 100644 --- a/chapter-1/1.3/1.38.scm +++ b/chapter-1/1.3/1.38.scm @@ -1,4 +1,4 @@ -(load "cont-frac.scm") +(load "cont-frac.lib.scm") (define (d i) (cond @@ -7,4 +7,5 @@ ((= 0 (remainder (- i 2) 3)) (* 2 (/ (+ i 1) 3))) (else 1))) +; 2.718281828459045 (display (+ 2 (cont-frac-iterative (lambda (i) 1.0) d 20))) diff --git a/chapter-1/1.3/1.39.scm b/chapter-1/1.3/1.39.scm index 717ee7a..cd0588b 100644 --- a/chapter-1/1.3/1.39.scm +++ b/chapter-1/1.3/1.39.scm @@ -1,4 +1,4 @@ -(load "cont-frac.scm") +(load "cont-frac.lib.scm") (define (tan-cf x k) (define (n i) @@ -7,5 +7,9 @@ (- (* i 2) 1.0)) (cont-frac-iterative n d k)) -; tan(10) = 0.64836 +(display "correct answer: ") +(display (/ (sin 10) (cos 10))) +(newline) + +(display "our approximation: ") (display (tan-cf 10 20)) diff --git a/chapter-1/1.3/cont-frac.scm b/chapter-1/1.3/cont-frac.lib.scm similarity index 100% rename from chapter-1/1.3/cont-frac.scm rename to chapter-1/1.3/cont-frac.lib.scm diff --git a/chapter-1/1.3/fixed-point.lib.scm b/chapter-1/1.3/fixed-point.lib.scm new file mode 100644 index 0000000..73eae06 --- /dev/null +++ b/chapter-1/1.3/fixed-point.lib.scm @@ -0,0 +1,10 @@ +(define (fixed-point f first-guess) + (define tolerance 0.00001) + (define (close-enough? x y) + (< (abs (- x y)) tolerance)) + (define (try guess) + (let ((next (f guess))) + (if (close-enough? guess next) + guess + (try next)))) + (try first-guess)) diff --git a/chapter-1/1.3/fixed-point.scm b/chapter-1/1.3/fixed-point.scm index 0a914df..1bd6bc0 100644 --- a/chapter-1/1.3/fixed-point.scm +++ b/chapter-1/1.3/fixed-point.scm @@ -1,11 +1,16 @@ -(define tolerance 0.00001) +(load "fixed-point.lib.scm") -(define (fixed-point f first-guess) - (define (close-enough? x y) - (< (abs (- x y)) tolerance)) - (define (try guess) - (let ((next (f guess))) - (if (close-enough? guess next) - guess - (try next)))) - (try first-guess)) +; y = cos(y) +; 0.739089 +(display (fixed-point cos 1.0)) +(newline) + +; y = sin(y) + cos(y) +; 1.258722 +(display (fixed-point (lambda (y) (+ (sin y) (cos y))) 1.0)) + +; calculate square root, y = x/y -> y = 1/2(y + x/y) +(define (square-root x) + (fixed-point (lambda (y) (/ (+ y (/ x y)) 2)) + 1.0)) +(display (square-root 38)) diff --git a/chapter-1/1.3/half-interval.scm b/chapter-1/1.3/half-interval.scm index e4b8b9e..59b400c 100644 --- a/chapter-1/1.3/half-interval.scm +++ b/chapter-1/1.3/half-interval.scm @@ -23,4 +23,5 @@ (display (half-interval sin 2.0 4.0)) (newline) +; x^3 - 2x -3 = 0 (display (half-interval (lambda (x) (- (* x x x) (* 2 x) 3)) 1.0 2.0)) diff --git a/chapter-1/1.3/test-fixed-point.scm b/chapter-1/1.3/test-fixed-point.scm deleted file mode 100644 index ac96399..0000000 --- a/chapter-1/1.3/test-fixed-point.scm +++ /dev/null @@ -1,15 +0,0 @@ -(load "fixed-point.scm") - -; Find fixed-point of cos -(display (fixed-point cos 1.0)) -(newline) - -; Find a solution to the equation y = siny + cosy -(display (fixed-point (lambda (y) (+ (sin y) (cos y))) 1.0)) -(newline) - -; Use fixed-point to calculate square root -(define (square-root x) - (fixed-point (lambda (y) (/ (+ y (/ x y)) 2)) - 1.0)) -(display (square-root 38))