Another code sample - symbolic derivatives David A. Wheeler (09 Apr 2013 02:57 UTC)
|
Re: Another code sample - symbolic derivatives
Mark H Weaver
(09 Apr 2013 04:26 UTC)
|
Re: Another code sample - symbolic derivatives
David A. Wheeler
(09 Apr 2013 04:45 UTC)
|
Re: Another code sample - symbolic derivatives
Alan Manuel Gloria
(09 Apr 2013 13:17 UTC)
|
Another code sample - symbolic derivatives David A. Wheeler 09 Apr 2013 02:57 UTC
Here's a version of the "Wizard book" symbolic derivative calculation, using sweet-expressions. I've placed it below and put it in an attachment. Unsurprisingly, sweet-expression's ability to accept infix makes infix expressions nicer. E.G.: deriv '{{x * y} * {x + 3}} 'x My goal of working out examples like this is to see if there are any serious problems with the sweet-expression notation. I don't see any problems with the notation in this case. Granted, this has a bunch of especially short and simple definitions, but I don't see any sign of trouble. Comments? --- David A. Wheeler #!/usr/bin/env sweet-run ;#!guile -s ;!# ; Code to generate derivatives from the "Wizard Book" - ; Hal Abelson's, Jerry Sussman's and Julie Sussman's ; "Structure and Interpretation of Computer Programs" ; (MIT Press, 1984; ISBN 0-262-01077-1), ; http://mitpress.mit.edu/sicp/full-text/sicp/book/node39.html ; http://mitpress.mit.edu/sicp/code/index.html ;;; SECTION 2.3.2 define deriv(exp var) cond number?(exp) 0 variable?(exp) if same-variable?(exp var) 1 0 sum?(exp) make-sum deriv(addend(exp) var) deriv(augend(exp) var) product?(exp) make-sum make-product multiplier(exp) deriv(multiplicand(exp) var) make-product deriv(multiplier(exp) var) multiplicand(exp) else error("unknown expression type -- DERIV" exp) ;; representing algebraic expressions define variable?(x) symbol?(x) define same-variable?(v1 v2) {variable?(v1) and variable?(v2) and eq?(v1 v2)} define sum?(x) {pair?(x) and eq?(car(x) '+)} define addend(s) cadr(s) define augend(s) caddr(s) define product?(x) {pair?(x) and eq?(car(x) '*)} define multiplier(p) cadr(p) define multiplicand(p) caddr(p) ;; Simplification define make-sum(a1 a2) cond =number?(a1 0) a2 =number?(a2 0) a1 {number?(a1) and number?(a2)} {a1 + a2} else list('+ a1 a2) define =number?(exp num) {number?(exp) and {exp = num}} define make-product(m1 m2) cond {=number?(m1 0) or =number?(m2 0)} 0 =number?(m1 1) m2 =number?(m2 1) m1 {number?(m1) and number?(m2)} {m1 * m2} else list('* m1 m2) ; Here are routines to display result in infix form: define infix-operators '(+ *) define infix-tail(op x) cond null?(x) display "}" pair?(x) display " " write op display " " my-write car(x) infix-tail op cdr(x) #t error("Infix operator with improper list") define my-write(x) cond null?(x) display "()" pair?(x) if {memq(car(x) infix-operators) and pair?(cdr(x))} begin ; Display in infix order display "{" if not(null?(cdr(x))) my-write cadr(x) infix-tail car(x) cddr(x) write x #t write x ; Use demo - this should produce {{x * y} + {y * {x + 3}}} my-write deriv '{{x * y} * {x + 3}} 'x