This file is indexed.

/usr/share/maxima/5.32.1/src/ratmac.lisp is in maxima-src 5.32.1-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
;;; -*-  Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;     The data in this file contains enhancments.                    ;;;;;
;;;                                                                    ;;;;;
;;;  Copyright (c) 1984,1987 by William Schelter,University of Texas   ;;;;;
;;;     All rights reserved                                            ;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;     (c) Copyright 1980 Massachusetts Institute of Technology         ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(in-package :maxima)

(macsyma-module ratmac macro)

;; Polynomials
;; ===========
;;
;; A polynomial in a single variable is stored as a sparse list of coefficients,
;; whose first element is the polynomial's variable. The rest of the elements
;; form a plist with keys the powers (in descending order) and values the
;; coefficients.
;;
;; For example, 42*x^2 + 1 might be stored as ($x 2 42 0 1). If, say,
;; x*sin(x)+x^2 is respresented as a polynomial in x, we might expect it to come
;; out as something like
;;
;;    ($x 2 1 1 ((%sin) $x)),
;;
;; but to make it easier to work with polynomials we don't allow arbitrary
;; conses as coefficients. What actually happens is that the expression is
;; thought of as a polynomial in two variables x and "sin(x)". More on that
;; below.
;;
;; Multivariate polynomials are stored in basically the same way as single
;; variable polynomials, using the observation that a polynomial in X and Y with
;; coefficients in K is the same as a polynomial in X with coefficients in K[Y].
;;
;; Specifically, the coefficient terms can be polynomials themselves (in other
;; variables). So x^2 + x*y could be rperesented as (($x 2 1 1 ($y 1 1))) or
;; alternatively as (($y 1 ($x 1 1) 0 ($x 2 1))), depending on whether x or y
;; was taken as the primary variable. If you add together two polynomials in
;; different variables (say x+1 and y+2) in the rational function code, then it
;; decides on the main variable using POINTERGP. This only works if the
;; variables have already been given a numbering by the rest of the rational
;; function code.
;;
;; In the x*sin(x) + x^2 example above, the expression can be represented as
;; something like ($x 2 1 1 (sinx 1 1)). When passed around as expressions
;; outside of the core rational function code, polynomials come with some header
;; information that explains what the variables are. In this case, it would be
;; responsible for remembering that "sinx" means sin(x).
;;
;; As a slightly special case, a polynomial can also be an atom, in which case
;; it is treated as a degree zero polynomial in no particular variable. Test for
;; this using the pcoefp macro defined below.
;;
;; There are accessor macros for the parts of a polynomial defined below: p-var,
;; p-terms, p-lc, p-le and p-red (which extract the primary variable, the list
;; of powers and coefficients, the leading coefficient, the leading exponent and
;; the list of powers and coefficients except the leading coefficient,
;; respectively).
;;
;; Rational expressions
;; ====================
;;
;; A rational expression is just a quotient of two polynomials p/q and, as such,
;; is stored as a cons pair (p . q), where p and q are in the format described
;; above. Since bare coefficients are allowed as polynomials, we can represent
;; zero as (0 . 1), which literally means 0/1.
;;
;; These format are also documented in the "Introduction to Polynomials" page of
;; the manual.

;; PCOEFP
;;
;; Returns true if E (which is hopefully a polynomial expression) should be
;; thought of as a bare coefficient.
(defmacro pcoefp (e) `(atom ,e))

;; PZEROP
;;
;; Return true iff the polynomial X is syntactically the zero polynomial. This
;; only happens when the polynomial is a bare coefficient and that coefficient
;; is zero.
(declaim (inline pzerop))
(defun pzerop (x)
  (cond
    ((fixnump x) (zerop x))
    ((consp x) nil)
    ((floatp x) (zerop x))))

;; PZERO
;;
;; A simple macro that evaluates to the zero polynomial.
(defmacro pzero () 0)

;; PTZEROP
;;
;; TERMS should be a list of terms of a polynomial. Returns T if that list is
;; empty, so the polynomial has no terms.
(defmacro ptzerop (terms) `(null ,terms))

