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/ngrobner.lisp@ 456

Last change on this file since 456 was 443, checked in by Marek Rychlik, 10 years ago
File size: 7.8 KB
Line 
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(in-package :ngrobner)
23
24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25;;
26;; Global switches
27;;
28;; Can be used in Maxima just fine, as they observe the
29;; Maxima naming convention, i.e. all names visible at the
30;; Maxima toplevel begin with a '$'.
31;;
32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
33
34(defvar $poly_monomial_order '$lex
35 "This switch controls which monomial order is used in polynomial
36and Grobner basis calculations. If not set, LEX will be used")
37
38(defvar $poly_coefficient_ring '$expression_ring
39 "This switch indicates the coefficient ring of the polynomials
40that will be used in grobner calculations. If not set, Maxima's
41general expression ring will be used. This variable may be set
42to RING_OF_INTEGERS if desired.")
43
44(defvar $poly_primary_elimination_order nil
45 "Name of the default order for eliminated variables in elimination-based functions.
46If not set, LEX will be used.")
47
48(defvar $poly_secondary_elimination_order nil
49 "Name of the default order for kept variables in elimination-based functions.
50If not set, LEX will be used.")
51
52(defvar $poly_elimination_order nil
53 "Name of the default elimination order used in elimination calculations.
54If set, it overrides the settings in variables POLY_PRIMARY_ELIMINATION_ORDER
55and SECONDARY_ELIMINATION_ORDER. The user must ensure that this is a true
56elimination order valid for the number of eliminated variables.")
57
58(defvar $poly_return_term_list nil
59 "If set to T, all functions in this package will return each polynomial as a
60list of terms in the current monomial order rather than a Maxima general expression.")
61
62(defvar $poly_grobner_debug nil
63 "If set to TRUE, produce debugging and tracing output.")
64
65(defvar $poly_grobner_algorithm '$buchberger
66 "The name of the algorithm used to find grobner bases.")
67
68(defvar $poly_top_reduction_only nil
69 "If not FALSE, use top reduction only whenever possible.
70Top reduction means that division algorithm stops after the first reduction.")
71
72
73(defvar *ratdisrep-fun* #'identity
74 "A function applied to polynomials after conversion to Maxima representation.")
75
76
77
78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
79;;
80;; This is how we perform operations on coefficients
81;; using Maxima functions.
82;;
83;; Functions and macros dealing with internal representation structure
84;;
85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
86
87
88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
89;;
90;; Debugging/tracing
91;;
92;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
93(defmacro debug-cgb (&rest args)
94 `(when $poly_grobner_debug (format *terminal-io* ,@args)))
95
96
97
98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
99;;
100;; These are provided mostly for debugging purposes To enable
101;; verification of grobner bases with BUCHBERGER-CRITERION, do
102;; (pushnew :grobner-check *features*) and compile/load this file.
103;; With this feature, the calculations will slow down CONSIDERABLY.
104;;
105;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
106
107(defun grobner-test (ring g f)
108 "Test whether G is a Grobner basis and F is contained in G. Return T
109upon success and NIL otherwise."
110 (debug-cgb "~&GROBNER CHECK: ")
111 (let (($poly_grobner_debug nil)
112 (stat1 (buchberger-criterion ring g))
113 (stat2
114 (every #'poly-zerop
115 (makelist (normal-form ring (copy-tree (elt f i)) g nil)
116 (i 0 (1- (length f)))))))
117 (unless stat1 (error "~&Buchberger criterion failed."))
118 (unless stat2
119 (error "~&Original polys not in ideal spanned by Grobner.")))
120 (debug-cgb "~&GROBNER CHECK END")
121 t)
122
123
124;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
125;;
126;; Selection of algorithm and pair heuristic
127;;
128;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
129
130(defun find-grobner-function (algorithm)
131 "Return a function which calculates Grobner basis, based on its
132names. Names currently used are either Lisp symbols, Maxima symbols or
133keywords."
134 (ecase algorithm
135 ((buchberger :buchberger $buchberger) #'buchberger)
136 ((parallel-buchberger :parallel-buchberger $parallel_buchberger) #'parallel-buchberger)
137 ((gebauer-moeller :gebauer_moeller $gebauer_moeller) #'gebauer-moeller)))
138
139(defun grobner (ring f &optional (start 0) (top-reduction-only nil))
140 ;;(setf F (sort F #'< :key #'sugar))
141 (funcall
142 (find-grobner-function $poly_grobner_algorithm)
143 ring f start top-reduction-only))
144
145(defun reduced-grobner (ring f &optional (start 0) (top-reduction-only $poly_top_reduction_only))
146 (reduction ring (grobner ring f start top-reduction-only)))
147
148;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
149;;
150;; Conversion from internal to infix form
151;;
152;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
153
154(defun coerce-to-infix (poly-type object vars)
155 (case poly-type
156 (:termlist
157 `(+ ,@(mapcar #'(lambda (term) (coerce-to-infix :term term vars)) object)))
158 (:polynomial
159 (coerce-to-infix :termlist (poly-termlist object) vars))
160 (:poly-list
161 `([ ,@(mapcar #'(lambda (p) (coerce-to-infix :polynomial p vars)) object)))
162 (:term
163 `(* ,(term-coeff object)
164 ,@(mapcar #'(lambda (var power) `(expt ,var ,power))
165 vars (monom-exponents (term-monom object)))))
166 (otherwise
167 object)))
168
169
170;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
171;;
172;; Order utilities
173;;
174;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
175
176(defun find-order (order)
177 "This function returns the order function bases on its name."
178 (cond
179 ((null order) nil)
180 ((symbolp order)
181 (case order
182 ((lex :lex $lex) #'lex>)
183 ((grlex :grlex $grlex) #'grlex>)
184 ((grevlex :grevlex $grevlex) #'grevlex>)
185 ((invlex :invlex $invlex) #'invlex>)
186 ((elimination-order-1 :elimination-order-1 elimination_order_1) #'elimination-order-1)
187 (otherwise
188 (warn "~%Warning: Order ~A not found. Using default.~%" order))))
189 (t
190 (warn "~%Order specification ~A is not recognized. Using default.~%" order)
191 nil)))
192
193;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
194;;
195;; Ring utilities
196;;
197;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
198
199(defun find-ring (ring)
200 "This function returns the ring structure bases on input symbol."
201 (cond
202 ((null ring) nil)
203 ((symbolp ring)
204 (case ring
205 ((expression-ring :expression-ring $expression_ring) *expression-ring*)
206 ((ring-of-integers :ring-of-integers $ring_of_integers) *ring-of-integers*)
207 (otherwise
208 (warn "~%Warning: Ring ~A not found. Using default.~%" ring))))
209 (t
210 (warn "~%Ring specification ~A is not recognized. Using default.~%" ring)
211 nil)))
Note: See TracBrowser for help on using the repository browser.