source: CGBLisp/src/RCS/svpoly.lisp,v@ 1

Last change on this file since 1 was 1, checked in by Marek Rychlik, 15 years ago

First import of a version circa 1997.

File size: 9.6 KB
Line 
1head 1.4;
2access;
3symbols;
4locks; strict;
5comment @;;; @;
6
7
81.4
9date 2009.01.23.10.37.28; author marek; state Exp;
10branches;
11next 1.3;
12
131.3
14date 2009.01.22.04.08.18; author marek; state Exp;
15branches;
16next 1.2;
17
181.2
19date 2009.01.19.09.31.34; author marek; state Exp;
20branches;
21next 1.1;
22
231.1
24date 2009.01.19.07.53.12; author marek; state Exp;
25branches;
26next ;
27
28
29desc
30@@
31
32
331.4
34log
35@*** empty log message ***
36@
37text
38@#|
39 $Id$
40 *--------------------------------------------------------------------------*
41 | Copyright (C) 1994, Marek Rychlik (e-mail: rychlik@@math.arizona.edu) |
42 | Department of Mathematics, University of Arizona, Tucson, AZ 85721 |
43 | |
44 | Everyone is permitted to copy, distribute and modify the code in this |
45 | directory, as long as this copyright note is preserved verbatim. |
46 *--------------------------------------------------------------------------*
47|#
48(defpackage "SVPOLY"
49 (:export))
50
51(in-package "SVPOLY")
52
53#+debug(proclaim '(optimize (speed 0) (debug 3)))
54#-debug(proclaim '(optimize (speed 3) (debug 0)))
55
56(defstruct (svpoly (:constructor make-svpoly-raw))
57 (nvars "Number of variables." (:type fixnum))
58 (coefficient-type "Type of the coefficient.")
59 (order "Monomial order.")
60 (terms "The array of terms."))
61
62(defun make-svpoly (alist order
63 &aux (nterms (length alist))
64 (nvars (length (caar alist)))
65 (coefficient-type (type-of (cdar alist))))
66 "Construct svpolynomial from ALIST."
67 (let ((svp (make-svpoly-raw
68 :nvars nvars
69 :coefficient-type (type-of (cdar alist))
70 :order order
71 :terms (make-array nterms :element-type 'cons))))
72 (dotimes (i nterms)
73 (let ((term (nth i alist)))
74 (setf (svref (svpoly-terms svp) i)
75 (cons (make-array nvars :initial-contents (car term))
76 (cdr term)))))
77 (svpoly-sort svp)))
78
79(defun svpoly-sort (svp)
80 "Destructively sorts an sv-polynomial SVP."
81 (setf (svpoly-terms svp) (sort (svpoly-terms svp) (svpoly-order svp) :key #'car)) svp)
82
83(defun make-order (nvars order)
84 "Returns an order function with two parameters P and Q such that if called
85on a pair of monomials with exactly NVARS variables, this function
86will return T if P is greater than Q and NIL otherwise. The keyword
87ORDER indicates one of several standard orders (:LEX, etc)."
88 (declare (fixnum nvars))
89 (ecase order
90 (:lex #'(lambda (p q)
91 (dotimes (i nvars (values NIL T))
92 (declare (fixnum i))
93 (cond
94 ((> (svref p i) (svref q i))
95 (return (values t nil)))
96 ((< (svref p i) (svref q i))
97 (return (values nil nil)))))))))
98
99(defun svpoly-add (p q)
100 "Adds polynomials P and Q, where P and Q are assumed to be ordered
101by the same monomial order. Destructive to P and Q."
102 (setf (svpoly-terms p) (add-terms (svpoly-terms p) (svpoly-terms q)
103 (svpoly-order p)))
104 p)
105
106(defun add-terms (p q pred &aux (lp (length p)) (lq (length q)))
107 (do ((r (make-array (+ lp lq) :element-type 'cons))
108 (i 0) (j 0) (k 0) done)
109 (done (coerce (adjust-array r k) 'simple-vector))
110 (cond
111 ((= i lp)
112 (do nil
113 ((>= j lq) (setf done t))
114 (setf (aref r k) (svref q j))
115 (incf j) (incf k)))
116 ((= j lq)
117 (do nil
118 ((>= i lp) (setf done t))
119 (setf (aref r k) (svref p i))
120 (incf i) (incf k)))
121 (t
122 (multiple-value-bind
123 (mgreater mequal)
124 (funcall pred (car (svref p i)) (car (svref q j)))
125 (cond
126 (mequal
127 (let ((s (+ (cdr (svref p i)) (cdr (svref q j)))))
128 (unless (zerop s) ;check for cancellation
129 (setf (aref r k) (cons (car (svref p i)) s))
130 (incf k))
131 (incf i)
132 (incf j)))
133 (mgreater
134 (setf (aref r k) (svref p i))
135 (incf i)
136 (incf k))
137 (t
138 (setf (aref r k) (svref q j))
139 (incf j)
140 (incf k))))))))
141
142#|
143
144(defun scalar-times-poly (c p)
145 "Return product of a scalar C by a polynomial P with coefficient ring RING."
146 (unless (funcall (ring-zerop ring) c)
147 (mapcar
148 #'(lambda (term) (cons (car term) (funcall (ring-* ring) c (cdr term))))
149 p)))
150
151(defun term-times-poly (term f &optional (ring *coefficient-ring*))
152 "Return product of a term TERM by a polynomial F with coefficient ring RING."
153 (mapcar #'(lambda (x) (term* term x ring)) f))
154
155(defun monom-times-poly (m f)
156 "Return product of a monomial M by a polynomial F with coefficient ring RING."
157 (mapcar #'(lambda (x) (monom-times-term m x)) f))
158
159(defun minus-poly (f &optional (ring *coefficient-ring*))
160 "Changes the sign of a polynomial F with coefficients in coefficient ring
161RING, and returns the result."
162 (mapcar #'(lambda (x) (cons (car x) (funcall (ring-- ring) (cdr x)))) f))
163
164
165(defun poly+ (p q &optional (pred #'lex>) (ring *coefficient-ring*))
166 "Returns the sum of two polynomials P and Q with coefficients in
167ring RING, with terms ordered according to monomial order PRED."
168 (do (r done)
169 (done r)
170 (cond
171 ((endp p) (setf r (append (nreverse r) q) done t))
172 ((endp q) (setf r (append (nreverse r) p) done t))
173 (t
174 (multiple-value-bind
175 (mgreater mequal)
176 (funcall pred (caar p) (caar q))
177 (cond
178 (mequal
179 (let ((s (funcall (ring-+ ring) (cdar p) (cdar q))))
180 (unless (funcall (ring-zerop ring) s) ;check for cancellation
181 (setf r (cons (cons (caar p) s) r)))
182 (setf p (cdr p) q (cdr q))))
183 (mgreater
184 (setf r (cons (car p) r)
185 p (cdr p)))
186 (t (setf r (cons (car q) r)
187 q (cdr q)))))))))
188
189(defun poly- (p q &optional (pred #'lex>) (ring *coefficient-ring*))
190 "Returns the difference of two polynomials P and Q with coefficients
191in ring RING, with terms ordered according to monomial order PRED."
192 (do (r done)
193 (done r)
194 (cond
195 ((endp p) (setf r (append (nreverse r) (minus-poly q ring)) done t))
196 ((endp q) (setf r (append (nreverse r) p) done t))
197 (t
198 (multiple-value-bind
199 (mgreater mequal)
200 (funcall pred (caar p) (caar q))
201 (cond
202 (mequal
203 (let ((s (funcall (ring-- ring) (cdar p) (cdar q))))
204 (unless (zerop s) ;check for cancellation
205 (setf r (cons (cons (caar p) s) r)))
206 (setf p (cdr p) q (cdr q))))
207 (mgreater
208 (setf r (cons (car p) r)
209 p (cdr p)))
210 (t (setf r (cons (cons (caar q) (funcall (ring-- ring) (cdar q))) r)
211 q (cdr q)))))))))
212
213;; Multiplication of polynomials
214;; Non-destructive version
215(defun poly* (p q &optional (pred #'lex>) (ring *coefficient-ring*))
216 "Returns the product of two polynomials P and Q with coefficients in
217ring RING, with terms ordered according to monomial order PRED."
218 (cond ((or (endp p) (endp q)) nil) ;p or q is 0 (represented by NIL)
219 ;; If p=p0+p1 and q=q0+q1 then pq=p0q0+p0q1+p1q
220 (t (cons (cons (monom* (caar p) (caar q))
221 (funcall (ring-* ring) (cdar p) (cdar q)))
222 (poly+ (term-times-poly (car p) (cdr q) ring)
223 (poly* (cdr p) q pred ring)
224 pred ring)))))
225
226(defun poly-op (f m g pred ring)
227 "Returns F-M*G, where F and G are polynomials with coefficients in
228ring RING, ordered according to monomial order PRED and M is a
229monomial."
230 (poly- f (term-times-poly m g ring) pred ring))
231
232(defun poly-expt (poly n &optional (pred #'lex>) (ring *coefficient-ring*))
233 "Exponentiate a polynomial POLY to power N. The terms of the
234polynomial are assumed to be ordered by monomial order PRED and with
235coefficients in ring RING. Use the Chinese algorithm; assume N>=0 and
236POLY is non-zero (not NIL)."
237 (labels ((poly-one ()
238 (list
239 (cons (make-list (length (caar poly)) :initial-element 0) (ring-unit ring)))))
240 (cond
241 ((minusp n) (error "Negative exponent."))
242 ((endp poly) (if (zerop n) (poly-one) nil))
243 (t
244 (do ((k 1 (ash k 1))
245 (q poly (poly* q q pred ring)) ;keep squaring
246 (p (poly-one) (if (not (zerop (logand k n))) (poly* p q pred ring) p)))
247 ((> k n) p))))))
248
249(defun poly-mexpt (plist monom &optional (pred #'lex>) (ring *coefficient-ring*))
250 "Raise a polynomial vector represented ad a list of polynomials
251PLIST to power MULTIINDEX. Every polynomial has its terms ordered by
252predicate PRED and coefficients in the ring RING."
253 (reduce
254 #'(lambda (u v) (poly* u v pred ring))
255 (mapcan #'(lambda (y i)
256 (cond ((endp y) (if (zerop i) nil (list nil)))
257 (t (list (poly-expt y i pred ring)))))
258 plist monom)))
259
260(defun poly-constant-p (p)
261 "Returns T if P is a constant polynomial."
262 (and (= (length p) 1)
263 (every #'zerop (caar p))))
264
265
266(defun poly-extend (p &optional (m (list 0)))
267 "Given a polynomial P in k[x[r+1],...,xn], it returns the same
268polynomial as an element of k[x1,...,xn], optionally multiplying it by
269a monomial x1^m1*x2^m2*...*xr^mr, where m=(m1,m2,...,mr) is a
270multiindex."
271 (mapcar #'(lambda (term) (cons (append m (car term)) (cdr term))) p))
272
273(defun poly-extend-end (p &optional (m (list 0)))
274 "Similar to POLY-EXTEND, but it adds new variables at the end."
275 (mapcar #'(lambda (term) (cons (append (car term) m) (cdr term))) p))
276
277(defun poly-zerop (p)
278 "Returns T if P is a zero polynomial."
279 (null p))
280
281(defun lt (p)
282 "Returns the leading term of a polynomial P."
283 #+debugging(assert (consp p))
284 (first p))
285
286(defun lm (p)
287 "Returns the leading monomial of a polynomial P."
288 #+debugging(assert (consp (lt p)))
289 (car (lt p)))
290
291(defun lc (p)
292 "Returns the leading coefficient of a polynomial P."
293 #+debugging(assert (consp (lt p)))
294 (cdr (lt p)))
295
296|#@
297
298
2991.3
300log
301@*** empty log message ***
302@
303text
304@a239 3
305(eval-when (compile)
306 (proclaim '(inline lt lm lc poly-zerop scalar-times-poly)))
307
308@
309
310
3111.2
312log
313@*** empty log message ***
314@
315text
316@d16 2
317a17 2
318;;(proclaim '(optimize (speed 0) (debug 3)))
319(proclaim '(optimize (speed 3) (debug 0)))
320@
321
322
3231.1
324log
325@Initial revision
326@
327text
328@d2 1
329a2 1
330 $Id: svpoly.lisp,v 1.6 1997/12/25 02:00:04 marek Exp $
331d16 2
332a17 1
333(proclaim '(optimize (speed 0) (debug 3)))
334@
Note: See TracBrowser for help on using the repository browser.