Advertisement
timothy235

sicp-2-3-2-symbolic-differentiation

Feb 24th, 2016
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 7.27 KB | None | 0 0
  1. #lang racket
  2.  
  3. (define (deriv expr var)
  4.   (cond [(number? expr) 0]
  5.         [(variable? expr)
  6.          (if (same-variable? expr var) 1 0)]
  7.         [(sum? expr)
  8.          (make-sum (deriv (addend expr) var)
  9.                    (deriv (augend expr) var))]
  10.         [(product? expr)
  11.          (make-sum (make-product (multiplier expr)
  12.                                  (deriv (multiplicand expr) var))
  13.                    (make-product (deriv (multiplier expr) var)
  14.                                  (multiplicand expr)))]
  15.         [(exponentiation? expr)
  16.          (make-product (exponent expr)
  17.                        (make-product (make-exponentiation (base expr)
  18.                                                           (sub1 (exponent expr)))
  19.                                      (deriv (base expr) var)))]
  20.         [else (error "unknown expression type -- DERIV" expr)]))
  21.  
  22. (define (variable? x) (symbol? x))
  23. (define (same-variable? v1 v2)
  24.   (and (variable? v1) (variable? v2) (eq? v1 v2)))
  25.  
  26. (define (=number? expr num)
  27.   (and (number? expr) (= expr num)))
  28.  
  29. ;; This file contains four different representations for sums and products.  The
  30. ;; original one below, another in 2.57, and two more in 2.58.  Only one can be
  31. ;; commented out at a time in order for the file to load and for deriv to work.
  32.  
  33. ;; (define (sum? x) (and (list? x) (eq? (first x) '+)))
  34. ;; (define (addend s) (second s))
  35. ;; (define (augend s) (third s))
  36.  
  37. ;; (define (make-sum a1 a2)
  38.   ;; (cond [(=number? a1 0) a2]
  39.         ;; [(=number? a2 0) a1]
  40.         ;; [(and (number? a1) (number? a2)) (+ a1 a2)]
  41.         ;; [else (list '+ a1 a2)]))
  42.  
  43. ;; (define (product? x) (and (list? x) (eq? (first x) '*)))
  44. ;; (define (multiplier p) (second p))
  45. ;; (define (multiplicand p) (third p))
  46.  
  47. ;; (define (make-product m1 m2)
  48.   ;; (cond [(or (=number? m1 0) (=number? m2 0)) 0]
  49.         ;; [(=number? m1 1) m2]
  50.         ;; [(=number? m2 1) m1]
  51.         ;; [(and (number? m1) (number? m2)) (* m1 m2)]
  52.         ;; [else (list '* m1 m2)]))
  53.  
  54. ;;;;;;;;;;
  55. ;; 2.56 ;;
  56. ;;;;;;;;;;
  57.  
  58. ;; Define a constructor and selectors for exponentiation and add an exponentiation
  59. ;; rule to the deriv procedure above.
  60.  
  61. (define (exponentiation? x) (and (list? x) (eq? (first x) '**)))
  62. (define (base e) (second e))
  63. (define (exponent e) (third e))
  64.  
  65. (define (make-exponentiation b p)
  66.   (cond [(=number? p 0) 1]
  67.         [(=number? p 1) b]
  68.         [else (list '** b p)]))
  69.  
  70. (deriv (make-exponentiation (list '* 'x 'y) 2) 'x)
  71. ;; '(* 2 (* (* x y) y))
  72.  
  73. ;;;;;;;;;;
  74. ;; 2.57 ;;
  75. ;;;;;;;;;;
  76.  
  77. ;; Define new constructors and selectors for sums and products that can take more
  78. ;; than one term.
  79.  
  80. (define (sum? x) (and (list? x) (eq? (first x) '+)))
  81. (define (addend s) (second s))
  82. (define (augend s)
  83.   (define rst (rest (rest s)))
  84.   (if (= (length  rst) 1)
  85.     (first rst)
  86.     (apply make-sum rst)))
  87.  
  88. (define (make-sum a1 a2 . more)
  89.   (define summands (append (list a1 a2) more))
  90.   (define numbers (filter number? summands))
  91.   (define not-numbers (filter-not number? summands))
  92.   (define sum-numbers (apply + numbers))
  93.   (cond [(empty? not-numbers) sum-numbers]
  94.         [(= (length not-numbers) 1)
  95.          (define not-number (first not-numbers))
  96.          (if (zero? sum-numbers)
  97.            not-number
  98.            (list '+ sum-numbers not-number))]
  99.         [else
  100.           (if (zero? sum-numbers)
  101.             (cons '+ not-numbers)
  102.             (append (list '+ sum-numbers) not-numbers))]))
  103.  
  104. (define (product? x) (and (list? x) (eq? (first x) '*)))
  105. (define (multiplier p) (second p))
  106. (define (multiplicand p)
  107.   (define rst (rest (rest p)))
  108.   (if (= (length rst) 1)
  109.     (first rst)
  110.     (apply make-product rst)))
  111.  
  112. (define (make-product m1 m2 . more)
  113.   (define factors (append (list m1 m2) more))
  114.   (define numbers (filter number? factors))
  115.   (define not-numbers (filter-not number? factors))
  116.   (define product-numbers (apply * numbers))
  117.   (cond [(empty? not-numbers) product-numbers]
  118.         [(zero? product-numbers) 0]
  119.         [(= (length not-numbers) 1)
  120.          (define not-number (first not-numbers))
  121.          (if (= product-numbers 1)
  122.            not-number
  123.            (list '* product-numbers not-number))]
  124.         [else
  125.           (if (= product-numbers 1)
  126.             (cons '* not-numbers)
  127.             (append (list '* product-numbers) not-numbers))]))
  128.  
  129. (deriv '(* x y (+ x 3)) 'x)
  130. ;; '(+ (* x y) (* y (+ x 3)))
  131.  
  132. (deriv '(+ x y (** z 2)) 'z)
  133. ;; '(* 2 z)
  134.  
  135. (deriv '(** (+ x y 3) 2) 'y)
  136. ;; '(* 2 (+ x y 3))
  137.  
  138. (deriv '(* (+ x y 3) 2) 'y)
  139. ;; 2
  140.  
  141. ;;;;;;;;;;
  142. ;; 2.58 ;;
  143. ;;;;;;;;;;
  144.  
  145. ;; a.  Define new constructors and selectors for sums and products that use infix
  146. ;; notation, take exactly two terms, and are fully parenthesized.
  147.  
  148. ;; (define (sum? x)
  149.   ;; (and (list? x)
  150.        ;; (= (length x) 3)
  151.        ;; (eq? (second x) '+)))
  152. ;; (define (addend s) (first s))
  153. ;; (define (augend s) (third s))
  154.  
  155. ;; (define (make-sum a1 a2)
  156.   ;; (cond [(=number? a1 0) a2]
  157.         ;; [(=number? a2 0) a1]
  158.         ;; [(and (number? a1) (number? a2)) (+ a1 a2)]
  159.         ;; [else (list a1 '+ a2)]))
  160.  
  161. ;; (define (product? x)
  162.   ;; (and (list? x)
  163.        ;; (= (length x) 3)
  164.        ;; (eq? (second x) '*)))
  165. ;; (define (multiplier p) (first p))
  166. ;; (define (multiplicand p) (third p))
  167.  
  168. ;; (define (make-product m1 m2)
  169.   ;; (cond [(or (=number? m1 0) (=number? m2 0)) 0]
  170.         ;; [(=number? m1 1) m2]
  171.         ;; [(=number? m2 1) m1]
  172.         ;; [(and (number? m1) (number? m2)) (* m1 m2)]
  173.         ;; [else (list m1 '* m2)]))
  174.  
  175. ;; (deriv '(x + (3 * (x + (y + 2)))) 'y)
  176. ;; ;; 3
  177.  
  178. ;; (deriv '(x * (y + (2 * z))) 'x)
  179. ;; ;; '(y + (2 * z))
  180.  
  181. ;; (deriv '(x * (y + (2 * z))) 'y)
  182. ;; ;; 'x
  183.  
  184. ;; (deriv '(x * (y + (2 * z))) 'z)
  185. ;; ;; '(x * 2)
  186.  
  187. ;; b.  Define new constructors and selectors for sums and products that use infix
  188. ;; notation, can take more than two terms, and may not be fully parenthesized.
  189.  
  190. ;; (define (not-plus? x)
  191.   ;; (not (equal? x '+)))
  192. ;; (define (sum? x)
  193.   ;; (and (list? x) (member '+ x) (not-plus? (last x))))
  194. ;; (define (addend s)
  195.   ;; (define a1 (takef s not-plus?))
  196.   ;; (if (= (length a1) 1) (first a1) a1))
  197. ;; (define (augend s)
  198.   ;; (define a2 (rest (dropf s not-plus?)))
  199.   ;; (if (= (length a2) 1) (first a2) a2))
  200.  
  201. ;; (define (make-sum a1 a2)
  202.   ;; (cond [(=number? a1 0) a2]
  203.         ;; [(=number? a2 0) a1]
  204.         ;; [(and (number? a1) (number? a2)) (+ a1 a2)]
  205.         ;; [else (list a1 '+ a2)]))
  206.  
  207. ;; (define (not-times? x)
  208.   ;; (not (equal? x '*)))
  209. ;; (define (product? x)
  210.   ;; (and (list? x)
  211.        ;; (not (member '+ x)) ; multiplication binds tighter than addition
  212.        ;; (member '* x)
  213.        ;; (not-times? (last x))))
  214. ;; (define (multiplier p)
  215.   ;; (define m1 (takef p not-times?))
  216.   ;; (if (= (length m1) 1) (first m1) m1))
  217. ;; (define (multiplicand p)
  218.   ;; (define m2 (rest (dropf p not-times?)))
  219.   ;; (if (= (length m2) 1) (first m2) m2))
  220.  
  221. ;; (define (make-product m1 m2)
  222.   ;; (cond [(or (=number? m1 0) (=number? m2 0)) 0]
  223.         ;; [(=number? m1 1) m2]
  224.         ;; [(=number? m2 1) m1]
  225.         ;; [(and (number? m1) (number? m2)) (* m1 m2)]
  226.         ;; [else (list m1 '* m2)]))
  227.  
  228. ;; (deriv '(x + 3 * (x + y + 2)) 'x)
  229. ;; ;; 4
  230.  
  231. ;; (deriv '(x + 3 * (x + y + 2)) 'y)
  232. ;; ;; 3
  233.  
  234. ;; (deriv '(x * (y + 2 * z)) 'x)
  235. ;; ;; '(y + 2 * z)
  236.  
  237. ;; (deriv '(x * (y + 2 * z)) 'y)
  238. ;; ;; 'x
  239.  
  240. ;; (deriv '(x * (y + 2 * z)) 'z)
  241. ;; ;; '(x * 2)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement