2.90¶
; Suppose we want to have a polynomial system that is efficient for both sparse and ; dense polynomials. One way to do this is to allow both kinds of term-list ; representations in our system. The situation is analogous to the complex-number ; example of Section 2.4, where we allowed both rectangular and polar representations. ; To do this we must distinguish different types of term lists and make the ; operations on term lists generic. Redesign the polynomial system to implement this ; generalization. This is a major effort, not a local change. ; Dense package (define (install-polynomial-package-dense) ;; internal procedures ;; representation of poly (define (make-poly variable term-list) (cons variable term-list)) (define (variable p) (car p)) (define (term-list p) (cdr p)) ; ⟨procedures same-variable? and variable? from section 2.3.2⟩ (define (variable? x) (symbol? x)) (define (same-variable? v1 v2) (and (variable? v1) (variable? v2) (eq? v1 v2))) ;; representation of terms (define (adjoin-term term term-list) (cond ((=zero? term) term-list) ((= (order term) (length term-list)) (cons (coeff term) term-list)) (else (adjoin-term term (cons 0 term-list))))) (define (the-empty-termlist) '()) (define (first-term term-list) (make-term (- (length term-list) 1) (car term-list))) (define (rest-term term-list) (cdr term-list)) (define (empty-termlist? term-list) (null? term-list)) (define (make-term order coeff) (list order coeff)) (define (order term) (car term)) (define (coeff term) (cadr term)) ;; Add (define (add-poly p1 p2) (if (same-variable? (variable p1) (variable p2)) (make-poly (variable p1) (add-terms (term-list p1) (term-list p2))) (error "Polys not in same var: ADD-POLY" (list p1 p2)))) (define (add-terms L1 L2) (cond ((empty-termlist? L1) L2) ((empty-termlist? L2) L1) (else (let ((t1 (first-term L1)) (t2 (first-term L2))) (cond ((> (order t1) (order t2)) (adjoin-term t1 (add-terms (rest-terms L1) L2))) ((< (order t1) (order t2)) (adjoin-term t2 (add-terms L1 (rest-terms L2)))) (else (adjoin-term (make-term (order t1) (add (coeff t1) (coeff t2))) (add-terms (rest-terms L1) (rest-terms L2))))))))) ;; Multiply (define (mul-poly p1 p2) (if (same-variable? (variable p1) (variable p2)) (make-poly (variable p1) (mul-terms (term-list p1) (term-list p2))) (error "Polys not in same var: MUL-POLY" (list p1 p2)))) (define (mul-terms L1 L2) (if (empty-termlist? L1) (the-empty-termlist) (add-terms (mul-term-by-all-terms (first-term L1) L2) (mul-terms (rest-terms) L2)))) (define (mul-term-by-all-terms t1 L) (if (empty-termlist? L) (the-empty-termlist) (let ((t2 (first-term L))) (adjoin-term (make-term (+ (order t1) (order t2)) (mul (coeff t1) (coeff t2))) (mul-term-by-all-terms t1 (rest-terms L)))))) ;; interface to rest of the system (define (tag p) (attach-tag 'polynomial-dense p)) (put 'add '(polynomial-dense polynomial-dense) (lambda (p1 p2) (tag (add-poly p1 p2)))) (put 'mul '(polynomial-dense polynomial-dense) (lambda (p1 p2) (tag (mul-poly p1 p2)))) (put 'make 'polynomial-dense (lambda (var terms) (tag (make-poly var terms)))) 'done) ; Sparse package (define (install-polynomial-package-sparse) ;; internal procedures ;; representation of poly (define (make-poly variable term-list) (cons variable term-list)) (define (variable p) (car p)) (define (term-list p) (cdr p)) ; ⟨procedures same-variable? and variable? from section 2.3.2⟩ (define (variable? x) (symbol? x)) (define (same-variable? v1 v2) (and (variable? v1) (variable? v2) (eq? v1 v2))) ;; representation of terms (define (adjoin-term term term-list) (if (=zero? (coeff term)) term-list (cons term term-list))) (define (the-empty-termlist) '()) (define (first-term term-list) (car term-list)) (define (rest-terms term-list) (cdr term-list)) (define (empty-termlist? term-list) (null? term-list)) (define (make-term order coeff) (list order coeff)) (define (order term) (car term)) (define (coeff term) (cadr term)) ;; Add (define (add-poly p1 p2) (if (same-variable? (variable p1) (variable p2)) (make-poly (variable p1) (add-terms (term-list p1) (term-list p2))) (error "Polys not in same var: ADD-POLY" (list p1 p2)))) (define (add-terms L1 L2) (cond ((empty-termlist? L1) L2) ((empty-termlist? L2) L1) (else (let ((t1 (first-term L1)) (t2 (first-term L2))) (cond ((> (order t1) (order t2)) (adjoin-term t1 (add-terms (rest-terms L1) L2))) ((< (order t1) (order t2)) (adjoin-term t2 (add-terms L1 (rest-terms L2)))) (else (adjoin-term (make-term (order t1) (add (coeff t1) (coeff t2))) (add-terms (rest-terms L1) (rest-terms L2))))))))) ;; Multiply (define (mul-poly p1 p2) (if (same-variable? (variable p1) (variable p2)) (make-poly (variable p1) (mul-terms (term-list p1) (term-list p2))) (error "Polys not in same var: MUL-POLY" (list p1 p2)))) (define (mul-terms L1 L2) (if (empty-termlist? L1) (the-empty-termlist) (add-terms (mul-term-by-all-terms (first-term L1) L2) (mul-terms (rest-terms) L2)))) (define (mul-term-by-all-terms t1 L) (if (empty-termlist? L) (the-empty-termlist) (let ((t2 (first-term L))) (adjoin-term (make-term (+ (order t1) (order t2)) (mul (coeff t1) (coeff t2))) (mul-term-by-all-terms t1 (rest-terms L)))))) ;; interface to rest of the system (define (tag p) (attach-tag 'polynomial-sparse p)) (put 'add '(polynomial-sparse polynomial-sparse) (lambda (p1 p2) (tag (add-poly p1 p2)))) (put 'mul '(polynomial-sparse polynomial-sparse) (lambda (p1 p2) (tag (mul-poly p1 p2)))) (put 'make 'polynomial-sparse (lambda (var terms) (tag (make-poly var terms)))) 'done)