Created
November 20, 2014 14:31
-
-
Save calebsmith/13c3c36737fdb98eb553 to your computer and use it in GitHub Desktop.
Rough Polynomial Calculator with Derivatives
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.