1 ;;; -*- Mode: Lisp; Package: Macsyma -*- ;;;
2 ;;; (c) Copyright 1984 the Regents of the University of California. ;;;
3 ;;; All Rights Reserved. ;;;
4 ;;; This work was produced under the sponsorship of the ;;;
5 ;;; U.S. Department of Energy. The Government retains ;;;
6 ;;; certain rights therein. ;;;
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9 (macsyma-module scifac
)
11 (declaim (special $negdistrib
))
13 (defmacro make-expt
(base exponent
) ``((mexpt simp
) ,,base
,,exponent
))
15 (defmacro acceptable-power
(x)
16 `(and (alike1 (cadr ,x
) var
)
17 (setq minpow
(cond (nstate (and (integerp expon
) (min minpow expon
)))
18 (number (and ($numberp expon
)
19 (integerp (sub minpow expon
))
20 (mfuncall '$min minpow expon
)))
22 (let ((powdif (sub minpow expon
)))
23 (cond ((integerp powdif
)
24 (cond ((> powdif
0) expon
)
27 (let ((g ($gcd minpow expon
)))
28 (let ((d1 ($ratsimp
(div minpow g
)))
29 (d2 ($ratsimp
(div expon g
))))
32 (cond ((> d1 d2
) expon
)
35 (cond (number (mnegp expon
))
37 (equal -
1 (cadr expon
)))))
40 (defun factorout-monomial (exp)
42 (lead-term (cadr exp
))
44 (minuslogic (and (> (length exp
) 3)
45 (let ((minusobj (car (last exp
))))
46 (cond ((integerp minusobj
) (minusp minusobj
))
48 (and (integerp (cadr minusobj
))
49 (minusp (cadr minusobj
)))))))))
50 (do ((rem-prod (cond ((or ($mapatom lead-term
)
51 (eq (caar lead-term
) 'mexpt
))
53 ((eq (caar lead-term
) 'mtimes
)
58 (follow lead-term rem-prod
)
61 (cond ((null monomials
) exp
)
64 (muln `(,.monomials
,(addn (cdr exp
) nil
)) nil
)))))
65 (let ((potentl-mon (car rem-prod
)) (truth) (leadfix))
66 (cond ((or (setq leadfix
(integerp potentl-mon
)) minuslogic
)
67 (let ((intgcd (cond (leadfix potentl-mon
)
70 (rplaca (cdr exp
) `((mtimes simp
) 1 ,potentl-mon
))
71 (setq rem-prod
(cdadr exp
)
73 (t (rplacd follow
(append (ncons 1) rem-prod
))
74 (setq rem-prod
(cdr follow
))))))))
75 (single (list (and leadfix alone
))))
76 (do ((ge (cddr exp
) (cdr ge
))
77 (all-minus (minusp intgcd
)))
79 (and (or minuslogic all-minus
)
81 (setq intgcd
(- intgcd
)))
82 (setq minuslogic nil
))
85 (setq monomials
`(,@monomials
,intgcd
))
86 (do ((redu-const (cdr exp
) (cdr redu-const
))
87 (in-follow exp redu-const
)
88 (logic single
(cdr logic
)))
90 (let ((term1 (car redu-const
)))
91 (cond ((car logic
) (rplaca redu-const
(quotient term1 intgcd
)))
92 (t (cond ((equal 1 (car (rplaca (cdr term1
) (quotient (cadr term1
) intgcd
))))
93 (and (eq logic single
)
96 (rplacd term1
(cddr term1
))
98 (let ((pluscontac (cadr term1
)))
99 (cond ((mplusp pluscontac
)
100 (rplacd in-follow
(append (cdr pluscontac
) (cdr redu-const
)))
101 (setq redu-const
(nthcdr (1- (length pluscontac
)) in-follow
))
102 (and (eq logic single
)
103 (let ((new-lead (cadr exp
)))
104 (cond ((mtimesp new-lead
)
105 (setq rem-prod new-lead
))
107 rem-prod
`(nil ,new-lead
)))))))
108 (t (rplaca redu-const pluscontac
)
109 (and (eq logic single
)
110 (setq alone t
)))))))))))))))
111 (let ((leadnum (car ge
)))
112 (cond ((integerp leadnum
)
113 (setq single
`(,@single t
)
114 intgcd
(gcd intgcd leadnum
)
115 all-minus
(and all-minus
(minusp leadnum
))))
117 (let ((numb (cadr leadnum
)))
118 (cond ((integerp numb
)
119 (setq single
`(,@single nil
)
120 intgcd
(gcd intgcd numb
)
121 all-minus
(and all-minus
(minusp numb
))))
123 (setq single
`(,@single nil
)
125 (rplacd leadnum
(append (ncons 1) (cdr leadnum
))))
128 (setq single
`(,@single nil
)
130 (rplaca ge
`((mtimes simp
) 1 ,leadnum
)))
131 (t (return nil
)))))))
132 (t (or ($mapatom potentl-mon
)
133 (setq truth
(eq (caar potentl-mon
) 'mexpt
)))
134 (let ((power (list (cond (truth (caddr potentl-mon
))
136 (place (list (cond (alone -
1)
138 (var (cond (truth (cadr potentl-mon
))
140 (let* ((minpow (car power
)) (number ($numberp minpow
)))
141 (do ((ge (cddr exp
) (cdr ge
))
142 (expon-sign (and truth
143 (cond (number (mnegp minpow
))
145 (equal -
1 (cadr minpow
))))))
146 (nstate (integerp minpow
)))
148 (or number
(and expon-sign
149 (setq minpow
(mul -
1 minpow
))))
151 `(,.monomials
,(cond ((equal minpow
1) var
)
152 (t (make-expt (cadr potentl-mon
) minpow
)))))
153 (do ((deflate (cdr exp
) (cdr deflate
))
154 (d-follow exp deflate
)
156 (pow power
(cdr pow
)))
158 (let ((pownum (car pow
)) (plnum (car pl
)))
159 (cond ((minusp plnum
)
160 (cond ((cond (nstate (equal pownum minpow
))
161 (t (alike1 pownum minpow
)))
163 (t (cond ((cond (nstate (equal pownum
(1+ minpow
)))
164 (t (alike1 pownum
(add 1 minpow
))))
165 (rplaca deflate
(cadar deflate
)))
166 (t (rplaca (cddar deflate
) (cond (nstate (- pownum minpow
))
167 (t (sub pownum minpow
)))))))))
168 (t (let* ((term (car deflate
)) (point (nthcdr plnum term
)))
169 (cond ((cond (nstate (equal pownum minpow
))
170 (t (alike1 pownum minpow
)))
171 (rplacd (nthcdr (1- plnum
) term
) (cdr point
))
176 (let ((pluscontac (cadr term
)))
177 (cond ((mplusp pluscontac
)
178 (rplacd d-follow
(append (cdr pluscontac
) (cdr deflate
)))
179 (setq deflate
(nthcdr (1- (length pluscontac
)) d-follow
))
181 (let ((new-lead (cadr exp
)))
182 (cond ((mtimesp new-lead
)
183 (setq rem-prod new-lead
))
185 rem-prod
`(nil ,new-lead
)))))))
186 (t (rplaca deflate pluscontac
)
189 (t (cond ((cond (nstate (equal pownum
(1+ minpow
)))
190 (t (alike1 pownum
(add 1 minpow
))))
191 (rplaca point
(cadar point
)))
192 (t (rplaca (cddar point
) (cond (nstate (- pownum minpow
))
193 (t (sub pownum minpow
))))))))))))))
194 (let ((exam-term (car ge
)))
195 (cond (($mapatom exam-term
)
196 (cond ((and nstate
(alike1 exam-term var
))
197 (setq place
`(,@place -
1)
201 ((eq (caar exam-term
) 'mexpt
)
202 (let ((expon (caddr exam-term
)))
203 (cond ((acceptable-power exam-term
)
204 (setq place
`(,@place -
2)
205 power
`(,@power
,expon
)))
207 ((eq (caar exam-term
) 'mtimes
)
208 (cond ((do ((pick (cdr exam-term
) (cdr pick
))
211 (let ((morcel (car pick
)))
212 (cond (($mapatom morcel
)
215 (setq place
`(,@place
,k
)
219 ((eq (caar morcel
) 'mexpt
)
220 (let ((expon (caddr morcel
)))
221 (cond ((acceptable-power morcel
)
222 (setq place
`(,@place
,k
)
223 power
`(,@power
,expon
))
225 (t (cond ((and nstate
229 (setq place
`(,@place
,k
)
234 ((and nstate
(alike1 exam-term var
) (not expon-sign
))
235 (setq place
`(,@place -
1)
238 (t (return nil
)))))))))))))
241 (defun pair-factor (gel flag
)
242 (cond ((and flag
(or ($mapatom gel
) (null (cdddr gel
)))) gel
)
243 (t (do ((lcl (cdr gel
) (cdr lcl
))
245 ((null (cdr lcl
)) gel
)
246 (let* ((pntr (add (car lcl
) (cadr lcl
)))
247 (g (factorout-monomial pntr
)))
249 (progn (let ((again (more-subfactors-q g
)))
250 (or (eq again g
) (setq g again
)))
252 (let ((exp (cddr lcl
)))
255 (pair-factor backpnt nil
))
256 (return (cond ((null (cddr gel
)) (cadr gel
))
260 (defun more-subfactors-q (gg)
261 (cond ((eq (caar gg
) 'mtimes
)
262 (do ((lom (cdr gg
) (cdr lom
))
265 ((null lom
) (cond (modified (muln (cdr gg
) t
))
267 (let ((obj (car lom
)))
269 (let ((pntr (pair-factor obj t
)))
271 (let ((fit (cdr pntr
)))
272 (rplacd back
(append fit
(cdr lom
)))
273 (setq lom
(nthcdr (length fit
) back
)
275 (t (pair-factor gg t
))))
278 (defun gcfac-prodscan (x)
279 (do ((inlev (cdr x
) (cdr inlev
))
282 ((null inlev
) (cond (modified (muln (cdr x
) t
))
284 (let* ((possibl-sum (car inlev
))
285 (pntr (monomial-factor possibl-sum
)))
286 (or (eq pntr possibl-sum
)
287 (let ((fit (cdr pntr
)))
288 (rplacd backpnt
(append fit
(cdr inlev
)))
289 (setq inlev
(nthcdr (length fit
) backpnt
)
293 (defun monomial-factor (exp)
294 (cond (($mapatom exp
) exp
)
295 ((eq (caar exp
) 'mtimes
)
296 (gcfac-prodscan exp
))
297 ((eq (caar exp
) 'mplus
)
298 (do ((mlm (cdr exp
) (cdr mlm
)))
300 (let ((potenl-prod (car mlm
)))
301 (cond ((mtimesp potenl-prod
)
302 (let ((w (gcfac-prodscan potenl-prod
)))
303 (or (eq w potenl-prod
) (rplaca mlm w
))))
304 (t (monomial-factor potenl-prod
)))))
305 (more-subfactors-q (factorout-monomial exp
)))
306 (t (do ((mlm (cdr exp
) (cdr mlm
)))
308 (let* ((obj (car mlm
)) (res (monomial-factor obj
)))
309 (or (eq obj res
) (rplaca mlm res
)))))))
312 (cond (($mapatom x
) x
)
313 (t (monomial-factor (copy-tree ($totaldisrep x
))))))