close Warning:

source: branches/f4grobner/.junk/poly-eval.lisp@ 1059

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

* empty log message *

  • Property svn:mime-type set to application/x-elc
File size: 4.9 KB
RevLine 
1(defun convert-number (number-or-poly n)
2 "Returns NUMBER-OR-POLY, if it is a polynomial. If it is a number,
3it converts it to the constant monomial in N variables. If the result
4is a number then convert it to a polynomial in N variables."
5 (if (numberp number-or-poly)
6 (make-poly-from-termlist (list (make-term (make-monom :dimension n) number-or-poly)))
7 number-or-poly))
8
9(defun $poly+ (ring-and-order p q n)
10 "Add two polynomials P and Q, where each polynomial is either a
11numeric constant or a polynomial in internal representation. If the
12result is a number then convert it to a polynomial in N variables."
13 (poly-add ring-and-order (convert-number p n) (convert-number q n)))
14
15(defun $poly- (ring-and-order p q n)
16 "Subtract two polynomials P and Q, where each polynomial is either a
17numeric constant or a polynomial in internal representation. If the
18result is a number then convert it to a polynomial in N variables."
19 (poly-sub ring-and-order (convert-number p n) (convert-number q n)))
20
21(defun $minus-poly (ring p n)
22 "Negation of P is a polynomial is either a numeric constant or a
23polynomial in internal representation. If the result is a number then
24convert it to a polynomial in N variables."
25 (poly-uminus ring (convert-number p n)))
26
27(defun $poly* (ring-and-order p q n)
28 "Multiply two polynomials P and Q, where each polynomial is either a
29numeric constant or a polynomial in internal representation. If the
30result is a number then convert it to a polynomial in N variables."
31 (poly-mul ring-and-order (convert-number p n) (convert-number q n)))
32
33(defun $poly/ (ring p q)
34 "Divide a polynomials P which is either a numeric constant or a
35polynomial in internal representation, by a number Q."
36 (if (numberp p)
37 (common-lisp:/ p q)
38 (scalar-times-poly ring (common-lisp:/ q) p)))
39
40(defun $poly-expt (ring-and-order p l n)
41 "Raise polynomial P, which is a polynomial in internal
42representation or a numeric constant, to power L. If P is a number,
43convert the result to a polynomial in N variables."
44 (poly-expt ring-and-order (convert-number p n) l))
45
46
47(defun variable-basis (ring n &aux (basis (make-list n)))
48 "Generate a list of polynomials X[i], i=0,1,...,N-1."
49 (dotimes (i n basis)
50 (setf (elt basis i) (make-variable ring n i))))
51
52
53(defun poly-eval-1 (expr vars &optional (ring *ring-of-integers*) (order #'lex>)
54 &aux
55 (ring-and-order (make-ring-and-order :ring ring :order order))
56 (n (length vars))
57 (basis (variable-basis ring (length vars))))
58 "Evaluate an expression EXPR as polynomial by substituting operators
59+ - * expt with corresponding polynomial operators and variables VARS
60with the corresponding polynomials in internal form. We use special
61versions of binary operators $poly+, $poly-, $minus-poly, $poly* and
62$poly-expt which work like the corresponding functions in the POLY
63package, but accept scalars as arguments as well. The result is a
64polynomial in internal form. This operation is somewhat similar to
65the function EXPAND in CAS."
66 (cond
67 ((numberp expr)
68 (cond
69 ((zerop expr) NIL)
70 (t (make-poly-from-termlist (list (make-term (make-monom :dimension n) expr))))))
71 ((symbolp expr)
72 (nth (position expr vars) basis))
73 ((consp expr)
74 (case (car expr)
75 (expt
76 (if (= (length expr) 3)
77 ($poly-expt ring-and-order
78 (poly-eval-1 (cadr expr) vars ring order)
79 (caddr expr)
80 n)
81 (error "Too many arguments to EXPT")))
82 (/
83 (if (and (= (length expr) 3)
84 (numberp (caddr expr)))
85 ($poly/ ring (cadr expr) (caddr expr))
86 (error "The second argument to / must be a number")))
87 (otherwise
88 (let ((r (mapcar
89 #'(lambda (e) (poly-eval-1 e vars ring order))
90 (cdr expr))))
91 (ecase (car expr)
92 (+ (reduce #'(lambda (p q) ($poly+ ring-and-order p q n)) r))
93 (-
94 (if (endp (cdr r))
95 ($minus-poly ring (car r) n)
96 ($poly- ring-and-order
97 (car r)
98 (reduce #'(lambda (p q) ($poly+ ring-and-order p q n)) (cdr r))
99 n)))
100 (*
101 (reduce #'(lambda (p q) ($poly* ring-and-order p q n)) r))
102 )))))))
103
104
105
106(defun poly-eval (expr vars &optional (order #'lex>) (ring *ring-of-integers*))
107 "Evaluate an expression EXPR, which should be a polynomial
108expression or a list of polynomial expressions (a list of expressions
109marked by prepending keyword :[ to it) given in Lisp prefix notation,
110in variables VARS, which should be a list of symbols. The result of
111the evaluation is a polynomial or a list of polynomials (marked by
112prepending symbol '[) in the internal alist form. This evaluator is
113used by the PARSE package to convert input from strings directly to
114internal form."
115 (cond
116 ((numberp expr)
117 (unless (zerop expr)
118 (make-poly-from-termlist
119 (list (make-term (make-monom :dimension (length vars)) expr)))))
120 ((or (symbolp expr) (not (eq (car expr) :[)))
121 (poly-eval-1 expr vars ring order))
122 (t (cons '[ (mapcar #'(lambda (p) (poly-eval-1 p vars ring order)) (rest expr))))))
123
124
Note: See TracBrowser for help on using the repository browser.