<commit_before>#lang racket

; Section 1.3.1: Procedures as Arguments

(require "common.rkt")

;   Exercise 1.29
;   =============
;   
;   Simpson's Rule is a more accurate method of numerical integration than
;   the method illustrated above.  Using Simpson's Rule, the integral of a
;   function f between a and b is approximated as
;   
;   h
;   ─ [y₀ + 4y₁ + 2y₂ + 4y₃ + 2y₄ + ... + 2y    + 4y    + y ]
;   3                                       ⁿ⁻²     ⁿ⁻¹    ⁿ
;   
;   where h = (b - a)/n, for some even integer n, and y_(k) = f(a + kh).
;   (Increasing n increases the accuracy of the approximation.) Define a
;   procedure that takes as arguments f, a, b, and n and returns the value
;   of the integral, computed using Simpson's Rule. Use your procedure to
;   integrate cube between 0 and 1 (with n = 100 and n = 1000), and compare
;   the results to those of the integral procedure shown above.
;   
;   ------------------------------------------------------------------------
;   [Exercise 1.29]: http://sicp-book.com/book-Z-H-12.html#%_thm_1.29
;   1.3.1 Procedures as Arguments - p60
;   ------------------------------------------------------------------------

(-start- "1.29")



(--end-- "1.29")

;   ========================================================================
;   
;   Exercise 1.30
;   =============
;   
;   The sum procedure above generates a linear recursion.  The procedure can
;   be rewritten so that the sum is performed iteratively. Show how to do
;   this by filling in the missing expressions in the following definition:
;   
;   (define (sum term a next b)
;     (define (iter a result)
;       (if <??>
;           <??>
;           (iter <??> <??>)))
;     (iter <??> <??>))<commit_msg>1.30 redux<commit_after>#lang racket

; Section 1.3.1: Procedures as Arguments

(require "common.rkt")

;   Exercise 1.29
;   =============
;   
;   Simpson's Rule is a more accurate method of numerical integration than
;   the method illustrated above.  Using Simpson's Rule, the integral of a
;   function f between a and b is approximated as
;   
;   h
;   ─ [y₀ + 4y₁ + 2y₂ + 4y₃ + 2y₄ + ... + 2y    + 4y    + y ]
;   3                                      ⁿ⁻²     ⁿ⁻¹    ⁿ
;   
;   where h = (b - a)/n, for some even integer n, and y_(k) = f(a + kh).
;   (Increasing n increases the accuracy of the approximation.) Define a
;   procedure that takes as arguments f, a, b, and n and returns the value
;   of the integral, computed using Simpson's Rule. Use your procedure to
;   integrate cube between 0 and 1 (with n = 100 and n = 1000), and compare
;   the results to those of the integral procedure shown above.
;   
;   ------------------------------------------------------------------------
;   [Exercise 1.29]: http://sicp-book.com/book-Z-H-12.html#%_thm_1.29
;   1.3.1 Procedures as Arguments - p60
;   ------------------------------------------------------------------------

(-start- "1.29")

(define (cube n)
  (* n n n))

(define (sum term a next b)
  (if (> a b)
      0
      (+ (term a) (sum term (next a) next b))))

(define (inc n)
  (+ n 1))

(define (simpson f a b n)
  (define h (/ (- b a) n))
  (define (y k) (f (+ a (* k h))))
  (define (term k)
    (cond
      ((= k 0) (y 0))
      ((= k n) (y n))
      ((even? k) (* 2 (y k)))
      (else (* 4 (y k)))))
  (* (/ h  3)
     (sum term 0 inc n)))

(present simpson
         (list cube 0 1. 2)
         (list cube 0 1. 100)
         (list cube 0 1. 1000) 
         (list cube 0 1. 100000))

(define (integral f a b dx)
  (define (add-dx x) (+ x dx))
  (* (sum f (+ a (/ dx 2.0)) add-dx b)
     dx))

(present integral
         (list cube 0 1. 0.5)
         (list cube 0 1. 0.01)
         (list cube 0 1. 0.001)
         (list cube 0 1. 0.00001))

(prn "As promised Simpson Rule is much more accurate for a given number of
iterations.  It looks like it would take 100,000,000 iterations for
Integral to be as accurate as Simpson is after 100 iterations.

Integral appears to be approaching the solution from below whereas we
see Simpson producse positive errors as well as negative errors.

This particular integration does seem to suite Simpsons well as it gives
an exactly correct answer after just 2 iterations.")

(--end-- "1.29")

;   ========================================================================
;   
;   Exercise 1.30
;   =============
;   
;   The sum procedure above generates a linear recursion.  The procedure can
;   be rewritten so that the sum is performed iteratively. Show how to do
;   this by filling in the missing expressions in the following definition:
;   
;   (define (sum term a next b)
;     (define (iter a result)
;       (if <??>
;           <??>
;           (iter <??> <??>)))
;     (iter <??> <??>))
{'fraction_non_alphanumeric': 0.21246578226995158, 'fraction_numerical': 0.033480732785849655, 'mean_word_length': 1.9393564356435644, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '664687', 'n_tokens_mistral': 1631, 'n_tokens_neox': 1454, 'n_words': 595}