descriptive.mac: declare local variable to avoid possibility of name collision.
[maxima.git] / src / mhayat.lisp
blob341c5db473aea20ef805d1b2b56983446ae96de1
1 ;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;;; The data in this file contains enhancements. ;;;;;
4 ;;; ;;;;;
5 ;;; Copyright (c) 1984,1987 by William Schelter,University of Texas ;;;;;
6 ;;; All rights reserved ;;;;;
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 ;;; (c) Copyright 1980 Massachusetts Institute of Technology ;;;
9 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11 (in-package :maxima)
13 (macsyma-module mhayat macro)
15 ;;; **************************************************************
16 ;;; ***** HAYAT ******* Finite Power Series Routines *************
17 ;;; **************************************************************
18 ;;; ** (c) Copyright 1980 Massachusetts Institute of Technology **
19 ;;; ****** This is a read-only file! (All writes reserved) *******
20 ;;; **************************************************************
22 ;;; Note: be sure to recompile this file if any modifications are made!
24 ;;; TOP LEVEL STRUCTURE
26 ;;; Power series have the following format when seen outside the power
27 ;;; series package:
28 ;;;
29 ;;; ((MRAT SIMP <varlist> <genvar> <tlist> trunc) <poly-form>)
30 ;;;
31 ;;; This is the form of the output of the expressions, to
32 ;;; be displayed they are RATDISREPed and passed to DISPLA.
34 ;;; The <poly-forms> consist of a header and list of exponent-coefficient
35 ;;; pairs as shown below. The PS is used to distinguish power series
36 ;;; from their coefficients which have a similar representation.
37 ;;;
38 ;;; (PS (<var> . <ord-num>) (<trunc-lvl>)
39 ;;; (<exponent> . <coeff>) (<exponent> . <coeff>) . . .)
40 ;;;
41 ;;; The <var> component of the power series is a gensym which represents the
42 ;;; kernel of the power series. If the package is called with the arguments:
43 ;;; Taylor(<expr>, x, a, n) then the kernel will be (x - a).
44 ;;; The <ord-num> is a relative ordering for the various kernels in a
45 ;;; multivariate expansion.
46 ;;; <trunc-lvl> is the highest degree of the variable <var> which is retained
47 ;;; in the current power series.
48 ;;; The terms in the list of exponent-coefficient pairs are ordered by
49 ;;; increasing degree.
51 (declare-top (special tlist ivars key-vars last-exp))
53 ;; subtitle hayat macros
55 (defmacro pszero (var pw)
56 (declare (ignore var pw))
57 ''(0 . 1)) ; until constants are fixed
59 (defmacro psp (e) `(eq (car ,e) 'ps))
61 (defmacro pscoefp (e) `(null (psp ,e)))
63 (defmacro psquo (ps1 &optional ps2)
64 (cond ((not ps2) `(psexpt ,ps1 (rcmone)))
65 (t `(pstimes ,ps1 (psexpt ,ps2 (rcmone))))))
67 (defmacro pslog-gvar (gvar)
68 `(pslog2 (get-inverse ,gvar)))
70 (defmacro gvar-o (e) `(cadr ,e))
72 (defmacro gvar (e) `(car (gvar-o ,e)))
74 (defmacro eqgvar (x y) `(eq (car ,x) (car ,y)))
76 (defmacro pointerp (x y) `(> (cdr ,x) (cdr ,y)))
78 (defmacro poly-data (p) `(caddr ,p))
80 (defmacro trunc-lvl (p) `(car (poly-data ,p)))
82 (defmacro terms (p) `(cdddr ,p))
84 (defmacro lt (terms) `(car ,terms))
86 (defmacro le (terms) `(caar ,terms))
88 (defmacro lc (terms) `(cdar ,terms))
90 (defmacro e (term) `(car ,term))
92 (defmacro c (term) `(cdr ,term))
94 (defmacro n-term (terms) `(cdr ,terms))
96 (defmacro mono-term? (terms) `(null (n-term ,terms)))
98 (defmacro nconc-terms (oldterms newterms) `(nconc ,oldterms ,newterms))
100 (defmacro term (e c) `(cons ,e ,c))
102 (defmacro make-ps (var-or-data-poly pdata-or-terms
103 &optional (terms () var-pdata-case?))
104 (if var-pdata-case?
105 `(cons 'ps (cons ,var-or-data-poly (cons ,pdata-or-terms ,terms)))
106 `(cons 'ps (cons (gvar-o ,var-or-data-poly)
107 (cons (poly-data ,var-or-data-poly)
108 ,pdata-or-terms)))))
110 ;; Be sure that PS has more than one term when deleting the first with del-lt
112 (defmacro del-lt (ps) `(rplacd (cddr ,ps) (cddddr ,ps)))
114 (defmacro add-term (terms &optional (term-or-e nil adding?) (c nil e-c?))
115 (cond ((null adding?) `(rplacd ,terms nil))
116 ((null e-c?)
117 `(rplacd ,terms (cons ,term-or-e (cdr ,terms))))
118 (`(rplacd ,terms (cons (cons ,term-or-e ,c) (cdr ,terms))))))
120 (defmacro add-term-&-pop (terms &rest args)
121 `(progn (add-term ,terms . ,args) (setq ,terms (n-term ,terms))))
123 ;; Keep both def'ns around until a new hayat is stable.
125 (defmacro change-coef (terms coef) `(rplacd (lt ,terms) ,coef))
127 (defmacro change-lc (terms coef) `(rplacd (lt ,terms) ,coef))
129 (defmacro getdisrep (var) `(get (car ,var) 'disrep))
131 (defmacro getdiff (var) `(get (car ,var) 'diff))
133 (defmacro lt-poly (p)
134 `(make-ps (gvar-o ,p) (poly-data ,p)
135 (list (lt (terms ,p)))))
137 (defmacro oper-name (func) `(if (atom ,func) ,func (caar ,func)))
139 (defmacro oper-namep (oper-form) `(atom ,oper-form))
141 (defmacro integer-subscriptp (subscr-fun)
142 `(apply 'and (mapcar #'integerp (cdr ,subscr-fun))))
144 (defmacro mlet (varl vals comp)
145 `(mbinding (,varl ,vals) ,comp))
148 ;;; these macros access "tlist" to get various global information
149 ;;; "tlist" is structured as a list of datums, each datum having
150 ;;; following form:
152 ;;; (<var> <trunc-lvl stack> <pt of expansion>
153 ;;; <list of switches> <internal var = gvar> . <ord-num>)
155 ;;; possible switches are:
156 ;;; $asymp = t asymptotic expansion
157 ;;; multi variable in a multivariate expansion
158 ;;; multivar the actual variable of expansion in a multi-
159 ;;; variate expansion
162 ;;; macros for external people to access the tlist
164 ;;; ((MRAT SIMP <varlist> <genvar> <tlist> trunc) <poly-form>)
166 (defmacro mrat-header (mrat) `(car ,mrat))
167 (defmacro mrat-varlist (mrat) `(third (mrat-header ,mrat)))
168 (defmacro mrat-genvar (mrat) `(fourth (mrat-header ,mrat)))
169 (defmacro mrat-tlist (mrat) `(fifth (mrat-header ,mrat)))
170 (defmacro mrat-ps (mrat) `(cdr ,mrat))
172 ;;; The following two macros are now functions.
174 ;; (defmacro push-pw (datum pw)
175 ;; `(rplaca (cdr ,datum) (cons ,pw (cadr ,datum))))
177 ;; (defmacro pop-pw (datum)
178 ;; `(rplaca (cdr ,datum) (cdadr ,datum)))
180 (defmacro datum-var (datum) `(car ,datum))
182 (defmacro trunc-stack (datum) `(cadr ,datum))
184 (defmacro current-trunc (datum) `(car (trunc-stack ,datum)))
186 (defmacro orig-trunc (datum) `(car (last (trunc-stack ,datum))))
188 (defmacro exp-pt (datum) `(caddr ,datum))
190 (defmacro switches (datum) `(cadddr ,datum))
192 (defmacro switch (sw datum)
193 `(cdr (assoc ,sw (switches ,datum) :test #'eq)))
195 (defmacro int-var (datum) `(cddddr ,datum))
197 (defmacro data-gvar-o (data) `(cddddr ,data))
199 (defmacro int-gvar (datum) `(car (int-var ,datum)))
201 (defmacro data-gvar (data) `(car (data-gvar-o ,data)))
203 (defmacro get-inverse (gensym)
204 `(cdr (assoc ,gensym ivars :test #'eq)))
206 (defmacro get-key-var (gensym)
207 `(cdr (assoc ,gensym key-vars :test #'eq)))
209 (defmacro gvar->var (gvar)
210 `(cdr (assoc ,gvar key-vars :test #'eq)))
212 (defmacro dummy-var () '(cdar key-vars))
214 (defmacro first-datum () '(car tlist))
216 (defmacro get-datum (expr &optional not-canonicalized?)
217 (if not-canonicalized?
218 `(assol ,expr tlist)
219 `(assoc ,expr tlist :test #'equal)))
221 (defmacro var-data (var)
222 `(assoc ,var tlist :test #'equal))
224 (defmacro gvar-data (gvar) `(var-data (gvar->var ,gvar)))
226 (defmacro ps-data (ps) `(gvar-data (gvar ,ps)))
228 (defmacro t-o-var (gensym) `(current-trunc (get-datum (get-key-var ,gensym))))
230 (defmacro gvar-trunc (gvar) `(current-trunc (gvar-data ,gvar)))
232 (defmacro ps-arg-trunc (ps) `(gvar-trunc (gvar ,ps)))
234 (defmacro ps-le (ps) `(le (terms ,ps)))
236 (defmacro ps-le* (ps) `(if (psp ,ps) (ps-le ,ps) '(0 . 1)))
238 (defmacro ps-lc (ps) `(lc (terms ,ps)))
240 (defmacro ps-lc* (ps) `(if (psp ,ps) (ps-lc ,ps) ,ps))
242 (defmacro ps-lt (ps) `(lt (terms ,ps)))
244 (defmacro getexp-le (fun) `(car (getexp-lt ,fun)))
246 (defmacro getexp-lc (fun) `(cdr (getexp-lt ,fun)))
248 (defmacro let-pw (datum pw comp)
249 `(let ((d ,datum))
250 (prog2 (push-pw d ,pw)
251 ,comp
252 (pop-pw d))))
254 (defmacro tlist-mapc (datum-var &rest comp)
255 `(mapc #'(lambda (,datum-var) . ,comp) tlist))
257 (defmacro find-lexp (exp &optional e-start errflag accum-vars)
258 `(get-lexp ,exp ,e-start ,errflag ,(and accum-vars '(ncons t))))
260 (defmacro tay-err (msg) `(throw 'tay-err (list ,msg last-exp)))
262 (defmacro zero-warn (exp)
263 `(mtell (intl:gettext "taylor: assumed to be zero: ~M~%")
264 `((mlabel) () ,,exp)))
266 ;;There is a duplicate version of this in MAXMAC
267 ;;(defmacro infinities () ''($inf $minf $infinity))
269 ;; Macros for manipulating expansion data in the expansion table.
271 (defmacro exp-datum-lt (fun exp-datum)
272 `(if (atom (cadr ,exp-datum))
273 (funcall (cadr ,exp-datum) (cdr ,fun))
274 (copy-tree (cadr ,exp-datum))))
276 (defmacro exp-datum-le (fun exp-datum) `(e (exp-datum-lt ,fun ,exp-datum)))
278 (defmacro exp-fun (exp-datum)
279 `(if (atom (car ,exp-datum)) (car ,exp-datum) (caar ,exp-datum)))
281 ;;; These macros are used to access the various extendable
282 ;;; portions of a polynomial.
284 (defmacro ext-fun (p) `(cadr (poly-data ,p)))
286 (defmacro ext-args (p) `(caddr (poly-data ,p)))
288 (defmacro extendablep (p)
289 `((lambda (d)
290 (or (null (car d))
291 (cdr d)))
292 (poly-data ,p)))
294 (defmacro exactp (p) `(null (trunc-lvl ,p)))
296 (defmacro nexactp (p) `(trunc-lvl ,p))
298 ;;; These macros are used to access user supplied information.
300 (defmacro get-ps-form (fun) `(get ,fun 'sp2))
302 (defmacro term-disrep (term p) `(m* (srdis (c ,term))
303 (m^ (get-inverse (gvar ,p))
304 (edisrep (e ,term)))))
307 ;; coefficient arithmetic
309 (defmacro rczero () ''(0 . 1))
311 (defmacro rcone () ''(1 . 1))
313 (defmacro rcfone () ''(1.0 . 1.0))
315 (defmacro rctwo () ''(2 . 1))
317 (defmacro rcmone () ''(-1 . 1))
319 (defmacro rczerop (r)
320 `(signp e (car ,r)))
322 (defmacro rcintegerp (c) `(and (integerp (car ,c)) (equal (cdr ,c) 1)))
324 (defmacro rcpintegerp (c)
325 `(and (rcintegerp ,c)
326 ;(signp g (car ,c))
327 ;What is this obsession with signp? Even in maclisp it's slower
328 ; and more code, since it doesn't assume the thing is a number.
329 ;The car is integerp, after all (as implied by rcintegerp).
330 (plusp (car ,c))))
332 (defmacro rcmintegerp (c)
333 `(and (rcintegerp ,c)
334 ;(signp l (car ,c))
335 ;Similar to above.
336 (minusp (car ,c))))
338 (defmacro rcplus (x y) `(ratplus ,x ,y))
340 (defmacro rcdiff (x y) `(ratdif ,x ,y))
342 (defmacro rcminus (x) `(ratminus ,x))
344 (defmacro rctimes (x y) `(rattimes ,x ,y t))
346 (defmacro rcquo (x y) `(ratquotient ,x ,y))
348 (defmacro rcdisrep (x) `(cdisrep ,x))
350 (defmacro rcderiv (x v) `(ratderivative ,x ,v))
352 (defmacro rcderivx (x) `(ratdx1 (car ,x) (cdr ,x)))
354 ;; exponent arithmetic
356 ;; These macros are also used in BMT;PADE and RAT;NALGFA.
358 (defmacro infp (x) `(null ,x))
360 (defmacro inf nil nil)
362 (defmacro e- (e1 &optional (e2 nil 2e?))
363 (cond (2e? `(ediff ,e1 ,e2))
364 (`(cons (f- (car ,e1)) (cdr ,e1)))))
366 (defmacro e// (e1 &optional (e2 nil 2e?))
367 (cond (2e? `(equo ,e1 ,e2))
368 (`(erecip ,e1))))
370 (defmacro e>= (e1 e2) `(or (e> ,e1 ,e2) (e= ,e1 ,e2)))
372 (defmacro ezero () ''(0 . 1))
374 (defmacro eone () ''(1 . 1))
376 (defmacro rcinv (r) `(ratinvert ,r))