Fix #4341: atan of complex bfloat calls rat
[maxima.git] / src / sinint.lisp
blob9b3df1c31f25e17b844e0d3f443c6c549fda9fc5
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 1982 Massachusetts Institute of Technology ;;;
9 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11 (in-package :maxima)
13 (macsyma-module sinint)
15 (load-macsyma-macros ratmac)
17 (defun rootfac (q sinint-var)
18 (prog (nthdq nthdq1 simproots ans n-loops)
19 (setq nthdq (pgcd q (pderivative q sinint-var)))
20 (setq simproots (pquotient q nthdq))
21 (setq ans (list (pquotient simproots (pgcd nthdq simproots))))
22 (setq n-loops 0)
23 amen
24 (cond
25 ((= n-loops $factor_max_degree)
26 (return (list q)))
27 ((or (pcoefp nthdq) (pointergp sinint-var (car nthdq)))
28 (return (reverse ans))))
29 (setq nthdq1 (pgcd (pderivative nthdq sinint-var) nthdq))
30 (push (pquotient (pgcd nthdq simproots)
31 (pgcd nthdq1 simproots))
32 ans)
33 (setq nthdq nthdq1)
34 (incf n-loops)
35 (go amen)))
37 (defun aprog (q sinint-var)
38 (setq q (oldcontent q))
39 (let ((sinint-rootfactor
40 (rootfac (cadr q) sinint-var)))
41 (setq sinint-rootfactor
42 (cons (ptimes (car q) (car sinint-rootfactor))
43 (cdr sinint-rootfactor)))
44 (let (sinint-pardenom)
45 (do ((pd (list (car sinint-rootfactor)))
46 (rf (cdr sinint-rootfactor) (cdr rf))
47 (n 2 (1+ n)))
48 ((null rf)
49 (setq sinint-pardenom (reverse pd)))
50 (push (pexpt (car rf) n)
51 pd))
52 (values sinint-rootfactor sinint-pardenom))))
54 (defun cprog (top bottom sinint-var sinint-pardenom)
55 (prog (frpart pardenomc ppdenom thebpg sinint-parnumer sinint-wholepart)
56 (setq frpart (pdivide top bottom))
57 (setq sinint-wholepart (car frpart))
58 (setq frpart (cadr frpart))
59 (if (= (length sinint-pardenom) 1)
60 (return (values (list frpart) sinint-wholepart)))
61 (setq pardenomc (cdr sinint-pardenom))
62 (setq ppdenom (list (car sinint-pardenom)))
63 dseq
64 (if (= (length pardenomc) 1)
65 (go ok))
66 (setq ppdenom (cons (ptimes (car ppdenom) (car pardenomc))
67 ppdenom))
68 (setq pardenomc (cdr pardenomc))
69 (go dseq)
71 (setq pardenomc (reverse sinint-pardenom))
72 numc
73 (setq thebpg (bprog (car pardenomc)
74 (car ppdenom)
75 sinint-var))
76 (setq sinint-parnumer
77 (cons (cdr (ratdivide (ratti frpart (cdr thebpg) t)
78 (car pardenomc)))
79 sinint-parnumer))
80 (setq frpart
81 (cdr (ratdivide (ratti frpart (car thebpg) t)
82 (car ppdenom))))
83 (setq pardenomc (cdr pardenomc))
84 (setq ppdenom (cdr ppdenom))
85 (if (null ppdenom)
86 (return (values (cons frpart sinint-parnumer)
87 sinint-wholepart)))
88 (go numc)))
90 (defun polyint (p sinint-var)
91 (labels
92 ((polyint1 (p sinint-var)
93 (cond ((or (null p) (equal p 0))
94 (cons 0 1))
95 ((atom p)
96 (list sinint-var 1 p))
97 ((not (numberp (car p)))
98 (if (pointergp sinint-var (car p))
99 (list sinint-var 1 p)
100 (polyint1 (cdr p) sinint-var)))
102 (ratplus (polyint2 p sinint-var)
103 (polyint1 (cddr p) sinint-var)))))
105 (polyint2 (p sinint-var)
106 (cons (list sinint-var
107 (1+ (car p))
108 (cadr p))
109 (1+ (car p)))))
110 (ratqu (polyint1 (ratnumerator p) sinint-var)
111 (ratdenominator p))))
114 (defun dprog (ratarg sinint-ratform sinint-var)
115 (prog (klth kx arootf deriv thebpg thetop thebot prod1 prod2 ans
116 sinint-logptdx sinint-parnumer sinint-pardenom sinint-rootfactor sinint-wholepart)
117 (setq ans (cons 0 1))
118 (if (or (pcoefp (cdr ratarg)) (pointergp sinint-var (cadr ratarg)))
119 (return (values (disrep (polyint ratarg sinint-var) sinint-ratform)
120 sinint-logptdx)))
121 (multiple-value-setq (sinint-rootfactor sinint-pardenom)
122 (aprog (ratdenominator ratarg) sinint-var))
123 (multiple-value-setq (sinint-parnumer sinint-wholepart)
124 (cprog (ratnumerator ratarg)
125 (ratdenominator ratarg)
126 sinint-var
127 sinint-pardenom))
128 (setq sinint-rootfactor (reverse sinint-rootfactor))
129 (setq sinint-parnumer (reverse sinint-parnumer))
130 (setq klth (length sinint-rootfactor))
131 intg
132 (if (= klth 1) (go simp))
133 (setq arootf (car sinint-rootfactor))
134 (if (zerop (pdegree arootf sinint-var))
135 (go reset))
136 (setq deriv (pderivative arootf sinint-var))
137 (setq thebpg (bprog arootf deriv sinint-var))
138 (setq kx (1- klth))
139 (setq thetop (car sinint-parnumer))
140 iter
141 (setq prod1 (ratti thetop (car thebpg) t))
142 (setq prod2 (ratti thetop (cdr thebpg) t))
143 (setq thebot (pexpt arootf kx))
144 (setq ans
145 (ratplus ans (ratqu (ratminus prod2)
146 (ratti kx thebot t))))
147 (setq thetop
148 (ratplus prod1
149 (ratqu (ratreduce (pderivative (car prod2) sinint-var)
150 (cdr prod2))
151 kx)))
152 (setq thetop (cdr (ratdivide thetop thebot)))
153 (cond ((= kx 1)
154 (setq sinint-logptdx (cons (ratqu thetop arootf)
155 sinint-logptdx))
156 (go reset)))
157 (setq kx (1- kx))
158 (go iter)
159 reset
160 (setq sinint-rootfactor (cdr sinint-rootfactor))
161 (setq sinint-parnumer (cdr sinint-parnumer))
162 (decf klth)
163 (go intg)
164 simp
165 (push (ratqu (car sinint-parnumer) (car sinint-rootfactor))
166 sinint-logptdx)
167 (if (equal ans 0)
168 (return (values (disrep (polyint sinint-wholepart sinint-var) sinint-ratform)
169 sinint-logptdx)))
170 (setq thetop
171 (cadr (pdivide (ratnumerator ans) (ratdenominator ans))))
172 (return (values (list '(mplus)
173 (disrep (polyint sinint-wholepart sinint-var) sinint-ratform)
174 (disrep (ratqu thetop (ratdenominator ans)) sinint-ratform))
175 sinint-logptdx))))
177 (defun logmabs (x)
178 (list '(%log) (if $logabs
179 (simplify (list '(mabs) x))
180 x)))
182 (defun npask (npask-exp)
183 (cond ((freeof '$%i npask-exp)
184 (learn `((mnotequal) ,npask-exp 0)
186 (asksign npask-exp))
187 (t '$positive)))
189 (defmvar $integrate_use_rootsof nil
190 "Use the rootsof form for integrals when denominator does not factor"
191 :setting-list (nil t))
193 (defun integrate-use-rootsof (f q variable sinint-ratform)
194 (let ((dummy (make-param))
195 (qprime (disrep (pderivative q (p-var q)) sinint-ratform))
196 (ff (disrep f sinint-ratform))
197 (qq (disrep q sinint-ratform)))
198 ;; This basically does a partial fraction expansion and integrates
199 ;; the result. Let r be one (simple) root of the denominator
200 ;; polynomial q. Then the partial fraction expansion is
202 ;; f(x)/q(x) = A/(x-r) + similar terms.
204 ;; Then
206 ;; f(x) = A*q(x)/(x-r) + others
208 ;; Take the limit as x -> r.
210 ;; f(r) = A*limit(q(x)/(x-r),x,r) + others
211 ;; = A*at(diff(q(x),r), [x=r])
213 ;; Hence, A = f(r)/at(diff(q(x),x),[x=r])
215 ;; Then it follows that the integral is
217 ;; A*log(x-r)
219 ;; Note that we don't express the polynomial in terms of the
220 ;; variable of integration, but in our dummy variable instead.
221 ;; Using the variable of integration results in a wrong answer
222 ;; when a substitution was done previously, since when the
223 ;; substitution is finally undone, that modifies the polynomial.
224 `((%lsum) ((mtimes)
225 ,(div* (subst dummy variable ff)
226 (subst dummy variable qprime))
227 ((%log) ,(sub* variable dummy)))
228 ,dummy
229 (($rootsof) ,(subst dummy variable qq) ,dummy))))
231 (defun eprog (p sinint-ratform sinint-var sinint-switch1)
232 (prog (p1e p2e a1e a2e a3e discrim repart sign ncc dcc allcc xx deg
233 sinint-parnumer sinint-pardenom sinint-wholepart)
234 (if (or (equal p 0) (equal (car p) 0))
235 (return 0))
236 (setq p1e (ratnumerator p)
237 p2e (ratdenominator p))
238 (cond ((or sinint-switch1
239 (and (not (atom p2e))
240 (eq (car (setq xx (cadr (oldcontent p2e))))
241 sinint-var)
242 (member (setq deg (pdegree xx sinint-var)) '(5 6) :test #'equal)
243 (zerocoefl xx deg sinint-var)
244 (or (equal deg 5)
245 (not (pminusp (car (last xx)))))))
246 (go efac)))
247 (setq a1e (intfactor p2e))
248 (if (> (length a1e) 1)
249 (go e40))
250 efac
251 (setq ncc (oldcontent p1e))
252 (setq p1e (cadr ncc))
253 (setq dcc (oldcontent p2e))
254 (setq p2e (cadr dcc))
255 (setq allcc (ratqu (car ncc) (car dcc)))
256 (setq deg (pdegree p2e sinint-var))
257 (setq a1e (pderivative p2e sinint-var))
258 (setq a2e (ratqu (polcoef p1e (pdegree p1e sinint-var) sinint-var)
259 (polcoef a1e (pdegree a1e sinint-var) sinint-var)))
260 (cond ((equal (ratti a2e a1e t) (cons p1e 1))
261 (return (list '(mtimes)
262 (disrep (ratti allcc a2e t) sinint-ratform )
263 (logmabs (disrep p2e sinint-ratform))))))
264 (cond ((equal deg 1) (go e10))
265 ((equal deg 2) (go e20))
266 ((and (equal deg 3) (equal (polcoef p2e 2 sinint-var) 0)
267 (equal (polcoef p2e 1 sinint-var) 0))
268 (return (e3prog p1e p2e allcc sinint-ratform sinint-var sinint-switch1)))
269 ((and (member deg '(4 5 6) :test #'equal)
270 (zerocoefl p2e deg sinint-var))
271 (return (enprog p1e p2e allcc deg sinint-ratform sinint-var))))
272 (cond ((and $integrate_use_rootsof
273 (equal (car (psqfr p2e)) p2e))
274 (return (list '(mtimes)
275 (disrep allcc sinint-ratform)
276 (integrate-use-rootsof p1e p2e
277 (car (last varlist))
278 sinint-ratform)))))
279 (return (list '(mtimes)
280 (disrep allcc sinint-ratform)
281 (list '(%integrate)
282 (list '(mquotient)
283 (disrep p1e sinint-ratform)
284 (disrep p2e sinint-ratform))
285 (car (last varlist)))))
287 (return (list '(mtimes)
288 (disrep (ratti allcc
289 (ratqu (polcoef p1e (pdegree p1e sinint-var) sinint-var)
290 (polcoef p2e 1 sinint-var))
292 sinint-ratform)
293 (logmabs (disrep p2e sinint-ratform))))
295 (setq discrim
296 (ratdifference (cons (pexpt (polcoef p2e 1 sinint-var) 2)
298 (ratti 4
299 (ratti (polcoef p2e 2 sinint-var)
300 (polcoef p2e 0 sinint-var)
302 t)))
303 (setq a2e (ratti (polcoef p2e (pdegree p2e sinint-var) sinint-var) 2 t))
304 (setq xx (simplify (disrep discrim sinint-ratform)))
305 (when (equal ($imagpart xx) 0)
306 (setq sign (npask xx))
307 (cond ((eq sign '$negative) (go e30))
308 ((eq sign '$zero) (go zip))))
309 (setq a1e (ratsqrt discrim sinint-ratform))
310 (setq a3e (logmabs
311 (list '(mquotient)
312 (list '(mplus)
313 (list '(mtimes)
314 (disrep a2e sinint-ratform)
315 (disrep (list sinint-var 1 1) sinint-ratform))
316 (disrep (polcoef p2e 1 sinint-var) sinint-ratform)
317 (list '(mminus) a1e))
318 (list '(mplus)
319 (list '(mtimes)
320 (disrep a2e sinint-ratform)
321 (disrep (list sinint-var 1 1) sinint-ratform))
322 (disrep (polcoef p2e 1 sinint-var) sinint-ratform)
323 a1e))))
324 (cond ((zerop (pdegree p1e sinint-var))
325 (return (list '(mtimes)
326 (disrep allcc sinint-ratform)
327 (list '(mquotient)
328 (disrep (polcoef p1e 0 sinint-var) sinint-ratform)
329 a1e)
330 a3e))))
331 (return
332 (list
333 '(mplus)
334 (list '(mtimes)
335 (disrep (ratti allcc
336 (ratqu (polcoef p1e (pdegree p1e sinint-var) sinint-var) a2e)
338 sinint-ratform)
339 (logmabs (disrep p2e sinint-ratform)))
340 (list
341 '(mtimes)
342 (list
343 '(mquotient)
344 (disrep (ratti allcc
345 (ratqu (eprogratd a2e p1e p2e sinint-var) a2e)
347 sinint-ratform)
348 a1e)
349 a3e)))
351 (setq a1e (ratsqrt (ratminus discrim) sinint-ratform))
352 (setq
353 repart
354 (ratqu (cond ((zerop (pdegree p1e sinint-var))
355 (ratti a2e (polcoef p1e 0 sinint-var) t))
357 (eprogratd a2e p1e p2e sinint-var)))
358 (polcoef p2e (pdegree p2e sinint-var) sinint-var)))
359 (setq a3e (cond ((equal 0 (car repart))
362 `((mtimes) ((mquotient)
363 ,(disrep (ratti allcc repart t) sinint-ratform)
364 ,a1e)
365 ((%atan)
366 ((mquotient)
367 ,(disrep (pderivative p2e sinint-var) sinint-ratform)
368 ,a1e))))))
369 (if (zerop (pdegree p1e sinint-var))
370 (return a3e))
371 (return (list '(mplus)
372 (list '(mtimes)
373 (disrep (ratti allcc
374 (ratqu (polcoef p1e (pdegree p1e sinint-var) sinint-var) a2e)
376 sinint-ratform)
377 (logmabs (disrep p2e sinint-ratform)))
378 a3e))
380 (setq
382 (ratqu
383 (psimp
384 (p-var p2e)
385 (pcoefadd 2
386 (pexpt (ptimes 2 (polcoef p2e 2 sinint-var)) 2)
387 (pcoefadd 1
388 (ptimes 4 (ptimes (polcoef p2e 2 sinint-var)
389 (polcoef p2e 1 sinint-var)))
390 (pcoefadd 0 (pexpt (polcoef p2e 1 sinint-var) 2) ()))))
391 (ptimes 4 (polcoef p2e 2 sinint-var))))
392 (return (fprog (ratti allcc (ratqu p1e p2e) t)
393 sinint-ratform
394 sinint-var))
396 (setq sinint-parnumer nil
397 sinint-pardenom a1e
398 sinint-switch1 t)
399 (multiple-value-setq (sinint-parnumer sinint-wholepart)
400 (cprog p1e p2e sinint-var sinint-pardenom))
401 (setq a2e
402 (mapcar #'(lambda (j k)
403 (eprog (ratqu j k) sinint-ratform sinint-var sinint-switch1))
404 sinint-parnumer sinint-pardenom))
405 (setq sinint-switch1 nil)
406 (return (cons '(mplus) a2e))))
408 (defun e3prog (num denom cont sinint-ratform sinint-var sinint-switch1)
409 (prog (a b c d e r ratr var* x)
410 (setq a (polcoef num 2 sinint-var)
411 b (polcoef num 1 sinint-var)
412 c (polcoef num 0 sinint-var)
413 d (polcoef denom 3 sinint-var)
414 e (polcoef denom 0 sinint-var))
415 (setq r (cond ((eq (npask (simplify (disrep (ratqu e d) sinint-ratform)))
416 '$negative)
417 (simpnrt (disrep (ratqu (ratti -1 e t) d) sinint-ratform) 3))
419 (neg (simpnrt (disrep (ratqu e d) sinint-ratform) 3)))))
420 (setq var* (list sinint-var 1 1))
421 (newvar r)
422 (orderpointer varlist)
423 (setq x (ratf r))
424 (setq sinint-ratform (car x) ratr (cdr x))
425 (return
426 (simplify
427 (list '(mplus)
428 (list '(mtimes)
429 (disrep (ratqu (r* cont (r+ (r* a ratr ratr) (r* b ratr) c))
430 (r* ratr ratr 3 d))
431 sinint-ratform)
432 (logmabs (disrep (ratpl (ratti -1 ratr t) var*) sinint-ratform)))
433 (eprog (r* cont (ratqu (r+ (r* (r+ (r* 2 a ratr ratr)
434 (r* -1 b ratr)
435 (r* -1 c))
436 var*)
437 (r+ (ratqu (r* -1 a e) d)
438 (r* b ratr ratr)
439 (r* -1 2 c ratr)))
440 (r* 3 d ratr ratr
441 (r+ (ratti var* var* t)
442 (ratti ratr var* t)
443 (ratti ratr ratr t)))))
444 sinint-ratform
445 sinint-var
446 sinint-switch1)
447 )))))
449 (defun eprogratd (a2e p1e p2e sinint-var)
450 (ratdifference (ratti a2e
451 (polcoef p1e (1- (pdegree p1e sinint-var)) sinint-var)
453 (ratti (polcoef p2e (1- (pdegree p2e sinint-var)) sinint-var)
454 (polcoef p1e (pdegree p1e sinint-var) sinint-var)
455 t)))
457 (defun enprog (num denom cont deg sinint-ratform sinint-var)
458 ;; Denominator is (A*VAR^4+B) =
459 ;; if B<0 then (SQRT(A)*VAR^2 - SQRT(-B)) (SQRT(A)*VAR^2 + SQRT(-B))
460 ;; else
461 ;; (SQRT(A)*VAR^2 - SQRT(2)*A^(1/4)*B^(1/4)*VAR + SQRT(B)) *
462 ;; (SQRT(A)*VAR^2 + SQRT(2)*A^(1/4)*B^(1/4)*VAR + SQRT(B))
463 ;; or (A*VAR^5+B) =
464 ;; (1/4) * (A^(1/5)*VAR + B^(1/5)) *
465 ;; (2*A^(2/5)*VAR^2 + (-SQRT(5)-1)*A^(1/5)*B^(1/5)*VAR + 2*B^(2/5)) *
466 ;; (2*A^(2/5)*VAR^2 + (+SQRT(5)-1)*A^(1/5)*B^(1/5)*VAR + 2*B^(2/5))
467 ;; or (A*VAR^6+B) =
468 ;; if B<0 then (SQRT(A)*VAR^3 - SQRT(-B)) (SQRT(A)*VAR^3 + SQRT(-B))
469 ;; else
470 ;; (A^(1/3)*VAR^2 + B^(1/3)) *
471 ;; (A^(1/3)*VAR^2 - SQRT(3)*A^(1/6)*B^(1/6)*VAR + B^(1/3)) *
472 ;; (A^(1/3)*VAR^2 + SQRT(3)*A^(1/6)*B^(1/6)*VAR + B^(1/3))
473 (prog (($expop 0) ($expon 0) a b term disvar $algebraic)
474 #+nil
475 (setq $expop 0 $expon 0)
476 (setq a (simplify (disrep (polcoef denom deg sinint-var) sinint-ratform))
477 b (simplify (disrep (polcoef denom 0 sinint-var) sinint-ratform))
478 disvar (simplify (get sinint-var 'disrep))
479 num (simplify (disrep num sinint-ratform))
480 cont (simplify (disrep cont sinint-ratform)))
481 (cond ((= deg 4)
482 (if (eq '$neg ($asksign b))
483 (setq denom
484 (mul2 (add2 (mul2 (power a '((rat simp) 1 2)) (power disvar 2))
485 (power (mul -1 b) '((rat simp) 1 2)))
486 (add2 (mul2 (power a '((rat simp) 1 2)) (power disvar 2))
487 (mul -1 (power (mul -1 b) '((rat simp) 1 2))))))
488 (progn
489 (setq denom (add2 (mul2 (power a '((rat simp) 1 2)) (power disvar 2))
490 (power b '((rat simp) 1 2)))
491 term (muln (list (power 2 '((rat simp) 1 2))
492 (power a '((rat simp) 1 4))
493 (power b '((rat simp) 1 4))
494 disvar)
496 (setq denom (mul2 (add2 denom term) (sub denom term))))))
497 ((= deg 5)
498 (setq term (mul3 (power a '((rat simp) 1 5))
499 (power b '((rat simp) 1 5))
500 disvar))
501 (setq denom (add2 (mul3 2 (power a '((rat simp) 2 5))
502 (power disvar 2))
503 (sub (mul2 2 (power b '((rat simp) 2 5))) term)))
504 (setq term (mul2 (power 5 '((rat simp) 1 2)) term))
505 (setq denom (muln (list '((rat simp) 1 4)
506 (add2 (mul2 (power a '((rat simp) 1 5)) disvar)
507 (power b '((rat simp) 1 5)))
508 (add2 denom term) (sub denom term))
509 t)))
511 (if (eq '$neg ($asksign b))
512 (setq denom
513 (mul2 (add2 (mul2 (power a '((rat simp) 1 2)) (power disvar 3))
514 (power (mul -1 b) '((rat simp) 1 2)))
515 (add2 (mul2 (power a '((rat simp) 1 2)) (power disvar 3))
516 (mul -1 (power (mul -1 b) '((rat simp) 1 2))))))
517 (progn
518 (setq denom (add2 (mul2 (power a '((rat simp) 1 3)) (power disvar 2))
519 (power b '((rat simp) 1 3)))
520 term (muln (list (power 3 '((rat simp) 1 2))
521 (power a '((rat simp) 1 6))
522 (power b '((rat simp) 1 6))
523 disvar)
525 (setq denom (mul3 denom (add2 denom term) (sub denom term))))
527 ;;Needs $ALGEBRAIC NIL so next call to RATF will preserve factorization.
528 (return (mul2 cont (ratint (div num denom) disvar)))))
530 (defun zerocoefl (e n sinint-var)
531 (do ((i 1 (1+ i)))
532 ((= i n) t)
533 (if (not (equal (polcoef e i sinint-var) 0))
534 (return nil))))
536 (defun ratsqrt (a sinint-ratform)
537 (let (varlist)
538 (simpnrt (disrep a sinint-ratform) 2)))
540 (defun fprog (rat* sinint-ratform sinint-var)
541 (multiple-value-bind (dprog-ret sinint-logptdx)
542 (dprog rat* sinint-ratform sinint-var)
543 (addn (cons dprog-ret
544 (mapcar #'(lambda (p)
545 (eprog p sinint-ratform sinint-var nil))
546 sinint-logptdx))
547 nil)))
549 (defun ratint (sinint-exp sinint-var)
550 (prog (genvar *checkfactors* varlist ratarg $keepfloat)
551 (setq varlist (list sinint-var))
552 (setq ratarg (ratf sinint-exp))
553 (let ((sinint-ratform (car ratarg))
554 (sinint-var (caadr (ratf sinint-var))))
555 (return (fprog (cdr ratarg) sinint-ratform sinint-var)))))
557 (defun intfactor (l)
558 (labels ((everysecond (a)
559 (if a (cons (if (numberp (car a))
560 (pexpt (car a) (cadr a))
561 (car a))
562 (everysecond (cddr a))))))
564 (prog ($factorflag a b)
565 (setq a (oldcontent l)
566 b (everysecond (pfactor (cadr a))))
567 (return (if (equal (car a) 1)
569 (cons (car a) b))))))