home *** CD-ROM | disk | FTP | other *** search
- ; DIFF.L FOR PC-LISP V2.13
- ; ~~~~~~~~~~~~~~~~~~~~~~~~
- ; This module is kind of fun, it takes an expression in a prefix lisp
- ; like form and will compute the derivative of the expression with respect
- ; to the indicated variable. After symbolic differentiation is done some
- ; folding is done to remove redundant stuff from the expression. Eg we get
- ; rid of things multiplied by zero, and fold things with 0 added to them,
- ; or things raised to the power 1. This reduces the output complexity
- ; significantly.
- ;
- ; Peter Ashwood-Smith
- ; September 1986.
- ;
- ; D(e,X) -
- ; Will compute the symbolic derivative of expression e with respect
- ; to varible X. We take the expression in standard lisp prefix form and will
- ; use the following rules of differentiation.
- ;
- ; D(x) = 1
- ; D(a) = 0
- ; D(ln u) = D(u)/u
- ; D(u+v) = D(u)+D(v)
- ; D(u-v) = D(u)-D(v)
- ; D(u*v) = D(u)*v + u*D(v)
- ; D(u/v) = D(u)*v + (u*D(v))/v^2
- ; D(v^u) = (v^u)*(u*D(v)/v + D(u)*ln(v))
- ;
- (defun D(e X &aux u v)
- (cond ((equal e X) 1)
- ((atom e) 0)
- (t (setq u (cadr e) v (caddr e))
- (caseq (car e)
- (ln `(/ ,(D u X) ,u))
- (+ `(+ ,(D u X) ,(D v X)))
- (- `(- ,(D u X) ,(D v X)))
- (* `(+ (* ,(D u X) ,v) (* ,(D v X) ,u)))
- (/ `(- (/ ,(D u X) ,v)
- (/ (* ,u ,(D v X)) (^ ,v 2))))
- (^ `(* ,e (+ (/ (* ,v ,(D u X)) ,u)
- (* ,(D v X) (ln ,u)))))
- (t (princ "ERROR") (exit)]
-
- ;
- ; Fold(e) -
- ; Will traverse the expression 'e' and construct a new expression.
- ; It checks for things like (* 1 <exp>), (* <exp> 0), (^ <exp> 1), (+ <exp> 0)
- ; and replaces them with the appropriate things <exp>,0,<exp> and <exp>
- ; respectively. These simple algabraic modifications greatly reduce the output
- ; complexity but do not do a complete job by any means. We use the macros
- ; ?times, ?plus and ?power to do the dirty work for us. We set displace-macros
- ; to t to cause PC-LISP to substitute the code into the body of Fold thus
- ; making it much faster.
- ;
-
- (setq displace-macros t)
-
- (defmacro ?times(v e)
- `(and (eq (car ,e) '*) (member ,v ,e]
-
- (defmacro ?plus(v e)
- `(and (eq (car ,e) '+) (member ,v ,e]
- (defmacro ?power(v e)
- `(and (eq (car ,e) '^) (eq (caddr ,e) ,v]
-
- (defun Fold(e)
- (cond ((atom e) e)
- (t (setq e (cons (Fold (car e)) (Fold (cdr e))))
- (cond ((?times 0 e) 0)
- ((?times 1 e) (cond ((eq (cadr e) 1) (caddr e))
- (t (cadr e))))
- ((?power 1 e) (cadr e))
- ((?plus 0 e) (cond ((eq (cadr e) 0) (caddr e))
- (t (cadr e))))
- (t e]
-
- (defun Differentiate(e x)
- (Fold (D e x)]
-
- ; ----------------- end if differentiate module ------------------
-
-
- (princ "\t\tSYMBOLIC DIFFERENCIATION\n\n")
- (princ "Following is the Input Expression Y\n")
- (setq y '(* x (ln (+ x a))))
- (pp-form y)
-
- (princ "\nComputing 1st Derivitive of Y with respect to x, Y'\n")
- (setq Dy (Differentiate y 'x))
- (pp-form Dy)
-
- (princ "\nComputing 2nd Derivitive of Y with respect to x, Y''\n")
- (setq DDy (Differentiate Dy 'x))
- (pp-form DDy)
-
- (princ "\nComputing 3rd Derivitive of Y with respect to x, Y'''\n")
- (setq DDDy (Differentiate DDy 'x))
- (pp-form DDDy)
-
- (princ "\nComputing 4th Derivitive of Y with respect to x, Y''''\n")
- (setq DDDDy (Differentiate DDDy 'x))
- (pp-form DDDDy)
-
- (princ "\nComputing 5th Derivitive of Y with respect to x, Y'''''\n")
- (setq DDDDDy (Differentiate DDDDy 'x))
- (pp-form DDDDDy)
-
- (princ "\n\nDone (finally)\n")
-