Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using a dispatch table in racket

Tags:

scheme

racket

I am writing a small program to compute simple derivatives of expressions represented in list form i.e 2x^2 is represented as (* 2 (exp x 2)) and I have defined the following functions:

;; derivative of a constant is 0
(define (diff-constant x E) 0)

;; computes derivative of E with respect to x where E can only be of the form
;; (+ x x ...)
(define (diff-sum x E)
  (cond ((or (not (list? E)) (null? E)) 0)
        ((eq? (car E) x) (+ 1 (diff-sum x (cdr E))))
        (else (diff-sum x (cdr E)))))

;; computes derivative of E with respect to x where E can only be of the form
;; (* x y)
(define (diff-product x E)
  (cond ((and (eq? x (cadr E)) (eq? x (caddr E))) (list '* 2 x))
        ((eq? x (cadr E)) (list (caddr E)))
        ((eq? x (caddr E)) (list (cadr E)))
        (else 0)))

;; computes derivative of E with respect to x where E can only be of the form
;; (expt x y) which is x^y
(define (diff-expt x E)
  (cond ( not (eq? x (cadr E)) 0)
        ((eq? 1 (caddr E)) 0)
        ((eq? 2 (caddr E)) (cadr E))
        (else (list '* (caddr E) (list 'expt x (- (caddr E) 1))))))

I also have a dispatch table defined as:

;; Dispatch Table of supported operators.
 (define diff-dispatch
   (list (list '+ diff-sum)
         (list '* diff-product)
         (list 'expt diff-expt)
         ))

and I am trying to write a function diff that takes an equation E (in list form) and computes the derivative with respect to x and uses the dispatch table to call the pre-defined functions returning the result

here is what I have so far but I can't figure out the rest

;; Differentiate expression E with respect to x.
(define (diff x E)
  (cond ((number? E) (diff-constant x E))
        ;; insert code here to handle the other base case - variables
        ...
        (else    ; insert code here to lookup the appropriate function in the
                 ; dispatch table based on the operator in the expression,
                 ; then call that function to differentiate the expression
                     (diff-func x E))))))

ex: (diff 'x '(+ x (* x x))) should evaluate to (+ 1 (+ (* 1 (* x)) (* x 1))) (i.e. 1 + x + x)

like image 662
kfem Avatar asked May 14 '26 08:05

kfem


1 Answers

In the SICP book there's a whole section explaining in detail how to build a Scheme program for performing symbolic differentiation, take a look at section §2.3. In particular, be aware that you're missing one case - what happens if the expression to be derived is a variable? check the link to make sure that you're on the right track.

Now, answering the question: it's simple to implement a dispatcher given the table representation used in the code. Something along these lines will work for obtaining an applying the correct differentiation procedure:

((cadr             ; obtain the differentiation procedure
  (assoc           ; look for the differentiation procedure
   (car E)         ; obtain the operator in the expression
   diff-dispatch)) ; dispatch table
 x E)              ; apply the procedure with parameters `x` and `E`

Notice that the "trick" for finding the correct procedure to apply lies in the fact that the table is implemented as an association list, and the assoc procedure was designed precisely for finding data in such a list. Read more about it in the documentation.

like image 147
Óscar López Avatar answered May 18 '26 13:05

Óscar López



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!