Skip to content

Instantly share code, notes, and snippets.

@calebsmith
Created November 20, 2014 14:31
Show Gist options
  • Save calebsmith/13c3c36737fdb98eb553 to your computer and use it in GitHub Desktop.
Save calebsmith/13c3c36737fdb98eb553 to your computer and use it in GitHub Desktop.
Rough Polynomial Calculator with Derivatives
(define (repeat num arg)
(let inner ((current 0))
(if (>= current num)
#nil
(cons arg (inner (1+ current))))))
(define (make-range-stream min-x max-x step-x)
(let inner ((x min-x))
(cons x (delay
(if (or (eq? x #nil) (>= (+ step-x x) max-x))
(cons #nil (delay (inner #nil)))
(inner (+ step-x x)))))))
(define stream-car car)
(define stream-cdr (compose force cdr))
(define (stream-map func stream)
(let ((item (stream-car stream)))
(if (null? item)
item
(cons (func item) (stream-map func (stream-cdr stream))))))
(define (poly poly-lst)
(lambda (x)
(let inner ((coefs (reverse poly-lst))
(power 0)
(value 0))
(if (null? coefs)
value
(inner (cdr coefs) (1+ power)
(+ (* (car coefs) (expt x power)) value))))))
(define (derive-coefs poly-lst)
(let inner ((coefs (cdr (reverse poly-lst)))
(power 1)
(value '()))
(if (null? coefs)
value
(inner (cdr coefs) (1+ power)
(cons (* (car coefs) power) value)))))
(define (derive-poly-n num)
(let* ((derivs (repeat num derive-coefs))
(args (cons poly derivs)))
(apply compose args)))
(define (get-y-values coefs derive-amt min-x max-x step-x)
(let* ((base-func (derive-poly-n derive-amt))
(func (base-func coefs))
(range (make-range-stream min-x max-x step-x)))
(stream-map func range)))
; quick test
;
(get-y-values '(3 2 1) 0 0 10 1)
(get-y-values '(3 2 1) 1 0 10 1)
(get-y-values '(3 2 1) 2 0 10 1)
; output
; (1 6 17 34 57 86 121 162 209 262)
; (2 8 14 20 26 32 38 44 50 56)
; (6 6 6 6 6 6 6 6 6 6)
@calebsmith
Copy link
Author

This is roughly based on a procedure that does the same thing in SICP

poly takes a list that represents a polynomial. For instance, '(3 2 1) in the example means 3x^2 + 2x + 1.
It returns a function that takes an x, and returns the y value for the given polynomail function.

derive-coefs takes such a polynomial list and returns a list representing the polynomial's derivative. derive-poly-n creates a function that has the same interface and behavior as poly, but takes the derivative of the given polynomial list n times.

The calls in the "quick test" section return the y values for the range 0 to 10, incrementing by 1 for the given polynomial, its derivative and its second derivative.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment