close Warning: Can't synchronize with repository "(default)" (The repository directory has changed, you should resynchronize the repository with: trac-admin $ENV repository resync '(default)'). Look in the Trac log for more information.

source: branches/f4grobner/polynomial.lisp@ 432

Last change on this file since 432 was 432, checked in by Marek Rychlik, 10 years ago

* empty log message *

File size: 9.6 KB
RevLine 
[77]1;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*-
2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3;;;
4;;; Copyright (C) 1999, 2002, 2009, 2015 Marek Rychlik <rychlik@u.arizona.edu>
5;;;
6;;; This program is free software; you can redistribute it and/or modify
7;;; it under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 2 of the License, or
9;;; (at your option) any later version.
10;;;
11;;; This program is distributed in the hope that it will be useful,
12;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with this program; if not, write to the Free Software
18;;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19;;;
20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21
22
[431]23(defpackage "POLYNOMIAL"
[432]24 (:use :cl :monomial :term :termlist)
25 (:export "POLY"
26 "POLY-TERMLIST"
27 "POLY-SUGAR"
28 "POLY-LT"
29 ))
[143]30
[431]31(in-package :polynomial)
32
[52]33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
34;;
35;; Polynomials
36;;
37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
38
39(defstruct (poly
40 ;;
41 ;; BOA constructor, by default constructs zero polynomial
42 (:constructor make-poly-from-termlist (termlist &optional (sugar (termlist-sugar termlist))))
43 (:constructor make-poly-zero (&aux (termlist nil) (sugar -1)))
44 ;; Constructor of polynomials representing a variable
45 (:constructor make-variable (ring nvars pos &optional (power 1)
[53]46 &aux
47 (termlist (list
48 (make-term-variable ring nvars pos power)))
49 (sugar power)))
50 (:constructor poly-unit (ring dimension
51 &aux
52 (termlist (termlist-unit ring dimension))
53 (sugar 0))))
[52]54 (termlist nil :type list)
55 (sugar -1 :type fixnum))
56
57;; Leading term
58(defmacro poly-lt (p) `(car (poly-termlist ,p)))
59
60;; Second term
61(defmacro poly-second-lt (p) `(cadar (poly-termlist ,p)))
62
63;; Leading monomial
64(defun poly-lm (p) (term-monom (poly-lt p)))
65
66;; Second monomial
67(defun poly-second-lm (p) (term-monom (poly-second-lt p)))
68
69;; Leading coefficient
70(defun poly-lc (p) (term-coeff (poly-lt p)))
71
72;; Second coefficient
73(defun poly-second-lc (p) (term-coeff (poly-second-lt p)))
74
75;; Testing for a zero polynomial
76(defun poly-zerop (p) (null (poly-termlist p)))
77
78;; The number of terms
79(defun poly-length (p) (length (poly-termlist p)))
80
81(defun scalar-times-poly (ring c p)
82 (make-poly-from-termlist (scalar-times-termlist ring c (poly-termlist p)) (poly-sugar p)))
83
84;; The scalar product omitting the head term
85(defun scalar-times-poly-1 (ring c p)
86 (make-poly-from-termlist (scalar-times-termlist ring c (cdr (poly-termlist p))) (poly-sugar p)))
[53]87
[52]88(defun monom-times-poly (m p)
89 (make-poly-from-termlist (monom-times-termlist m (poly-termlist p)) (+ (poly-sugar p) (monom-sugar m))))
90
91(defun term-times-poly (ring term p)
92 (make-poly-from-termlist (term-times-termlist ring term (poly-termlist p)) (+ (poly-sugar p) (term-sugar term))))
93
94(defun poly-add (ring p q)
95 (make-poly-from-termlist (termlist-add ring (poly-termlist p) (poly-termlist q)) (max (poly-sugar p) (poly-sugar q))))
96
97(defun poly-sub (ring p q)
98 (make-poly-from-termlist (termlist-sub ring (poly-termlist p) (poly-termlist q)) (max (poly-sugar p) (poly-sugar q))))
99
100(defun poly-uminus (ring p)
101 (make-poly-from-termlist (termlist-uminus ring (poly-termlist p)) (poly-sugar p)))
102
103(defun poly-mul (ring p q)
104 (make-poly-from-termlist (termlist-mul ring (poly-termlist p) (poly-termlist q)) (+ (poly-sugar p) (poly-sugar q))))
105
106(defun poly-expt (ring p n)
107 (make-poly-from-termlist (termlist-expt ring (poly-termlist p) n) (* n (poly-sugar p))))
108
109(defun poly-append (&rest plist)
110 (make-poly-from-termlist (apply #'append (mapcar #'poly-termlist plist))
[53]111 (apply #'max (mapcar #'poly-sugar plist))))
[52]112
113(defun poly-nreverse (p)
114 (setf (poly-termlist p) (nreverse (poly-termlist p)))
115 p)
116
117(defun poly-contract (p &optional (k 1))
118 (make-poly-from-termlist (termlist-contract (poly-termlist p) k)
[53]119 (poly-sugar p)))
[52]120
121(defun poly-extend (p &optional (m (make-monom 1 :initial-element 0)))
122 (make-poly-from-termlist
123 (termlist-extend (poly-termlist p) m)
124 (+ (poly-sugar p) (monom-sugar m))))
125
126(defun poly-add-variables (p k)
127 (setf (poly-termlist p) (termlist-add-variables (poly-termlist p) k))
128 p)
129
130(defun poly-list-add-variables (plist k)
131 (mapcar #'(lambda (p) (poly-add-variables p k)) plist))
132
133(defun poly-standard-extension (plist &aux (k (length plist)))
134 "Calculate [U1*P1,U2*P2,...,UK*PK], where PLIST=[P1,P2,...,PK]."
135 (declare (list plist) (fixnum k))
136 (labels ((incf-power (g i)
137 (dolist (x (poly-termlist g))
138 (incf (monom-elt (term-monom x) i)))
139 (incf (poly-sugar g))))
140 (setf plist (poly-list-add-variables plist k))
141 (dotimes (i k plist)
142 (incf-power (nth i plist) i))))
143
144(defun saturation-extension (ring f plist &aux (k (length plist)) (d (monom-dimension (poly-lm (car plist)))))
145 "Calculate [F, U1*P1-1,U2*P2-1,...,UK*PK-1], where PLIST=[P1,P2,...,PK]."
146 (setf f (poly-list-add-variables f k)
147 plist (mapcar #'(lambda (x)
148 (setf (poly-termlist x) (nconc (poly-termlist x)
149 (list (make-term (make-monom d :initial-element 0)
150 (funcall (ring-uminus ring) (funcall (ring-unit ring)))))))
151 x)
152 (poly-standard-extension plist)))
153 (append f plist))
154
155
156(defun polysaturation-extension (ring f plist &aux (k (length plist))
[53]157 (d (+ k (length (poly-lm (car plist))))))
[52]158 "Calculate [F, U1*P1+U2*P2+...+UK*PK-1], where PLIST=[P1,P2,...,PK]."
159 (setf f (poly-list-add-variables f k)
160 plist (apply #'poly-append (poly-standard-extension plist))
161 (cdr (last (poly-termlist plist))) (list (make-term (make-monom d :initial-element 0)
162 (funcall (ring-uminus ring) (funcall (ring-unit ring))))))
163 (append f (list plist)))
164
165(defun saturation-extension-1 (ring f p) (polysaturation-extension ring f (list p)))
[53]166
167
168
169;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
170;;
171;; Evaluation of polynomial (prefix) expressions
172;;
173;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
174
175(defun coerce-coeff (ring expr vars)
176 "Coerce an element of the coefficient ring to a constant polynomial."
177 ;; Modular arithmetic handler by rat
178 (make-poly-from-termlist (list (make-term (make-monom (length vars) :initial-element 0)
179 (funcall (ring-parse ring) expr)))
180 0))
181
182(defun poly-eval (ring expr vars &optional (list-marker '[))
183 (labels ((p-eval (arg) (poly-eval ring arg vars))
184 (p-eval-list (args) (mapcar #'p-eval args))
185 (p-add (x y) (poly-add ring x y)))
186 (cond
187 ((eql expr 0) (make-poly-zero))
188 ((member expr vars :test #'equalp)
189 (let ((pos (position expr vars :test #'equalp)))
190 (make-variable ring (length vars) pos)))
191 ((atom expr)
192 (coerce-coeff ring expr vars))
193 ((eq (car expr) list-marker)
194 (cons list-marker (p-eval-list (cdr expr))))
195 (t
196 (case (car expr)
197 (+ (reduce #'p-add (p-eval-list (cdr expr))))
198 (- (case (length expr)
199 (1 (make-poly-zero))
200 (2 (poly-uminus ring (p-eval (cadr expr))))
201 (3 (poly-sub ring (p-eval (cadr expr)) (p-eval (caddr expr))))
202 (otherwise (poly-sub ring (p-eval (cadr expr))
203 (reduce #'p-add (p-eval-list (cddr expr)))))))
204 (*
205 (if (endp (cddr expr)) ;unary
206 (p-eval (cdr expr))
207 (reduce #'(lambda (p q) (poly-mul ring p q)) (p-eval-list (cdr expr)))))
208 (expt
209 (cond
210 ((member (cadr expr) vars :test #'equalp)
211 ;;Special handling of (expt var pow)
212 (let ((pos (position (cadr expr) vars :test #'equalp)))
213 (make-variable ring (length vars) pos (caddr expr))))
214 ((not (and (integerp (caddr expr)) (plusp (caddr expr))))
215 ;; Negative power means division in coefficient ring
216 ;; Non-integer power means non-polynomial coefficient
217 (coerce-coeff ring expr vars))
218 (t (poly-expt ring (p-eval (cadr expr)) (caddr expr)))))
219 (otherwise
220 (coerce-coeff ring expr vars)))))))
[55]221
222(defun spoly (ring f g)
223 "It yields the S-polynomial of polynomials F and G."
224 (declare (type poly f g))
225 (let* ((lcm (monom-lcm (poly-lm f) (poly-lm g)))
226 (mf (monom-div lcm (poly-lm f)))
227 (mg (monom-div lcm (poly-lm g))))
228 (declare (type monom mf mg))
229 (multiple-value-bind (c cf cg)
230 (funcall (ring-ezgcd ring) (poly-lc f) (poly-lc g))
231 (declare (ignore c))
232 (poly-sub
233 ring
234 (scalar-times-poly ring cg (monom-times-poly mf f))
[53]235 (scalar-times-poly ring cf (monom-times-poly mg g))))))
236
[55]237
238(defun poly-primitive-part (ring p)
239 "Divide polynomial P with integer coefficients by gcd of its
240coefficients and return the result."
241 (declare (type poly p))
242 (if (poly-zerop p)
243 (values p 1)
244 (let ((c (poly-content ring p)))
245 (values (make-poly-from-termlist (mapcar
246 #'(lambda (x)
247 (make-term (term-monom x)
248 (funcall (ring-div ring) (term-coeff x) c)))
249 (poly-termlist p))
250 (poly-sugar p))
251 c))))
252
253(defun poly-content (ring p)
254 "Greatest common divisor of the coefficients of the polynomial P. Use the RING structure
255to compute the greatest common divisor."
256 (declare (type poly p))
[57]257 (reduce (ring-gcd ring) (mapcar #'term-coeff (rest (poly-termlist p))) :initial-value (poly-lc p)))
258
Note: See TracBrowser for help on using the repository browser.