Start to implement term div-terms

This commit is contained in:
2020-11-28 20:28:01 -05:00
parent 07e01a0483
commit 262d0ed507

View File

@@ -770,6 +770,8 @@
(put 'adjoin-term 'dense adjoin-term-dense) (put 'adjoin-term 'dense adjoin-term-dense)
(define (the-empty-termlist) (tag-sparse '())) (define (the-empty-termlist) (tag-sparse '()))
(define (empty-termlist t)
(attach-tag (type-tag t) '()))
(define (rest-terms term-list) (define (rest-terms term-list)
(let ((term-type (type-tag term-list)) (let ((term-type (type-tag term-list))
(terms (contents term-list))) (terms (contents term-list)))
@@ -839,6 +841,56 @@
(error "Polys not in same var -- MUL-POLY" (error "Polys not in same var -- MUL-POLY"
(list p1 p2)))) (list p1 p2))))
(define (div-poly p1 p2)
(if (same-variable? (variable p1) (variable p2))
(make-poly (variable p1)
(div-terms (term-list p1)
(term-list p2)))
(error "Polys not in same var -- MUL-POLY"
(list p1 p2))))
; Division can be performed via long division. That is, divide the highest-order
; term of the dividend by the highest-order term of the divisor. The result is
; the first term of the quotient. Next, multiply the result by the divisor,
; subtract that from the dividend, and produce the rest of the answer by
; recursively dividing the difference by the divisor. Stop when the order of the
; divisor exceeds the order of the dividend and declare the dividend to be the
; remainder. Also, if the dividend ever becomes zero, return zero as both
; quotient and remainder.
;
; We can design a div-poly procedure on the model of add-poly and mul-poly. The
; procedure checks to see if the two polys have the same variable. If so,
; div-poly strips off the variable and passes the problem to div-terms, which
; performs the division operation on term lists. Div-poly finally reattaches the
; variable to the result supplied by div-terms. It is convenient to design
; div-terms to compute both the quotient and the remainder of a division.
; Div-terms can take two term lists as arguments and return a list of the
; quotient term list and the remainder term list.
;
; dividend
; --------
; divisor
;
; Complete the following definition of div-terms by filling in the missing
; expressions. Use this to implement div-poly, which takes two polys as arguments
; and returns a list of the quotient and remainder polys.
(define (div-terms L1 L2)
(if (empty-termlist? L1)
(list L1 L2)
(let ((t1 (first-term L1))
(t2 (first-term L2)))
(if (> (order t2) (order t1))
(list (empty-termlist L2) L1)
(let ((new-c (div (coeff t1) (coeff t2)))
(new-o (- (order t1) (order t2)))
(new-term (make-term (- (order t1) (order t2))
(div (coeff t1) (coeff t2)))))
; XXX: continue here
(let ((rest-of-result (div-terms (empty-termlist L1) L2)))
(list (adjoin-term new-term (car rest-of-result))
(cadr rest-of-result))))))))
(define (=zero?-poly p) (define (=zero?-poly p)
(define (=zero?-terms terms) (define (=zero?-terms terms)
(cond (cond
@@ -855,6 +907,8 @@
(lambda (p1 p2) (tag (mul-poly p1 p2)))) (lambda (p1 p2) (tag (mul-poly p1 p2))))
(put 'sub '(polynomial polynomial) (put 'sub '(polynomial polynomial)
(lambda (p1 p2) (tag (sub-poly p1 p2)))) (lambda (p1 p2) (tag (sub-poly p1 p2))))
(put 'div '(polynomial polynomial)
(lambda (p1 p2) (div-poly p1 p2)))
(put '=zero? '(polynomial) =zero?-poly) (put '=zero? '(polynomial) =zero?-poly)
(put 'make 'poly-sparse (put 'make 'poly-sparse
(lambda (var terms) (tag (make-poly-sparse var terms)))) (lambda (var terms) (tag (make-poly-sparse var terms))))
@@ -893,8 +947,16 @@
(make-poly-dense 'x '((200 4) (101 8) (2 4)))) (make-poly-dense 'x '((200 4) (101 8) (2 4))))
(display "\nex-2.91\n") (display "\nex-2.91 - divide\n")
;(display "\nex-2.92\n") (define p1 (make-poly-dense 'x '((5 1) (0 -1))))
(define p2 (make-poly-dense 'x '((2 1) (0 -1))))
(assert (mul p1 p1) (make-poly-dense 'x '((10 1) (5 -2) (0 1))))
(assert (mul p1 p2) (make-poly-dense 'x '((7 1) (5 -1) (2 -1) (0 1))))
(display p1) (newline)
(display p2) (newline)
(display (div p1 p2)) (newline)
(display "\nex-2.92\n")
;(display "\nex-2.93\n") ;(display "\nex-2.93\n")