Created
October 24, 2017 15:15
-
-
Save leesharma/250c3dfd18b5618fb7bf53ab7bbcde1d to your computer and use it in GitHub Desktop.
A working example of symbolic differentiation (SICP section 2.4).
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
;Symbolic Differentiation | |
; | |
; note: all arithmetic terms must have two operands! | |
; e.g. `(+ a b c) becomes `(+ a (+ b c))) | |
; | |
(define (deriv exp var) | |
(cond ((constant? exp var) 0) | |
((same-var? exp var) 1) | |
((sum? exp) | |
(make-sum (deriv (a1 exp) var) | |
(deriv (a2 exp) var))) | |
((product? exp) | |
(make-sum | |
(make-product (m1 exp) | |
(deriv (m2 exp) var)) | |
(make-product (deriv (m1 exp) var) | |
(m2 exp)))))) | |
(define (constant? exp var) | |
(and (atom? exp) | |
(not (eq? exp var)))) | |
(define (same-var? exp var) | |
(and (atom? exp) | |
(eq? exp var))) | |
(define (sum? exp) | |
(and (not (atom? exp)) | |
(eq? (car exp) '+))) | |
(define (make-sum a1 a2) | |
(cond ((and (number? a1) | |
(number? a2)) | |
(+ a1 a2)) | |
((and (number? a1) (= a1 0)) a2) | |
((and (number? a2) (= a2 0)) a1) | |
((eq? a1 a2) (list '* 2 a1)) | |
(else (list '+ a1 a2)))) | |
(define a1 cadr) | |
(define a2 caddr) | |
(define (product? exp) | |
(and (not (atom? exp)) | |
(eq? (car exp) '*))) | |
(define (make-product m1 m2) | |
(cond ((and (number? m1) (number? m2)) (* m1 m2)) | |
((and (number? m1) (= m1 1)) m2) | |
((and (number? m2) (= m2 1)) m1) | |
((and (number? m1) (= m1 0)) 0) | |
((and (number? m2) (= m2 0)) 0) | |
(else (list '* m1 m2)))) | |
(define m1 cadr) | |
(define m2 caddr) | |
(define (atom? x) | |
(not (list? x))) | |
;Example equation | |
(define foo | |
'(+ (* a (* x x)) | |
(+ (* b x) | |
c))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment