<< Previous exercise (2.55) | Index | Next exercise (2.57) >>
(define (deriv expr var)
(cond ((number? expr) 0)
((variable? expr) (if (same-variable? expr var) 1 0))
((sum? expr) (make-sum (deriv (addend expr) var)
(deriv (augend expr) var)))
((product? expr) (let ((m1 (multiplier expr)) (m2 (multiplicand expr)))
(make-sum (make-product (deriv m1 var) m2)
(make-product m1 (deriv m2 var)))))
((and (exponentiation? expr) (=number? (deriv (exponent expr) var) 0))
(let ((b (base expr)) (e (exponent expr)))
(make-product (deriv b var)
(make-product e (make-exponentiation b (make-sum e -1))))))
(else (list 'deriv expr var))))
Without the check that the derivative of the exponent is 0 the code would be wrong, since the derivative of x |-> x^x is not x |-> x*x^(x-1)=x^x.
The above solution works. but in the end product, there is no need to check the exponent is number or not, procedure make-sum can do that. so the end product can be like this:
(define (deriv expr var)
(cond ((number? expr) 0)
((variable? expr)
(if (same-variable? expr var) 1 0))
((sum? expr)
(make-sum (deriv (addend expr) var)
(deriv (augend expr) var)))
((product? expr)
(make-sum
(make-product (multiplier expr)
(deriv (multiplicand expr) var))
(make-product (multiplicand expr)
(deriv (multiplier expr) var))))
((exponentiation? expr)
(make-product
(make-product
(exponent expr)
(make-exponentiation (base expr)
(make-sum (exponent expr) -1)))
(deriv (base expr) var)))
(else (error "unkown expression type -- DERIV" expr))))
Show how to extend the basic differentiator to handle more kinds of expressions. For instance, implement the differentiation rule
d(u^n)/dr = nu^(n-1)(du/dr)
by adding a new clause to the deriv program and defining appropriate procedures exponentiation?, base, exponent, and make-exponentiation. (You may use the symbol ** to denote exponentiation.) Build in the rules that anything raised to the power 0 is 1 and anything raised to the power 1 is the thing itself.
code given in the book:
First add this code to (derive exp var) to add differentiation of exponentiations.
((exponentiation? exp) (make-product (make-product (exponent exp) (make-exponentiation (base exp) (make-sum(exponent exp) '-1))) (deriv (base exp) var)))
The end product is:
(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)))) ((exponentiation? exp) (make-product (make-product (exponent exp) (make-exponentiation (base exp) (if (number? (exponent exp)) (- (exponent exp) 1) (' (- (exponent exp) 1))))) (deriv (base exp) var))) (else (error "unknown expression type -- DERIV" exp))))
Next (define (exponentiation? exp))
(define (exponentiation? exp) (and (pair? exp) (eq? (car exp) '**)))
We are using '** as the symbol for exponent.
Next, (define (base exp)) and (define (exponent exp))
All that is left is to (define (make-exponentiation base exp)).
(define (make-exponentiation base exp) (cond ((=number? base 1) 1) ((=number? exp 1) base) ((=number? exp 0) 1) (else (list '** base exp))))
otakutyrant
Good simplification, but we can simplify it more:
(define (make-exponentiation base exponent) (cond ((=number? base 1) 1) ((=number? exponent 0) 1) ((=number? exponent 1) base) ((and (number? base) (number? exponent)) (expt base exponent)) (else (list '** base exponent)) ) )