home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-04-27 | 2.2 KB | 62 lines | [TEXT/????] |
- ;;; $Header: lagrange.scm,v 1.2 87/08/28 00:53:44 GMT gjs Exp $
- ;;;; LAGRANGE.SCM
- ;;; produces an interpolation polynomial expression for a given
- ;;; set of values at a given set of points.
- ;;; (lagrange ys xs) |--> (lambda (t) ...)
- ;;; For example, if we do:
- ;;; (define xs '(.1 .2 .3 .4 .5 .6))
- ;;; (define bar (lagrange (map sin xs) xs))
- ;;; (define foo (lambda->procedure bar))
- ;;; Then BAR is a lambda-expression, and FOO is the procedure that
- ;;; evaluates the polynomial interpolating SIN at the given points.
- ;;;
-
- (if-mit
- (declare (usual-integrations = + - * /
- zero? 1+ -1+
- ;; truncate round floor ceiling
- sqrt exp log sin cos)))
-
- ;;; Needs: ALGCON.SCM (for algebraic constructors)
- ;;; COMCON.SCM (for LAMBDAFY, LETIFY utilities)
-
- (define lagrange
- (lambda (ys xs)
- (lambdafy 1
- (lambda (bvl)
- (let ((var (car bvl)))
- (letify (map (lambda (x) (make-diff var x)) xs)
- (lambda (diffs)
- (triangle-iterate xs ys
- (make-linear-interpolator (table-of eqv? xs diffs))))))))))
-
- (define triangle-iterate
- (lambda (xs v f) ;(f x0 x1 v0 v1)
- (define (all-except-ends l)
- (reverse (cdr (reverse (cdr l)))))
- (define map-consec-pairs
- (lambda (x0s x1s vs)
- (if (null? x1s)
- '()
- (cons (f (car x0s) (car x1s) (car vs) (cadr vs))
- (map-consec-pairs (cdr x0s) (cdr x1s) (cdr vs))))))
- (let level ((x1s (cdr xs)) (vs v))
- (if (null? (cdr vs))
- (car vs)
- (let ((nvs (map-consec-pairs xs x1s vs)))
- (if (null? (cdr nvs))
- (car nvs)
- (letify (all-except-ends nvs)
- (lambda (names)
- (level (cdr x1s)
- (append (list (car nvs))
- names
- (last-pair nvs)))))))))))
-
- (define make-linear-interpolator
- (lambda (lookup)
- (lambda (x0 x1 v0 v1)
- (make-quo (make-diff (make-prod v1 (lookup x0))
- (make-prod v0 (lookup x1)))
- (make-diff x1 x0)))))
-