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/monom.lisp@ 2778

Last change on this file since 2778 was 2778, checked in by Marek Rychlik, 9 years ago

* empty log message *

File size: 9.6 KB
Line 
1;;; -*- Mode: Lisp -*-
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(defpackage "MONOM"
23 (:use :cl :ring)
24 (:export "MONOM"
25 "EXPONENT"
26 "MONOM-EQUALP"
27 "MAKE-MONOM-VARIABLE")
28 (:documentation
29 "This package implements basic operations on monomials.
30DATA STRUCTURES: Conceptually, monomials can be represented as lists:
31
32 monom: (n1 n2 ... nk) where ni are non-negative integers
33
34However, lists may be implemented as other sequence types, so the
35flexibility to change the representation should be maintained in the
36code to use general operations on sequences whenever possible. The
37optimization for the actual representation should be left to
38declarations and the compiler.
39
40EXAMPLES: Suppose that variables are x and y. Then
41
42 Monom x*y^2 ---> (1 2) "))
43
44(in-package :monom)
45
46(proclaim '(optimize (speed 3) (space 0) (safety 0) (debug 0)))
47
48(deftype exponent ()
49 "Type of exponent in a monomial."
50 'fixnum)
51
52(defclass monom ()
53 ((dimension :initarg :dimension :accessor r-dimension)
54 (exponents :initarg :exponents :accessor r-exponents))
55 (:default-initargs :dimension nil :exponents nil :exponent nil))
56
57(defmethod print-object ((self monom) stream)
58 (format stream "#<MONOM DIMENSION=~A EXPONENTS=~A>"
59 (r-dimension self)
60 (r-exponents self)))
61
62(defmethod shared-initialize :after ((self monom) slot-names
63 &key
64 dimension
65 exponents
66 exponent
67 &allow-other-keys
68 )
69 (if (eq slot-names t) (setf slot-names '(dimension exponents)))
70 (dolist (slot-name slot-names)
71 (case slot-name
72 (dimension
73 (cond (dimension
74 (setf (slot-value self 'dimension) dimension))
75 (exponents
76 (setf (slot-value self 'dimension) (length exponents)))
77 (t
78 (error "DIMENSION or EXPONENTS must not be NIL"))))
79 (exponents
80 (cond
81 ;; when exponents are supplied
82 (exponents
83 (let ((dim (length exponents)))
84 (when (and dimension (/= dimension dim))
85 (error "EXPONENTS must have length DIMENSION"))
86 (setf (slot-value self 'dimension) dim
87 (slot-value self 'exponents) (make-array dim :initial-contents exponents))))
88 ;; when all exponents are to be identical
89 (t
90 (let ((dim (slot-value self 'dimension)))
91 (setf (slot-value self 'exponents)
92 (make-array (list dim) :initial-element (or exponent 0)
93 :element-type 'exponent)))))))))
94
95(defun monom-equalp (m1 m2)
96 "Returns T iff monomials M1 and M2 have identical
97EXPONENTS."
98 (declare (type monom m1 m2))
99 (equalp (r-exponents m1) (r-exponents m2)))
100
101(defmethod r-coeff ((m monom))
102 "A MONOM can be treated as a special case of TERM,
103where the coefficient is 1."
104 1)
105
106(defmethod r-elt ((m monom) index)
107 "Return the power in the monomial M of variable number INDEX."
108 (with-slots (exponents)
109 m
110 (elt exponents index)))
111
112(defmethod (setf r-elt) (new-value (m monom) index)
113 "Return the power in the monomial M of variable number INDEX."
114 (with-slots (exponents)
115 m
116 (setf (elt exponents index) new-value)))
117
118(defmethod r-total-degree ((m monom) &optional (start 0) (end (r-dimension m)))
119 "Return the todal degree of a monomoal M. Optinally, a range
120of variables may be specified with arguments START and END."
121 (declare (type fixnum start end))
122 (with-slots (exponents)
123 m
124 (reduce #'+ exponents :start start :end end)))
125
126
127(defmethod r-sugar ((m monom) &aux (start 0) (end (r-dimension m)))
128 "Return the sugar of a monomial M. Optinally, a range
129of variables may be specified with arguments START and END."
130 (declare (type fixnum start end))
131 (r-total-degree m start end))
132
133(defmethod r* ((m1 monom) (m2 monom))
134 "Multiply monomial M1 by monomial M2."
135 (with-slots ((exponents1 exponents) dimension)
136 m1
137 (with-slots ((exponents2 exponents))
138 m2
139 (let* ((exponents (copy-seq exponents1)))
140 (map-into exponents #'+ exponents1 exponents2)
141 (make-instance 'monom :dimension dimension :exponents exponents)))))
142
143(defmethod multiply-by ((self monom) (other monom))
144 (with-slots ((exponents1 exponents))
145 self
146 (with-slots ((exponents2 exponents))
147 other
148 (map-into exponents1 #'+ exponents1 exponents2)))
149 self)
150
151(defmethod r/ ((m1 monom) (m2 monom))
152 "Divide monomial M1 by monomial M2."
153 (with-slots ((exponents1 exponents) (dimension1 dimension))
154 m1
155 (with-slots ((exponents2 exponents))
156 m2
157 (let* ((exponents (copy-seq exponents1))
158 (dimension dimension1))
159 (map-into exponents #'- exponents1 exponents2)
160 (make-instance 'monom :dimension dimension :exponents exponents)))))
161
162(defmethod r-divides-p ((m1 monom) (m2 monom))
163 "Returns T if monomial M1 divides monomial M2, NIL otherwise."
164 (with-slots ((exponents1 exponents))
165 m1
166 (with-slots ((exponents2 exponents))
167 m2
168 (every #'<= exponents1 exponents2))))
169
170
171(defmethod r-divides-lcm-p ((m1 monom) (m2 monom) (m3 monom))
172 "Returns T if monomial M1 divides LCM(M2,M3), NIL otherwise."
173 (every #'(lambda (x y z) (<= x (max y z)))
174 m1 m2 m3))
175
176
177(defmethod r-lcm-divides-lcm-p ((m1 monom) (m2 monom) (m3 monom) (m4 monom))
178 "Returns T if monomial MONOM-LCM(M1,M2) divides MONOM-LCM(M3,M4), NIL otherwise."
179 (declare (type monom m1 m2 m3 m4))
180 (every #'(lambda (x y z w) (<= (max x y) (max z w)))
181 m1 m2 m3 m4))
182
183(defmethod r-lcm-equal-lcm-p (m1 m2 m3 m4)
184 "Returns T if monomial LCM(M1,M2) equals LCM(M3,M4), NIL otherwise."
185 (with-slots ((exponents1 exponents))
186 m1
187 (with-slots ((exponents2 exponents))
188 m2
189 (with-slots ((exponents3 exponents))
190 m3
191 (with-slots ((exponents4 exponents))
192 m4
193 (every
194 #'(lambda (x y z w) (= (max x y) (max z w)))
195 exponents1 exponents2 exponents3 exponents4))))))
196
197(defmethod r-divisible-by-p ((m1 monom) (m2 monom))
198 "Returns T if monomial M1 is divisible by monomial M2, NIL otherwise."
199 (with-slots ((exponents1 exponents))
200 m1
201 (with-slots ((exponents2 exponents))
202 m2
203 (every #'>= exponents1 exponents2))))
204
205(defmethod r-rel-prime-p ((m1 monom) (m2 monom))
206 "Returns T if two monomials M1 and M2 are relatively prime (disjoint)."
207 (with-slots ((exponents1 exponents))
208 m1
209 (with-slots ((exponents2 exponents))
210 m2
211 (every #'(lambda (x y) (zerop (min x y))) exponents1 exponents2))))
212
213
214(defmethod r-equalp ((m1 monom) (m2 monom))
215 "Returns T if two monomials M1 and M2 are equal."
216 (monom-equalp m1 m2))
217
218(defmethod r-lcm ((m1 monom) (m2 monom))
219 "Returns least common multiple of monomials M1 and M2."
220 (with-slots ((exponents1 exponents) (dimension1 dimension))
221 m1
222 (with-slots ((exponents2 exponents))
223 m2
224 (let* ((exponents (copy-seq exponents1))
225 (dimension dimension1))
226 (map-into exponents #'max exponents1 exponents2)
227 (make-instance 'monom :dimension dimension :exponents exponents)))))
228
229
230(defmethod r-gcd ((m1 monom) (m2 monom))
231 "Returns greatest common divisor of monomials M1 and M2."
232 (with-slots ((exponents1 exponents) (dimension1 dimension))
233 m1
234 (with-slots ((exponents2 exponents))
235 m2
236 (let* ((exponents (copy-seq exponents1))
237 (dimension dimension1))
238 (map-into exponents #'min exponents1 exponents2)
239 (make-instance 'monom :dimension dimension :exponents exponents)))))
240
241(defmethod r-depends-p ((m monom) k)
242 "Return T if the monomial M depends on variable number K."
243 (declare (type fixnum k))
244 (with-slots (exponents)
245 m
246 (plusp (elt exponents k))))
247
248(defmethod r-tensor-product ((m1 monom) (m2 monom))
249 (with-slots ((exponents1 exponents) (dimension1 dimension))
250 m1
251 (with-slots ((exponents2 exponents) (dimension2 dimension))
252 m2
253 (make-instance 'monom
254 :dimension (+ dimension1 dimension2)
255 :exponents (concatenate 'vector exponents1 exponents2)))))
256
257(defmethod r-contract ((m monom) k)
258 "Drop the first K variables in monomial M."
259 (declare (fixnum k))
260 (with-slots (dimension exponents)
261 m
262 (setf dimension (- dimension k)
263 exponents (subseq exponents k))))
264
265(defun make-monom-variable (nvars pos &optional (power 1)
266 &aux (m (make-instance 'monom :dimension nvars)))
267 "Construct a monomial in the polynomial ring
268RING[X[0],X[1],X[2],...X[NVARS-1]] over the (unspecified) ring RING
269which represents a single variable. It assumes number of variables
270NVARS and the variable is at position POS. Optionally, the variable
271may appear raised to power POWER. "
272 (declare (type fixnum nvars pos power) (type monom m))
273 (with-slots (exponents)
274 m
275 (setf (elt exponents pos) power)
276 m))
277
278(defmethod r->list ((m monom))
279 "A human-readable representation of a monomial M as a list of exponents."
280 (coerce (r-exponents m) 'list))
Note: See TracBrowser for help on using the repository browser.