;; PTZERO
;;
;; A simple macro that evaluates to an empty list of polynomial terms,
;; representing the zero polynomial.
(defmacro ptzero () '())

;; CMINUS
;;
;; Return the negation of a coefficient, which had better be numeric.
(defmacro cminus (c) `(- ,c))

;; CMINUSP
;;
;; Return T if the coefficient C is negative. Only works if C is a real number.
(defmacro cminusp (c) `(minusp ,c))


;; VALGET
;;
;; Retrieve a stored value from the given symbol, stored by VALPUT. This is used
;; in the rational function code, which uses it to store information on gensyms
;; that represent variables.
;;
;; Historical note from 2000 (presumably wfs):
;;
;;   The PDP-10 implementation used to use the PRINTNAME of the gensym as a
;;   place to store a VALUE. Somebody changed this to value-cell instead, even
;;   though using the value-cell costs more. Anyway, in NIL I want it to use the
;;   property list, as thats a lot cheaper than creating a value cell. Actually,
;;   better to use the PACKAGE slot, a kludge is a kludge right?
(defmacro valget (item)
  `(symbol-value ,item))

;; VALPUT
;;
;; Store a value on the given symbol, which can be later retrieved by
;; valget. This is used by the rational function code.
(defmacro valput (item val)
  `(setf (symbol-value ,item) ,val))

;; POINTERGP
;;
;; Test whether one symbol should occur before another in a canonical ordering.
;;
;; A historical note from Richard Fateman, on the maxima list, 2006/03/17:
;;
;;   "The name pointergp comes from the original hack when we wanted a bunch of
;;   atoms that could be ordered fast, we just generated, say, 10 gensyms.  Then
;;   we sorted them by the addresses of the symbols in memory.  Then we
;;   associated them with x,y,z,....  This meant that pointergp was one or two
;;   instructions on a PDP-10, in assembler."
;;
;;   "That version of pointergp turned out to be more trouble than it was worth
;;   because we sometimes had to interpolate between two gensym "addresses" and
;;   to do that we had to kind of renumber too much of the universe.  Or maybe
;;   we just weren't clever enough to do it without introducing bugs."
;;
;; Richard Fateman also says pointergp needs to be fast because it's called a
;; lot.  So if you get an error from pointergp, it's probably because someone
;; forgot to initialize things correctly.
(declaim (inline pointergp))
(defun pointergp (a b)
  (> (symbol-value a) (symbol-value b)))

;; ALGV
;;
;; V should be a symbol. If V has an "algebraic value" (stored in the TELLRAT
;; property) then return it, provided that the $ALGEBRAIC flag is
;; true. Otherwise, return NIL.
(defmacro algv (v)
  `(and $algebraic (get ,v 'tellrat)))

;; RZERO
;;
;; Expands to the zero rational expression (literally 0/1)
(defmacro rzero () ''(0 . 1))

;; RZEROP
;;
;; Test whether a rational expression is zero. A quotient p/q is zero iff p is
;; zero.
(defmacro rzerop (a) `(pzerop (car ,a)))

;; PRIMPART
;;
;; Calculate the primitive part of a polynomial. This is the polynomial divided
;; through by the greatest common divisor of its coefficients.
(defmacro primpart (p) `(second (oldcontent ,p)))

;; MAKE-POLY
;;
;; A convenience macro for constructing polynomials. VAR is the main variable
;; and should be a symbol. With no other arguments, it constructs the polynomial
;; representing the linear polynomial "VAR".
;;
;; A single optional argument is taken to be a coefficient list and, if the list
;; is known at compile time, some tidying up is done with PSIMP.
;;
;; With two optional arguments, they are taken to be an exponent/coefficient
;; pair. So (make-poly 'x 3 2) represents 2*x^3.
;;
;; With all three optional arguments, the first two are interpreted as above,
;; but this coefficient is prepended to an existing list of terms passed in the
;; third argument.
;;
;; Note: Polynomials are normally assumed to have terms listed in descending
;;       order of exponent. MAKE-POLY does not ensure this, so
;;       (make-poly 'x 1 2 '(2 1)) results in '(x 1 2 2 1), for example.
(defmacro make-poly (var &optional (terms-or-e nil options?) (c nil e-c?) (terms nil terms?))
  (cond ((null options?) `(cons ,var '(1 1)))
	((null e-c?) `(psimp ,var ,terms-or-e))
	((null terms?) `(list ,var ,terms-or-e ,c))
	(t `(psimp ,var (list* ,terms-or-e ,c ,terms)))))

;; P-VAR
;;
;; Extract the main variable from the polynomial P. Note: this does not work for
;; a bare coefficient.
(defmacro p-var (p) `(car ,p))

;; P-TERMS
;;
;; Extract the list of terms from the polynomial P. Note: this does not work for
;; a bare coefficient.
(defmacro p-terms (p) `(cdr ,p))

;; P-LC
;;
;; Extract the leading coefficient of the polynomial P. Note: this does not work for
;; a bare coefficient.
(defmacro p-lc (p) `(caddr ,p))

;; P-LE
;;
;; Extract the leading exponent or degree of the polynomial P. Note: this does
;; not work for a bare coefficient.
(defmacro p-le (p) `(cadr ,p))

;; P-RED
;;
;; Extract the terms of the polynomial P, save the leading term.
(defmacro p-red (p) `(cdddr ,p))

;; PT-LC
;;
;; Extract the leading coefficient from TERMS, a list of polynomial terms.
(defmacro pt-lc (terms) `(cadr ,terms))

;; PT-LE
;;
;; Extract the leading exponent (or degree) from TERMS, a list of polynomial
;; terms.
(defmacro pt-le (terms) `(car ,terms))

;; PT-RED
;;
;; Return all but the leading term of TERMS, a list of polynomial terms.
(defmacro pt-red (terms) `(cddr ,terms))

;; R+
;;
;; Sum one or more rational expressions with RATPL
(defmacro r+ (r . l)
  (cond ((null l) r)
	(t `(ratpl ,r (r+ ,@l)))))

;; R*
;;
;; Take the product of one or more rational expressions with RATTI.
(defmacro r* (r . l)
  (cond ((null l) r)
	(t `(ratti ,r (r* ,@l) t))))

;; R-
;;
;; Subtract the sum of the second and following rational expressions from the
;; first, using RATDIF.
(defmacro r- (r . l)
  (cond ((null l) `(ratminus (ratfix ,r)))
	(t `(ratdif (ratfix ,r) (r+ ,@l)))))