Eliminate spurious redefinition of derivabbrev in Ctensor, fix documentation of diagm...
[maxima/cygwin.git] / src / irinte.lisp
blob0db9ac57afda946c8fec93b40de425f5b6aaf934
1 ;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;;; The data in this file contains enhancments. ;;;;;
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 irinte)
15 (load-macsyma-macros rzmac)
17 (declare-top (special checkcoefsignlist var zerosigntest productcase))
19 (defun hasvar (exp) (not (freevar exp)))
21 (defun zerp (a) (equal a 0))
23 (defun integerpfr (a) (if (not (maxima-integerp a)) (integerp1 a)))
25 (defun nonzerp (a) (not (equal a 0)))
27 (defun freevnz (a) (and (freevar a) (not (equal a 0))))
29 (defun inte (funct x)
30 (let ((checkcoefsignlist nil)
31 (*globalcareflag* nil)
32 ($radexpand t))
33 (declare (special checkcoefsignlist *globalcareflag* $radexpand))
34 (intir-ref funct x)))
36 (defun intir-ref (fun x)
37 (prog (a)
38 (when (setq a (intir1 fun x)) (return a))
39 (when (setq a (intir2 fun x)) (return a))
40 (return (intir3 fun x))))
42 (defun intir1 (fun x)
43 (prog (assoclist e0 r0 e1 e2 r1 r2 d p)
44 (setq assoclist (factpow (specrepcheck fun) x))
45 (setq e1 (cdras 'e1 assoclist)
46 e2 (cdras 'e2 assoclist))
47 (cond ((null assoclist)(return nil)))
48 (setq d (cdras 'd assoclist)
49 p (cdras 'p assoclist)
50 e0 (cdras 'e0 assoclist)
51 r0 (cdras 'r0 assoclist)
52 r1 (cdras 'r1 assoclist)
53 r2 (cdras 'r2 assoclist))
54 (cond ((floatp e0)
55 (setq e0 (rdis (ration1 e0)))))
56 (cond ((floatp e1)
57 (setq e1 (rdis (ration1 e1)))))
58 (cond ((floatp e2)
59 (setq e2 (rdis (ration1 e2)))))
60 (return (intir1-ref d p r0 e0 r1 e1 r2 e2 x))))
62 (defun intir2 (funct x)
63 (let ((res (intir funct x)))
64 (if res
65 res
66 (intirfactoroot funct x))))
68 (defun intir3 (exp x)
69 (prog ((assoclist (elliptquad exp x)) e f g r0)
70 (cond (assoclist
71 (setq e (cdras 'e assoclist) f (cdras 'f assoclist)
72 g (cdras 'g assoclist) r0 (cdras 'r0 assoclist))
73 (assume `(($notequal) ,e 0))
74 (return (intir3-r0test assoclist x e f g r0))))
75 (return nil)))
77 (defun intir3-r0test (assoclist x e f g r0)
78 (if (root+anything r0 x)
79 nil
80 (intir3-ref assoclist x e f g r0)))
82 ;; Handle integrals of the form d*p(x)*r1(x)^e1*r2(x)^e2*r0(x)^e0,
83 ;; where p(x) is a polynomial, e1 and e2 are both half an odd integer,
84 ;; and e3 is an integer.
85 (defun intir1-ref (d p r0 e0 r1 e1 r2 e2 x)
86 (let ((nume1 (cadr e1)) ;; nume1 = 2*e1
87 (nume2 (cadr e2))) ;; nume2 = 2*e2
88 ;; I think what this does is try to rationalize r1(x)^e1 or
89 ;; r2(x)^e2 so we end up with a new integrand of the form
90 ;; d*p'(x)*r0'(x)^e0*ra(x)^ea, where p'(x) is a new polynomial
91 ;; obtained from rationaling one term and r0'(x) is a more
92 ;; complicated term.
93 (cond ((and (plusp nume1) (plusp nume2))
94 (pp-intir1 d p r0 e0 r1 e1 r2 e2 x))
95 ((and (minusp nume1) (minusp nume2))
96 (mm-intir1 d p r0 e0 r1 e1 r2 e2 x))
97 ((plusp nume1)
98 (pm-intir1 d p r0 e0 r1 e1 r2 e2 x))
100 (pm-intir1 d p r0 e0 r2 e2 r1 e1 x)))))
102 (defun pp-intir1 (d p r0 e0 r1 e1 r2 e2 x)
103 (if (> (cadr e1) (cadr e2))
104 (pp-intir1-exec d p r0 e0 r1 e1 r2 e2 x)
105 (pp-intir1-exec d p r0 e0 r2 e2 r1 e1 x)))
107 ;; Handle integrals of the form d*p(x)*r0(x)^e0*r1(x)^e1*r2(x)^e2
108 ;; where p(x) is a polynomial, e1 < 0, and e2 < 0 and are both half an
109 ;; odd integer, and e3 is an integer.
110 (defun mm-intir1 (d p r0 e0 r1 e1 r2 e2 x)
111 (if (> (cadr e1) (cadr e2))
112 (mm-intir1-exec d p r0 e0 r1 e1 r2 e2 x)
113 (mm-intir1-exec d p r0 e0 r2 e2 r1 e1 x)))
115 ;; Handle integrals of the form d*p(x)*r0(x)^e0*r1(x)^e1*r2(x)^e2
116 ;; where p(x) is a polynomial, e1 > 0, and e2 < 0 and are both half an
117 ;; odd integer, and e3 is an integer.
119 (defun pm-intir1 (d p r0 e0 rofpos epos rofneg eneg x)
120 (let ((numepos (cadr epos)) ;; numepos = 2*epos = 2*e1
121 (numul-1eneg (mul -1 (cadr eneg)))) ;; numul-1eneg = -2*eneg = -2*e2
122 (cond ((> numepos numul-1eneg)
123 (mm-intir1 d (mul p (power rofpos (sub epos eneg)))
124 r0 e0 rofpos eneg rofneg eneg x))
125 ((or (equal e0 0) (plusp e0))
126 (pp-intir1 d (mul p (power rofneg (sub eneg epos)))
127 r0 e0 rofpos epos rofneg epos x))
129 (mm-intir1 d (mul p (power rofpos (sub epos eneg)))
130 r0 e0 rofpos eneg rofneg eneg x)))))
132 (defun pp-intir1-exec (d p r0 e0 rofmax emax rofmin emin x)
133 (intir (mul d p (if (equal e0 0) 1 (power r0 e0))
134 (power rofmax (add emax (mul -1 emin)))
135 (power ($expand (mul rofmax rofmin)) emin)) x))
137 ;; Handle integrals of the form d*p(x)*r0(x)^e0*r1(x)^e1*r2(x)^e2
138 ;; where p(x) is a polynomial, e1 < 0, and e2 < 0 and are both half an
139 ;; odd integer, and e3 is an integer. And e2 > e1.
140 (defun mm-intir1-exec (d p r0 e0 rofmin emin rofmax emax x)
141 (intir (mul d p
142 (if (equal e0 0) 1
143 (power r0 e0))
144 (power rofmax (add emax (mul -1 emin)))
145 (power ($expand (mul rofmax rofmin)) emin)) x))
147 ;; Integrating the form (e*x^2+f*x+g)^m*r0(x)^e0.
149 (defun intir3-ref (assoclist x e f g r0)
150 (let ((signdisc (signdiscr e f g))
151 (d (cdras 'd assoclist))
152 (p (cdras 'p assoclist))
153 (e0 (cdras 'e0 assoclist)))
154 (cond ((eq signdisc '$positive)
155 (pns-intir3 x e f g d p r0 e0))
156 ((eq signdisc '$negative)
157 (ns-intir3 x e f g d p r0 e0))
159 (zs-intir3 x e f d p r0 e0)))))
161 (defun root+anything (exp var)
162 (m2 exp '((mplus)
163 ((coeffpt) (c nonzerp) ((mexpt) (u hasvar) (v integerpfr)))
164 ((coeffpp) (c true)))))
166 ;; Handle d*p(x)/(e*x^2+f*x+g)*r0(x)^e0. We know that e*x^2+f*x+g has
167 ;; no repeated roots. Let D be the discriminant of this quadratic,
168 ;; sqrt(f^2-4*e*g). (If we're here, we already know that f^2-4*e*g >
169 ;; 0). Thus, we can factor this quadratic as
170 ;; (2*e*x+f-D)*(2*e*x+f+D)/(4*e). Thus, the original integrand
171 ;; becomes
173 ;; 4*e*d/(2*e*x+f-D)/(2*e*x+f+D)*p(x)*r0(x)^e0.
175 ;; We can separate this as a partial fraction to get
177 ;; (2*d*e/D/(2*e*x+f-D) - 2*d*e/D/(2*e*x+f+D))*p(x)*r0(x)^e0.
179 ;; So we have separated this into two "simpler" integrals.
180 (defun pns-intir3 (x e f g d p r0 e0)
181 (let* ((discr (power (sub (mul f f) (mul 4 e g)) 1//2)) ;; Compute discriminant of
182 (p*r0^e0 (mul p (power r0 e0))) ;; quadratic: sqrt(f^2-4*e*g)
183 (2*e*x+f (add (mul 2 e x) f))
184 (2*e*d*invdisc (mul 2 e d (inv discr))))
185 (mul 2*e*d*invdisc
186 (sub (intir2 (mul (inv (sub 2*e*x+f discr)) p*r0^e0) x)
187 (intir2 (mul (inv (add 2*e*x+f discr)) p*r0^e0) x)))))
189 ;; Handle d*p(x)/(e*x^2+f*x+g)*r0(x)^e0. We know that e*x^2+f*x+g has
190 ;; repeated roots.
192 (defun zs-intir3 (x e f d p r0 e0)
193 ;; Since e*x^2+f*x+g has repeated roots, it can be written as e*(x+r)^2.
194 ;; We easily see that r = f/(2*e), so rewrite the integrand as
196 ;; d*p(x)/e/(x+r)^2*r0(x)^e0.
197 (intir2 (mul d p (inv e)
198 (power (add x (div f (add e e))) -2)
199 (power r0 e0))
202 ;; Handle d*p(x)/(e*x^2+f*x+g)*r0(x)^e0. We know that e*x^2+f*x+g has
203 ;; no real roots.
205 ;; G&R 2.252 shows how we can handle these integrals, but I'm too lazy
206 ;; to implement them right now, so return NIL to indicate we don't
207 ;; know what to do. But whatever it is we do, it's definitely not
208 ;; calling intir or intir2 like zs-intir3 or pns-intir3 do because
209 ;; they eventually call inti which only handles linear forms (e = 0.)
210 ;; We'll need to write custom versions.
211 (defun ns-intir3 (xx ee fff gg dd pp r0 e0)
212 (declare (ignore xx ee fff gg dd pp r0 e0))
213 nil)
215 (defun cdras (a b)
216 (cdr (assoc a b :test #'equal)))
218 (defun intir (funct x)
219 (inti funct x (jmaug (specrepcheck funct) x)))
221 ;; Integrate d*p(x)*(f*x+e)^m*(a*x^2+b*x+c)^n. p(x) is a polynomial,
222 ;; m is an integer, n is a number(?). a, b, c, e, and f are
223 ;; expressions independent of x (var).
224 (defun inti (funct x assoclist)
225 (prog (met n expr f e #+nil denom)
226 (setq n (cdras 'n assoclist))
227 (when (or (null assoclist) (maxima-integerp n))
228 (return nil))
229 (setq f (cdras 'f assoclist)
230 e (cdras 'e assoclist))
231 ;; If e is 0 (or not given, we don't have to do the
232 ;; transformation. Just integrate it and return.
233 (when (or (equal e 0) (null e))
234 (return (intira funct x)))
236 ;; (unless (numberp f) (go jump))
237 ;; (when (plusp f) (go jump))
238 ;; I (rtoy) think this is the case where f is a negative number.
239 ;; I think this is trying to convert f*x+e to -f*x-e to make the
240 ;; coefficient of x positive. And if I'm right, the code below
241 ;; isn't doing it correctly, except when m = 1 or m = -1.
242 ;; (setq denom (add (mul f x) e)
243 ;; f (mul -1 f)
244 ;; e (mul -1 e)
245 ;; funct (mul -1 (div (meval (mul denom funct))
246 ;; (add (mul f x) e))))
248 jump
249 ;; Apply the linear substitution y = f*x+e. That is x = (y-e)/f.
250 ;; Then use INTIRA to integrate this. The integrand becomes
251 ;; something like p(y)*y^m and other terms.
252 (setq expr (intira (distrexpandroot
253 (cdr ($substitute
254 (mul (inv f)
255 (add (setq met (make-symbol (symbol-name '#:yannis)))
256 (mul -1 e)))
257 x funct)))
258 met))
259 (setq expr (and expr (mul (inv f) expr)))
260 (return ($expand ($substitute (add (mul f x) e) met expr)))))
262 (defun distrexpandroot (expr)
263 (if (null expr)
265 (mul (expandroot (car expr))
266 (distrexpandroot (cdr expr)))))
268 (defun expandroot (expr)
269 (if (atom expr)
270 expr
271 (if (and (eq (caar expr) 'mexpt)
272 (integerpfr (caddr expr)))
273 ($expand expr)
274 expr)))
276 (defun intirfactoroot (expr x)
277 (declare (special *globalcareflag*))
278 (prog (assoclist (exp expr))
279 (when (setq assoclist (jmaug (setq expr (distrfactor (timestest expr) x)) x))
280 (return (inti expr x assoclist)))
281 (setq *globalcareflag* 't)
282 (when (setq assoclist (jmaug (setq exp (distrfactor (timestest exp) x)) x))
283 (setq *globalcareflag* nil)
284 (return (inti exp x assoclist)))
285 (setq *globalcareflag* nil)
286 (return nil)))
288 (defun distrfactor (expr x)
289 (if (null expr)
291 (mul (factoroot (car expr) x)
292 (distrfactor (cdr expr) x))))
294 (defun factoroot (expr var)
295 (if (atom expr)
296 expr
297 (if (and (eq (caar expr) 'mexpt)
298 (hasvar expr)
299 (integerpfr (caddr expr)))
300 (carefulfactor expr var)
301 expr)))
303 (defun carefulfactor (expr x)
304 (declare (special *globalcareflag*))
305 (if (null *globalcareflag*)
306 ($factor expr)
307 (restorex ($factor (power (div (cadr expr) x) (caddr expr))) x)))
309 (defun restorex (expr var)
310 (if (atom expr)
311 expr
312 (if (eq (caar expr) 'mtimes)
313 (distrestorex (cdr expr) var)
314 expr)))
316 (defun distrestorex (expr var)
317 (if (null expr)
319 (mul (restoroot (car expr) var)
320 (distrestorex (cdr expr) var))))
322 (defun restoroot (expr var)
323 (if (atom expr)
324 expr
325 (if (and (eq (caar expr) 'mexpt)
326 (integerpfr (caddr expr))
327 (mplusp (cadr expr)))
328 (power ($expand (mul var (cadr expr))) (caddr expr))
329 expr)))
331 (defun timestest (expr)
332 (if (atom expr)
333 (list expr)
334 (if (eq (caar expr) 'mtimes)
335 (cdr expr)
336 (list expr))))
338 ;; Integrate a function of the form d*p(y)*y^m*(a*y^2+b*x+c)^n.
339 ;; n is half of an integer.
340 (defun intira (funct x)
341 (prog (a b c *ec-1* d m n (assoclist (jmaug (specrepcheck funct) x))
342 pluspowfo1 pluspowfo2 minuspowfo
343 polfact signn poszpowlist negpowlist)
344 (declare (special *ec-1*))
345 (setq n (cdras 'n assoclist))
346 ;; r12 1//2)
347 ;; (format t "n = ~A~%" n)
348 (when (or (null assoclist)
349 (maxima-integerp n))
350 (return nil))
351 (when (floatp n)
352 (setq n (rdis (ration1 n))))
353 (setq d (cdras 'd assoclist))
354 (when (equal d 0) (return 0))
355 (setq c (cdras 'a assoclist))
356 (when (equal c 0) (return nil))
357 (setq m (cdras 'm assoclist)
358 polfact (cdras 'p assoclist)
359 ;; We know that n is of the form s/2, so just make n = s,
360 ;; and remember that the actual exponent needs to be
361 ;; divided by 2.
362 n (cadr n)
363 signn (checksigntm n)
364 *ec-1* (power c -1)
365 b (cdras 'b assoclist)
366 a (cdras 'c assoclist)
367 ;; pluspowfo1 = 1/2*(n-1), That is, the original exponent - 1/2.
368 pluspowfo1 (mul 1//2 (+ n -1))
369 ;; minupowfo = 1/2*(n+1), that is, the original exponent + 1/2.
370 minuspowfo (mul 1//2 (+ n 1))
371 ;; pluspowfo2 = -1/2*(n+1), that is, the negative of 1/2
372 ;; plus the original exponent.
373 pluspowfo2 (* -1 minuspowfo))
374 (destructuring-bind (pos &optional neg)
375 (powercoeflist polfact m x)
376 (setf poszpowlist pos)
377 (setf negpowlist neg))
379 #+nil (progn
380 (format t "n = ~A~%" n)
381 (format t "pluspowfo1 = ~A~%" pluspowfo1)
382 (format t "minuspowfo = ~A~%" minuspowfo)
383 (format t "pluspowfo2 = ~A~%" pluspowfo2))
385 ;; I (rtoy) think powercoeflist computes p(x)/x^m as a Laurent
386 ;; series. POSZPOWLIST is a list of coefficients of the positive
387 ;; powers and NEGPOWLIST is a list of the negative coefficients.
388 (when (and (null negpowlist)
389 (not (null poszpowlist)))
390 ;; Only polynomial parts.
391 (when (eq signn '$positive)
392 (return (augmult (mul d
393 (nummnumn poszpowlist
394 pluspowfo1
395 minuspowfo c b a x)))))
396 (return (augmult (mul d
397 (nummdenn poszpowlist
398 pluspowfo2 c b a x)))))
399 (when (and (null poszpowlist)
400 (not (null negpowlist)))
401 ;; No polynomial parts
402 (when (eq signn '$positive)
403 (return (augmult (mul d
404 (denmnumn negpowlist minuspowfo c b a x)))))
405 (return (augmult (mul d
406 (denmdenn negpowlist pluspowfo2 c b a x)))))
407 (when (and (not (null negpowlist))
408 (not (null poszpowlist)))
409 ;; Positive and negative powers.
410 (when (eq signn '$positive)
411 (return (add (augmult (mul d
412 (nummnumn poszpowlist
413 pluspowfo1
414 minuspowfo c b a x)))
415 (augmult (mul d
416 (denmnumn negpowlist
417 minuspowfo c b a x))))))
418 (return (add (augmult (mul d
419 (nummdenn poszpowlist
420 pluspowfo2 c b a x)))
421 (augmult (mul d
422 (denmdenn negpowlist
423 pluspowfo2 c b a x))))))))
425 ;; Match d*p(x)*(f*x+e)^m*(a*x^2+b*x+c)^n. p(x) is a polynomial, m is
426 ;; an integer, n is half of an integer. a, b, c, e, and f are
427 ;; expressions independent of x (var).
428 (defun jmaug (exp var)
429 (m2 exp '((mtimes)
430 ((coefftt) (d freevar))
431 ((coefftt) (p polyp))
432 ((mexpt) ((mplus) ((coeffpt) (f freevar) (x varp))
433 ((coeffpp)(e freevar)))
434 (m maxima-integerp))
435 ((mexpt) ((mplus)
436 ((coeffpt) (a freevar) ((mexpt) (x varp) 2))
437 ((coeffpt) (b freevar) (x varp))
438 ((coeffpp) (c freevar)))
439 (n integerp1)))))
441 ;; Match d*p(x)*r1(x)^e1*r2(x)^e2*r0(x)^e0, where p(x) is a
442 ;; polynomial, e1 and e2 are both half an odd integer, and e3 is an
443 ;; integer.
444 (defun factpow (exp var)
445 (m2 exp '((mtimes) ((coefftt) (d freevar))
446 ((coefftt) (p polyp))
447 ((mexpt) (r1 hasvar)
448 (e1 integerpfr))
449 ((mexpt) (r2 hasvar)
450 (e2 integerpfr))
451 ((mexpt) (r0 hasvar)
452 (e0 maxima-integerp)))))
454 ;; Match EXP to the form
455 ;; d*p/(e*x^2+f*x+g)*r0(x)^e0. p is a polynomial in x.
456 (defun elliptquad (exp var)
457 (m2 exp '((mtimes)
458 ((coefftt) (d freevar))
459 ((coefftt) (p polyp))
460 ((mexpt) ((mplus) ((coeffpt) (e freevnz) ((mexpt) (x varp) 2))
461 ((coeffpt) (f freevar) (x varp))
462 ((coeffpp) (g freevar)))
464 ((mexpt) (r0 hasvar)
465 (e0 integerpfr)))))
467 ;; From the set of coefficients, generate the polynomial c*x^2+b*x+a.
468 (defun polfoo (c b a x)
469 (add (mul c x x)
470 (mul b x)
473 ;; I think this is computing the list of coefficients of fun(x)/x^m,
474 ;; where fun(x) is a polynomial and m is a non-negative integer. The
475 ;; result is a list of two lists. The first list contains the
476 ;; polynomial part of fun(x)/x^m. The second is the principal part
477 ;; containing negative powers.
479 ;; Each of the lists is itself a list of power and coefficient itself.
481 ;; Thus (x+3)^2/x^2 = 1 + 6/x + 9/x^2 returns
483 ;; '(((0 1)) ((1 6) (2 9)))
484 (defun powercoeflist (fun m var)
485 (prog ((expanfun (unquote ($expand (mul (prevconstexpan fun var) (power var m)))))
486 maxpowfun powfun coef poszpowlist negpowlist)
487 (when (and (equal fun 1) (plusp m))
488 (return (cons nil (list (list (cons m (list 1)))))))
489 (when (and (equal fun 1) (minusp m))
490 (return (cons nil (list (list (cons (- m) (list 1)))))))
491 (when (equal expanfun 1)
492 (return (cons (list (cons 0 (list 1))) (list nil))))
493 (setq maxpowfun ($hipow expanfun var)
494 powfun ($lopow expanfun var))
495 loop (setq coef ($coeff expanfun (power var powfun)))
496 (when (numberp coef) (go testjump))
497 (go nojump)
498 testjump (when (and (not (zerop powfun)) (zerop coef))
499 (go jump))
500 nojump (when (plusp powfun)
501 (setq poszpowlist (append poszpowlist
502 (list (cons powfun (list coef))))))
503 (when (zerop powfun)
504 (setq poszpowlist
505 (append poszpowlist
506 (list (cons 0 (list (consterm (cdr expanfun) var)))))))
507 (when (minusp powfun)
508 (setq negpowlist (append negpowlist (list (cons (- powfun) (list coef))))))
509 (when (= powfun maxpowfun)
510 (return (list poszpowlist (reverse negpowlist))))
511 jump (incf powfun)
512 (go loop)))
514 (defun consterm (fun var)
515 (cond ((null fun) 0)
516 ((freeof var (car fun))
517 (add (car fun) (consterm (cdr fun) var)))
518 (t (consterm (cdr fun) var))))
520 (defun prevconstexpan (fun var)
521 (cond ((atom fun) fun)
522 ((eq (caar fun) 'mplus)
523 (cond ((and (freeof var fun)
524 (not (inside fun 'mexpt)))
525 (list '(mquote) fun))
526 ((and (freeof var fun) (inside fun 'mexpt))
527 (list '(mquote)
528 (distrinplusprev (cdr fun) var)))
529 ((inside fun 'mexpt)
530 (distrinplusprev (cdr fun) var))
531 (t fun)))
532 ((eq (caar fun) 'mtimes)
533 (distrintimesprev (cdr fun) var))
534 ((and (not (inside (cdr fun) var))
535 (eq (caar fun) 'mexpt))
536 (power (prevconstexpan (cadr fun) var) (caddr fun)))
537 (t fun)))
539 (defun distrinplusprev (fun var)
540 (cond ((null fun) 0)
541 (t (add (prevconstexpan (car fun) var)
542 (distrinplusprev (cdr fun) var)))))
544 (defun distrintimesprev (fun var)
545 (cond ((null fun) 1)
546 (t (mul (prevconstexpan (car fun) var)
547 (distrintimesprev (cdr fun) var)))))
549 (defun inside (fun arg)
550 (cond ((atom fun)(equal fun arg))
551 ((inside (car fun) arg) t)
552 (t (inside (cdr fun) arg))))
554 (defun unquote (fun)
555 (cond ((not (inside fun 'mquote)) fun)
556 (t (unquote (meval fun)))))
558 (defun checksigntm (expr)
559 (prog (aslist quest zerosigntest productcase)
560 (setq aslist checkcoefsignlist)
561 (cond ((atom expr) (go loop)))
562 (cond ((eq (caar expr) 'mtimes)(setq productcase t)))
563 loop (cond ((null aslist)
564 (setq checkcoefsignlist
565 (append checkcoefsignlist
566 (list (cons expr
567 (list
568 (setq quest (checkflagandact expr)))))))
569 (return quest)))
570 (cond ((equal (caar aslist) expr) (return (cadar aslist))))
571 (setq aslist (cdr aslist))
572 (go loop)))
574 (defun checkflagandact (expr)
575 (cond (productcase
576 (setq productcase nil)
577 (findsignoftheirproduct (findsignofactors (cdr expr))))
578 (t (asksign ($realpart expr)))))
580 (defun findsignofactors (listofactors)
581 (cond ((null listofactors) nil)
582 ((eq zerosigntest '$zero) '$zero)
583 (t (append (list (setq zerosigntest (checksigntm (car listofactors))))
584 (findsignofactors (cdr listofactors))))))
586 (defun findsignoftheirproduct (llist)
587 (prog (sign)
588 (cond ((eq llist '$zero) (return '$zero)))
589 (setq sign '$positive)
590 loop (cond ((null llist) (return sign)))
591 (cond ((eq (car llist) '$positive)
592 (setq llist (cdr llist))
593 (go loop)))
594 (cond ((eq (car llist) '$negative)
595 (setq sign (changesign sign) llist (cdr llist))
596 (go loop)))
597 (return '$zero)))
599 (defun changesign (sign)
600 (if (eq sign '$positive)
601 '$negative
602 '$positive))
604 ;; Integrate 1/sqrt(c*x^2+b*x+a).
606 ;; G&R 2.261 gives the following, where R = c*x^2+b*x+a and D =
607 ;; 4*a*b-b^2:
609 ;; c > 0:
610 ;; 1/sqrt(c)*log(2*sqrt(c*R)+2*c*x+b)
612 ;; c > 0, D > 0:
613 ;; 1/sqrt(c)*asinh((2*c*x+b)/sqrt(D))
615 ;; c < 0, D < 0:
616 ;; -1/sqrt(-c)*asin((2*c*x+b)/sqrt(-D))
618 ;; c > 0, D = 0:
619 ;; 1/sqrt(c)*log(2*c*x+b)
621 (defun den1 (c b a x)
622 (let* ((expr (add (mul 2 c x) b)) ;; expr = 2*c*x+b
623 (signc (checksigntm (power c -1)))
624 (signb (checksigntm (power b 2)))
625 (signdiscrim (signdis2 c b a signc signb)))
626 (when (and (eq signc '$positive)
627 (eq signdiscrim '$negative))
628 ;; c > 0, D > 0
629 (return-from den1 (augmult (mul* (power c -1//2)
630 `((%asinh)
631 ,(mul expr
632 (power (add (mul 4 c a)
633 (mul -1 b b))
634 -1//2)))))))
635 (when (and (eq signc '$positive)
636 (eq signdiscrim '$zero))
637 ;; c > 0, D = 0
638 (return-from den1 (augmult (mul* (power -1 expr)
639 (power c -1//2)
640 `((%log) ,expr)))))
641 (when (eq signc '$positive)
642 ;; c > 0
643 (return-from den1 (augmult (mul* (power c -1//2)
644 `((%log)
645 ,(add (mul 2
646 (power c 1//2)
647 (power (polfoo c b a x) 1//2))
648 expr))))))
649 (when (and (eq signc '$negative)
650 (eq signdiscrim '$positive))
651 ;; c < 0, D > 0
652 (return-from den1 (augmult (mul* -1
653 (power (mul -1 c) -1//2)
654 `((%asin)
655 ,(mul expr
656 (power (add (mul b b)
657 (mul -4 c a))
658 -1//2)))))))
659 (when (eq signc '$negative)
660 ;; c < 0. We try again, but flip the sign of the
661 ;; polynomial, and multiply by -%i.
662 (return-from den1 (augmult (mul (power -1 -1//2)
663 (den1 (mul -1 c)
664 (mul -1 b)
665 (mul -1 a)
666 x)))))))
668 ;; Compute sign of discriminant of the quadratic c*x^2+b*x+a. That
669 ;; is, the sign of b^2-4*c*a.
670 (defun signdiscr (c b a)
671 (checksigntm (simplifya (add (power b 2) (mul -4 c a)) nil)))
673 (defun askinver (a)
674 (checksigntm (inv a)))
676 (defun signdis1 (c b a)
677 (cond ((equal (mul b a) 0)
678 (if (and (equal b 0) (equal a 0))
679 '$zero
680 '$nonzero))
682 ;; Why are we checking the sign of (b^2-4*a*c)^2?
683 (checksigntm (power (add (mul b b) (mul -4 c a)) 2)))))
685 ;; Check sign of discriminant of c*x^2+b*x+a, but also taking into
686 ;; account the sign of c and b.
687 (defun signdis2 (c b a signc signb)
688 (cond ((equal signb '$zero)
689 (cond ((equal a 0) '$zero)
690 (t (let ((askinv (askinver a)))
691 (if (or (and (eq signc '$positive)
692 (eq askinv '$negative))
693 (and (eq signc '$negative)
694 (eq askinv '$positive)))
695 '$positive
696 '$negative)))))
697 (t (if (equal a 0)
698 '$positive
699 (signdiscr c b a)))))
701 (defun signdis3 (c b a signa)
702 (declare (special *ec-1*))
703 (cond ((equal b 0)
704 (if (equal (checksigntm *ec-1*) signa)
705 '$negative
706 '$positive))
707 (t (signdiscr c b a))))
709 ;; Integrate things like x^m*R^(p-1/2), p > 0, m > 0.
711 ;; I think pluspowfo1 = p - 1.
712 (defun nummnumn (poszpowlist pluspowfo1 p c b a x)
713 (declare (special *ec-1*))
714 (let ((expr (power (polfoo c b a x) (add p 1//2))) ;; expr = R^(p+1/2)
715 (expo *ec-1*) ;; expo = 1/c
716 (ex (power c -2))) ;; ex = 1/c^2
717 (prog ((result 0)
718 (controlpow (caar poszpowlist))
719 (coef (cadar poszpowlist))
720 count res1 res2 m partres)
721 #+nil (format t "p = ~A~%pluspowfo1 = ~A~%" p pluspowfo1)
722 (when (zerop controlpow)
723 ;; Integrate R^(p-1/2)
724 (setq result (augmult (mul coef (numn pluspowfo1 c b a x)))
725 count 1)
726 (go loop))
728 jump1
729 ;; Handle x*R^(p-1/2)
731 ;; G&R 2.260, m = 1
733 ;; integrate(x*R^(2*p-1),x) =
734 ;; R^(p+1/2)/(2*p+1)/c
735 ;; - b/2/c*integrate(sqrt(R^(2*p-1)),x)
736 (setq res1 (add (augmult (mul expr expo
737 (power (+ p p 1) -1)))
738 (augmult (mul -1 b 1//2 expo
739 (numn pluspowfo1 c b a x)))))
740 (when (equal controlpow 1)
741 (setq result (add result (augmult (mul coef res1)))
742 count 2)
743 (go loop))
745 jump2
746 ;; Handle x^2*R^(p-1/2)
748 ;; G&R 2.260, m = 2
750 ;; integrate(x^2*R^(2*p-1),x) =
751 ;; x*R^(p+1/2)/(2*p+2)/c
752 ;; - (2*p+3)*b/2/(2*p+2)/c*integrate(x*sqrt(R^(2*p-1)),x)
753 ;; - a/(2*p+2)/c*integrate(sqrt(R^(2*p-1)),x)
754 (setq res2 (add (augmult (mul* x expr expo
755 (inv (+ p p 2))))
756 (augmult (mul* b (+ p p 3)
757 '((rat) -1 4)
759 (inv (+ p p p 1
760 (* p p)
761 (* p p)))
762 expr))
763 (augmult (mul (inv (1+ p))
765 '((rat simp) 1 8)
766 (add (mul (power b 2)
767 (+ p p 3))
768 (mul -4 a c))
769 (numn pluspowfo1 c b a x)))))
770 (when (equal controlpow 2)
771 (setq result (add result (augmult (mul coef res2)))
772 count 3)
773 (go loop))
775 jump3
776 (setq count 4
777 m 3)
778 jump
779 ;; The general case: x^m*R^(p-1/2)
780 (setq partres
781 (let ((pro (inv (+ m p p))))
782 ;; pro = 1/(m+2*p)
784 ;; G&R 2.260, m = 2
786 ;; integrate(x^m*R^(2*p-1),x) =
787 ;; x^(m-1)*R^(p+1/2)/(m+2*p)/c
788 ;; - (2*m+2*p-1)*b/2/(m+2*p)/c*integrate(x^(m-1)*sqrt(R^(2*p-1)),x)
789 ;; - (m-1)*a/(m+2*p)/c*integrate(x^(m-2)*sqrt(R^(2*p-1)),x)
790 (add (augmult (mul (power x (1- m))
791 expr expo pro))
792 (augmult (mul -1 b (+ p p m m -1)
793 1//2 expo pro res2))
794 (augmult (mul -1 a (1- m)
795 expo pro res1)))))
796 (incf m)
797 (when (> m controlpow)
798 (setq result (add result (augmult (mul coef partres))))
799 (go loop))
801 jump4
802 (setq res1 res2
803 res2 partres)
804 (go jump)
806 loop
807 (setq poszpowlist (cdr poszpowlist))
808 (when (null poszpowlist) (return result))
809 (setq coef (cadar poszpowlist))
810 (setq controlpow (caar poszpowlist))
811 (when (equal count 4) (go jump4))
812 (when (equal count 1) (go jump1))
813 (when (equal count 2) (go jump2))
814 (go jump3))))
816 ;; Integrate R^(p+1/2)
817 (defun numn (p c b a x)
818 (declare (special *ec-1*))
819 (let ((exp1 *ec-1*) ;; exp1 = 1/c
820 (exp2 (add b (mul 2 c x))) ;; exp2 = b+2*c*x
821 (exp4 (add (mul 4 a c) (mul -1 b b))) ;; exp4 = 4*a*c-b^2
822 (exp5 (div 1 (1+ p)))) ;; exp5 = 1/(p+1)
823 (if (zerop p)
824 ;; integrate(sqrt(R),x)
826 ;; G&R 2.262 says
828 ;; integrate(sqrt(R),x) =
829 ;; (2*c*x+b)*sqrt(R)/4/c + del/8/c*integrate(1/sqrt(R),x)
831 ;; del = 4*a*c-b^2
832 (add (augmult (mul '((rat simp) 1 4)
833 exp1 exp2
834 (power (polfoo c b a x) 1//2)))
835 (augmult (mul '((rat simp) 1 8)
836 exp1 exp4
837 (den1 c b a x))))
839 ;; The general case
841 ;; G&R 2.260, eq. 2:
843 ;; integrate(sqrt(R^(2*p+1)),x) =
844 ;; (2*c*x+b)/4/(p+1)/c*R^(p+1/2)
845 ;; + (2*p+1)*del/8/(p+1)/c*integrate(sqrt(R^(2*p-1)),x)
846 (add (augmult (mul '((rat simp) 1 4)
847 exp1 exp5 exp2
848 (power (polfoo c b a x) (add p 1//2))))
849 (augmult (mul '((rat simp) 1 8)
850 exp1 exp5 (+ p p 1)
851 exp4
852 (numn (1- p) c b a x)))))))
854 (defun augmult (x)
855 ($multthru (simplifya x nil)))
857 ;; Integrate things like 1/x^m/R^(p+1/2), p > 0.
858 (defun denmdenn (negpowlist p c b a x)
859 (let ((exp1 (power (polfoo c b a x) (add 1//2 (- p))))) ;; exp1 = 1/R^(p-1/2)
860 (prog (result controlpow coef count res1 res2 m partres
861 (signa (checksigntm (simplifya a nil)))
862 ea-1)
863 (when (eq signa '$zero)
864 (return (noconstquad negpowlist p c b x)))
865 (setq result 0
866 controlpow (caar negpowlist)
867 ea-1 (power a -1))
868 (setq coef (cadar negpowlist))
869 (when (zerop controlpow)
870 ;; I'm not sure we ever get here because m = 0 is
871 ;; usually handled elsewhere.
872 (setq result (augmult (mul coef (denn p c b a x)))
873 count 1)
874 (go loop))
876 jump1
877 ;; Handle 1/x/R^(p+1/2)
878 (setq res1 (den1denn p c b a x))
879 (when (equal controlpow 1)
880 (setq result (add result (augmult (mul coef res1)))
881 count 2)
882 (go loop))
884 jump2
885 ;; Handle 1/x^2/R^(p+1/2)
887 ;; G&R 2.268, m = 2
889 ;; integrate(1/x^2/R^(p+1/2),x) =
890 ;; -1/a/x/sqrt(R^(2*p-1))
891 ;; -(2*p+1)*b/2/a*integrate(1/x/sqrt(R^(2*p+1)),x)
892 ;; -2*p*c/a*integrate(1/sqrt(R^(2*p+1)),x)
893 (setq res2 (add (augmult (mul -1 ea-1 (power x -1) exp1))
894 (augmult (mul -1 b (+ 1 p p) 1//2
895 ea-1 (den1denn p c b a x)))
896 (augmult (mul -2 p c ea-1 (denn p c b a x)))))
897 (when (equal controlpow 2)
898 (setq result (add result (augmult (mul coef res2)))
899 count 3)
900 (go loop))
902 jump3
903 (setq count 4
904 m 3)
906 jump
907 ;; General case 1/x^m/R^(p+1/2)
909 ;; G&R 2.268
911 ;; integrate(1/x^2/R^(p+1/2),x) =
912 ;; -1/(m-1)/a/x^(m-1)/sqrt(R^(2*p-1))
913 ;; -(2*p+2*m-3)*b/2/(m-1)/a*integrate(1/x^(m-1)/sqrt(R^(2*p+1)),x)
914 ;; -(2*n+m-2)*c/(m-1)/a*integrate(1/x^(m-2)/sqrt(R^(2*p+1)),x)
915 (setq partres
916 (let ((exp2 (div -1 (1- m))))
917 ;; exp2 = -1/(m-1)
918 (add (augmult (mul exp2 ea-1
919 (power x (1+ (- m)))
920 exp1))
921 (augmult (mul b (+ p p m m -3) 1//2
922 ea-1 exp2 res2))
923 (augmult (mul c ea-1 exp2
924 (+ p p m -2) res1)))))
925 (incf m)
926 (when (> m controlpow)
927 (setq result (add result (augmult (mul coef partres))))
928 (go loop))
930 jump4
931 (setq res1 res2 res2 partres)
932 (go jump)
934 loop
935 (setq negpowlist (cdr negpowlist))
936 (when (null negpowlist) (return result))
937 (setq coef (cadar negpowlist)
938 controlpow (caar negpowlist))
939 (when (equal count 4) (go jump4))
940 (when (equal count 1) (go jump1))
941 (when (equal count 2) (go jump2))
942 (go jump3))))
944 ;; Integral of 1/(c*x^2+b*x+a)^(n), n > 0. p = n + 1/2.
946 ;; See G&R 2.263 formula 3.
948 ;; Let R = c*x^2+b*x+a.
949 (defun denn (p c b a x)
950 (let ((signdisc (signdis1 c b a))
951 (exp1 (add b (mul 2 c x))) ;; exp1 = b + 2*c*x;
952 (exp2 (add (mul 4 a c) (mul b b -1))) ;; exp2 = (4*a*c-b^2)
953 (exp3 (inv (+ p p -1))) ;; exp3 = 1/(2*p-1)
954 (*ec-1* (inv c)))
955 (declare (special *ec-1*))
956 #+nil (format t "signdisc = ~A~%p = ~A~%" signdisc p)
957 (cond ((and (eq signdisc '$zero) (zerop p))
958 ;; 1/sqrt(R), and R has duplicate roots. That is, we have
959 ;; 1/sqrt(c*(x+b/(2c))^2) = 1/sqrt(c)/sqrt((x+b/2/c)^2).
961 ;; We return 1/sqrt(c)*log(x+b/2/c). Shouldn't we return
962 ;; 1/c*log(|x+b/2/c|)?
963 (augmult (mul* (power *ec-1* 1//2)
964 `((%log) ,(add x (mul b 1//2 *ec-1*))))))
965 ((and (eq signdisc '$zero) (plusp p))
966 ;; 1/sqrt(R^(2*p+1)), with duplicate roots.
968 ;; That is, 1/sqrt((c*(x+b/2/c)^(2)^(2*p+1))), or
969 ;; 1/c^(p+1/2)/(x+b/2/c)^(2*p+1). So the result is
970 ;; -1/2/p*c^(-p-1/2)/(x+b/2/c)^(2*p)
971 (augmult (mul (div -1 (+ p p))
972 (power c (mul -1//2 (+ p p 1)))
973 (power (add x (mul b 1//2 *ec-1*)) (* -2 p)))))
974 ((zerop p)
975 ;; 1/sqrt(R)
976 (den1 c b a x))
977 ((equal p 1)
978 ;; 1/sqrt(R^3).
980 ;; G&R 2.264 eq. 5 says
982 ;; 2*(2*c*x+b)/del/sqrt(R).
983 (augmult (mul 2 exp1 (inv exp2)
984 (power (polfoo c b a x) -1//2))))
986 ;; The general case. G&R 2.263 eq. 3.
988 ;; integrate(1/sqrt(R^(2*p+1)),x) =
989 ;; 2*(2*c*x+b)/(2*p-1)/c/sqrt(R^(2*p-1))
990 ;; + 8*(p-1)*c/(2*p-1)/del*integrate(1/sqrt(R^(2*p-1)),x)
992 ;; where del = 4*a*c-b^2.
993 (add (augmult (mul 2 exp1
994 exp3 (inv exp2)
995 (power (polfoo c b a x)
996 (add 1//2 (- p)))))
997 (augmult (mul 8 c (1- p)
998 exp3 (inv exp2)
999 (denn (1- p) c b a x))))))))
1001 ;; Integral of 1/x/(c*x^2+b*x+a)^(p+1/2), p > 0.
1002 (defun den1denn (p c b a x)
1003 (let ((signa (checksigntm (power a 2))) ;; signa = sign of a^2
1004 (ea-1 (inv a))) ;; ea-1 = 1/a
1005 (cond ((eq signa '$zero)
1006 ;; This is wrong because noconstquad expects a
1007 ;; powercoeflist for th first arg. But I don't think
1008 ;; there's any way to get here from anywhere. I'm pretty
1009 ;; sure den1denn is never called with a equal to 0.
1010 (noconstquad 1 p c b x))
1011 ((zerop p)
1012 ;; 1/x/sqrt(c*x^2+b*x+a)
1013 (den1den1 c b a x))
1015 ;; The general case. See G&R 2.268:
1017 ;; R=(c*x^2+b*x+a)
1019 ;; integrate(1/x/sqrt(R^(2*p+1)),x) =
1021 ;; 1/(2*p-1)/a/sqrt(R^(2*p-1))
1022 ;; - b/2/a*integrate(1/sqrt(R^(2*p+1)),x)
1023 ;; + 1/a*integrate(1/x/sqrt(R^(2*p-1)),x)
1024 (add (augmult (mul (inv (+ p p -1))
1025 ea-1
1026 (power (polfoo c b a x)
1027 (add 1//2 (- p)))))
1028 (augmult (mul ea-1 (den1denn (1- p) c b a x)))
1029 (augmult (mul -1 1//2 ea-1 b (denn p c b a x))))))))
1031 ;; Integral of 1/x/sqrt(c*x^2+b*x+a).
1033 ;; G&R 2.266 gives the following results, where del is the
1034 ;; discriminant 4*a*c-b^2. (I think this is the opposite of what we
1035 ;; compute below for the discriminant.)
1037 (defun den1den1 (c b a x)
1038 (let ((exp2 (add (mul b x) a a)) ; exp2 = b*x+2*a
1039 (exp3 (inv (simplify (list '(mabs) x))))) ; exp3 = 1/abs(x)
1040 (prog (signdiscrim
1041 (condition (add (mul b x) a a))
1042 (signa (checksigntm (simplifya a nil)))
1043 exp1)
1044 (when (eq signa '$zero)
1045 (return (noconstquad '((1 1)) 0 c b x)))
1046 (setq signdiscrim (signdis3 c b a signa)
1047 exp1 (power a (inv -2)))
1048 #+nil (format t "signa = ~A~%signdiscrim = ~A~%" signa signdiscrim)
1050 (when (and (eq signa '$positive)
1051 (eq signdiscrim '$negative))
1052 ;; G&R case a > 0, del > 0
1054 ;; -1/sqrt(a)*asinh((2*a+b*x)/x/sqrt(del)
1055 (return (mul* -1 exp1
1056 `((%asinh)
1057 ,(augmult (mul exp2 exp3
1058 (power (add (mul 4 a c)
1059 (mul -1 b b))
1060 -1//2)))))))
1061 (when (and (eq signdiscrim '$zero)
1062 (eq signa '$positive))
1063 ;; G&R case del = 0, a > 0
1065 ;; 1/sqrt(a)*log(x/(2*a+b*x))
1066 (return (mul* (power -1 condition)
1067 -1 exp1
1068 `((%log) ,(augmult (mul exp3 exp2))))))
1069 (when (eq signa '$positive)
1070 ;; G&R case a > 0
1072 ;; -1/sqrt(a)*log((2*a+b*x+2*sqrt(a*R))/x)
1074 ;; R = c*x^2+b*x+a.
1075 (return (mul* -1 exp1
1076 `((%log)
1077 ,(add b (mul 2 a exp3)
1078 (mul 2 exp3
1079 (power a 1//2)
1080 (power (polfoo c b a x) 1//2)))))))
1081 (when (and (eq signa '$negative)
1082 (eq signdiscrim '$positive))
1083 ;; G&R case a < 0, del < 0
1085 ;; 1/sqrt(-a)*asin((2*a+b*x)/x/sqrt(b^2-4*a*c))
1086 (return (mul* (power (mul -1 a) -1//2)
1087 `((%asin)
1088 ,(augmult (mul exp2 exp3
1089 (power (add (mul b b) (mul -4 a c)) -1//2)))))))
1090 ;; I think this is the case of a < 0. We flip the sign of
1091 ;; coefficients of the quadratic to make a positive, and
1092 ;; multiply the result by 1/%i.
1094 ;; Why can't we use the case a < 0 in G&R 2.266:
1096 ;; 1/sqrt(-a)*atan((2*a+b*x)/2/sqrt(-a)/sqrt(R)
1098 ;; FIXME: Why the multiplication by -1?
1099 (return (mul #+nil -1
1100 (power -1 1//2)
1101 (den1den1 (mul -1 c) (mul -1 b) (mul -1 a) x))))))
1103 ;; Integral of d/x^m/(c*x^2+b*x)^(p+1/2), p > 0. The values of m and
1104 ;; d are in NEGPOWLIST.
1105 (defun noconstquad (negpowlist p c b x)
1106 (let ((exp1 (inv (+ p p 1))) ;; exp1 = 1/(2*p+1)
1107 (exp2 (inv x)) ;; exp2 = 1/x
1108 (exp3 (- p))) ;; exp3 = -p
1109 (prog (result controlpow coef count res1 signb m partres eb-1)
1110 (setq signb (checksigntm (power b 2)))
1111 (when (eq signb '$zero)
1112 (return (trivial1 negpowlist p c x)))
1113 (setq result 0
1114 controlpow (caar negpowlist)
1115 coef (cadar negpowlist)
1116 eb-1 (inv b))
1117 (when (zerop controlpow)
1118 ;; Not sure if we ever actually get here. The case of
1119 ;; m=0 is usually handled at a higher level.
1120 (setq result (augmult (mul coef (denn p c b 0 x)))
1121 count 1)
1122 (go loop))
1123 jump1
1124 ;; Handle 1/x/R^(p+1/2)
1126 ;; G&R 2.268, a = 0, m = 1
1128 ;; integrate(1/x^m/sqrt(R^(2*p+1)),x) =
1129 ;; -2/(2*p+1)/b/x/sqrt(R^(2*p-1))
1130 ;; -4*p*c/(2*p+1)/b*integrate(1/sqrt(R^(2*p+1)),x)
1131 (setq res1 (add (augmult (mul -2 exp1 eb-1 exp2
1132 (power (polfoo c b 0 x)
1133 (add 1//2 exp3))))
1134 (augmult (mul -4 p c exp1 eb-1 (denn p c b 0 x)))))
1135 (when (equal controlpow 1)
1136 (setq result (add result (augmult (mul coef res1)))
1137 count 2)
1138 (go loop))
1139 jump2 (setq count 3 m 2)
1140 jump
1141 ;; Handle general case 1/x^m/R^(p+1/2)
1143 ;; G&R 2.268, a = 0
1145 ;; integrate(1/x^m/sqrt(R^(2*p+1)),x) =
1146 ;; -2/(2*p+2*m-1)/b/x^m/sqrt(R^(2*p+1))
1147 ;; -(4*p+2*m-2)*c/(2*p+2*m-1)/b*integrate(1/x^(m-1)/sqrt(R^(2*p+1)),x)
1148 (setq partres
1149 (add (augmult (mul -2 (inv (+ p p m m -1))
1150 eb-1
1151 (power x (mul -1 m))
1152 (power (polfoo c b 0 x)
1153 (add 1//2 exp3))))
1154 (augmult (mul -2 c (+ p p m -1)
1155 eb-1
1156 (inv (+ p p m m -1))
1157 res1))))
1158 (incf m)
1159 (when (> m controlpow)
1160 (setq result (add result (augmult (mul coef partres))))
1161 (go loop))
1162 jump3
1163 (setq res1 partres)
1164 (go jump)
1165 loop
1166 (setq negpowlist (cdr negpowlist))
1167 (when (null negpowlist) (return result))
1168 (setq coef (cadar negpowlist)
1169 controlpow (caar negpowlist))
1170 (when (= count 3) (go jump3))
1171 (when (= count 1) (go jump1))
1172 (go jump2))))
1174 ;; The trivial case of d/x^m/(c*x^2+b*x+a)^(p+1/2), p > 0, and a=b=0.
1175 (defun trivial1 (negpowlist p c x)
1176 (cond ((null negpowlist) 0)
1178 ;; d/x^m/c^(p+1/2)/x^(2*p+1) = d/c^(p+1/2)/x^(m+2*p+1)
1179 ;; The integral is obviously
1181 ;; -d/c^(p+1/2)/x^(m+2*p)/(m+2*p)
1182 (add (augmult (mul (power x
1183 (add (* -2 p)
1184 (mul -1 (caar negpowlist))))
1185 (cadar negpowlist)
1186 (power c (add (- p) -1//2))
1187 (inv (add (* -2 p)
1188 (mul -1 (caar negpowlist))))))
1189 (trivial1 (cdr negpowlist) p c x)))))
1191 ;; Integrate pl(x)/(c*x^2+b*x+a)^(p+1/2) where pl(x) is a polynomial
1192 ;; and p > 0. The polynomial is given in POSZPOWLIST.
1193 (defun nummdenn (poszpowlist p c b a x)
1194 (declare (special *ec-1*))
1195 (let ((exp1 (inv (+ p p -1))) ;; exp1 = 1/(2*p-1)
1196 (exp2 (power (polfoo c b a x) (add 1//2 (- p)))) ;; exp2 = (a*x^2+b*x+c)^(p-1/2)
1197 (exp3 (add (mul 4 a c) (mul -1 b b))) ;; exp3 = (4*a*c-b^2) (negative of the discriminant)
1198 (exp4 (add x (mul b 1//2 *ec-1*))) ;; exp4 = x+b/2/c
1199 (exp5 (power c -2)) ;; exp5 = 1/c^2
1200 (exp6 (+ 2 (* -2 p))) ;; exp6 = -2*p+2
1201 (exp7 (1+ (* -2 p)))) ;; exp7 = -2*p+1
1202 (prog (result controlpow coef count res1 res2 m partres signdiscrim)
1203 ;; Let S=R^(p+1/2).
1205 ;; We are trying to integrate pl(x)/S
1206 ;; = (p0 + p1*x + p2*x^3 + ...)/S
1208 ;; So the general term is pm*x^m/S. This integral is given by
1209 ;; G&R 2.263, eq.1:
1211 ;; integrate(x^m/sqrt(R^(2*p+1)),x) =
1213 ;; x^(m-1)/(m-2*n)/sqrt(R^(2*p-1))
1214 ;; - (2*m-2*n-1)*b/2/(m-2*n)/c*integrate(x^(m-1)/sqrt(R^(2*p+1)),x)
1215 ;; - (m-1)*a/(m-2*n)/c*integrate(x^(m-2)/sqrt(R^(2*p+1)),x)
1217 ;; Thus the integration of x^m/S involves x^(m-1)/S and x^(m-2)/S.
1219 ;; I think what this loop does is integrate x^(m-1)/S and
1220 ;; x^(m-2)/S, and remember them so that we can integrate x^m/S
1221 ;; without having to do all the integrals again. Thus we
1222 ;; start with the constant term and work our way up to the
1223 ;; highest term.
1225 ;; I think this would be much simpler if we used memoization
1226 ;; and start with the highest power. Then all the
1227 ;; intermediate forms will have been computed, and we can just
1228 ;; simply integrate all the lower terms by looking them up.
1229 (setq result 0
1230 controlpow (caar poszpowlist))
1231 (setq coef (cadar poszpowlist)
1232 signdiscrim (signdis1 c b a))
1233 ;; We're looking at coef*x^controlpow/R^(p+1/2) right now.
1234 (when (zerop controlpow)
1235 ;; Actually it's coef/R^(p+1/2), so handle that now, go
1236 ;; to the next coefficient.
1237 (setq result (augmult (mul coef (denn p c b a x)))
1238 count 1)
1239 (go loop))
1241 jump1
1243 ;; This handles the case coef*x/R^(p+1/2)
1245 ;; res1 = -1/c/(2*p-1)*R^(p-1/2)
1246 ;; -b/2/c*integrate(R^(p+1/2),x)
1248 (setq res1
1249 (add (augmult (mul -1 *ec-1* exp1 exp2))
1250 (augmult (mul b -1//2 *ec-1* (denn p c b a x)))))
1251 (when (= controlpow 1)
1252 ;; Integrate coef*x/R^(p+1/2).
1254 ;; x/R^(p+1/2) is in res1.
1255 (setq result (add result (augmult (mul coef res1)))
1256 count 2)
1257 (go loop))
1258 jump2
1259 ;; This handles the case coef*x^2/R^(p+1/2)
1260 (when (and (plusp p) (not (eq signdiscrim '$zero)))
1261 ;; p > 0, no repeated roots
1262 (setq res2
1263 (add (augmult (mul *ec-1* exp1 (inv exp3) exp2
1264 (add (mul 2 a b)
1265 (mul 2 b b x)
1266 (mul -4 a c x))))
1267 (augmult (mul *ec-1* (inv exp3) exp1
1268 (add (mul 4 a c)
1269 (mul 2 b b p)
1270 (mul -3 b b))
1271 (denn (+ p -1)
1272 c b a x))))))
1273 (when (and (zerop p) (not (eq signdiscrim '$zero)))
1274 ;; x^2/sqrt(R), no repeated roots.
1276 ;; G&R 2.264, eq. 3
1278 ;; integrate(x^2/sqrt(R),x) =
1279 ;; (x/2/c-3*b/4/c^2)*sqrt(R)
1280 ;; + (3*b^2/8/c^2-a/2/c)*integrate(1/sqrt(R),x)
1282 ;; = (2*c*x-3*b)/4/c^2*sqrt(R)
1283 ;; + (3*b^2-4*a*c)/8/c^2*integrate(1/sqrt(R),x)
1284 (setq res2
1285 (add (augmult (mul '((rat simp) 1 4)
1286 exp5
1287 (add (mul 2 c x)
1288 (mul -3 b))
1289 (power (polfoo c b a x)
1290 1//2)))
1291 (augmult (mul '((rat simp) 1 8)
1292 exp5
1293 (add (mul 3 b b)
1294 (mul -4 a c))
1295 (den1 c b a x))))))
1296 (when (and (zerop p) (eq signdiscrim '$zero))
1297 ;; x^2/sqrt(R), repeated roots
1299 ;; With repeated roots, R is really of the form
1300 ;; c*x^2+b*x+b^2/4/c = c*(x+b/2/c)^2. So we have
1302 ;; x^2/sqrt(c)/(x+b/2/c)
1304 ;; And the integral of this is
1306 ;; b^2*log(x+b/2/c)/4/c^(5/2) + x^2/2/sqrt(c) - b*x/2/c^(3/2).
1308 (setq res2
1309 ;; (add (augmult (mul* b b (list '(rat) 1 4)
1310 ;; (power c -3)
1311 ;; (list '(%log) exp4)))
1312 ;; (augmult (mul *ec-1* 1//2 (power exp4 2)))
1313 ;; (augmult (mul -1 b x exp5)))
1314 (add (augmult (mul* b b '((rat) 1 4)
1315 (power c (div -5 2))
1316 `((%log) ,exp4)))
1317 (augmult (mul (power c -1//2) 1//2 (power x 2)))
1318 (augmult (mul -1//2 b x (power c (div -3 2)))))))
1320 (when (and (= p 1) (eq signdiscrim '$zero))
1321 ;; x^2/sqrt(R^3), repeated roots
1323 ;; As above, we have c*(x+b/2/c)^2, so
1325 ;; x^2/sqrt(R^3) = x^2/sqrt(c^3)/(x+b/2/c)^3
1327 ;; And the integral is
1329 ;; log(x+b/2/c)/c^(3/2) + z*(3*z+4*x)/2/c^(3/2)/(z+x)^2
1331 ;; where z = b/2/c.
1332 (setq res2
1333 ;; (add (augmult (mul* *ec-1* (list '(%log) exp4)))
1334 ;; (augmult (mul b exp5 (power exp4 -1)))
1335 ;; (augmult (mul (list '(rat) -1 8)
1336 ;; (power c -3)
1337 ;; b b (power exp4 -2))))
1338 (add (augmult (mul* (power c (div -3 2)) `((%log) ,exp4)))
1339 (augmult (mul b x (power c (div -5 2)) (power exp4 -2)))
1340 (augmult (mul (div 3 8)
1341 (power c (div -7 2))
1342 b b (power exp4 -2))))))
1344 (when (and (eq signdiscrim '$zero) (> p 1))
1345 ;; x^2/R^(p+1/2), repeated roots, p > 1
1347 ;; As above, we have R=c*(x+b/2/c)^2, so the integral is
1349 ;; x^2/(x+b/2/c)^(2*p+1)/c^(p+1/2).
1351 ;; Let d = b/2/c. Then write x^2 =
1352 ;; (x+d)^2-2*d*(x+d)+d^2. The integrand becomes
1354 ;; 1/(x+d)^(2*p-1) - 2*d/(x+d)^(2*p) + d^2/(x+d)^(2*p+1)
1356 ;; whose integral is
1358 ;; 1/(2*p-2)/(x+d)^(2*p-2) - 2*d/(2*p-1)/(x+d)^(2*p-1)
1359 ;; + d^2/(2*p)/(x+d)^(2*p)
1361 ;; And don't forget the factor c^(-p-1/2). Finally,
1363 ;; 1/c^(p+1/2)/(2*p-2)/(x+d)^(2*p-2)
1364 ;; - b/c^(p+3/2)/(2*p-1)/(x+d)^(2*p-1)
1365 ;; + b^2/8/c^(p+5/2)/p/(x+d)^(2*p)
1366 (setq res2
1367 ;; (add (augmult (mul *ec-1*
1368 ;; (power exp4 exp6)
1369 ;; (inv exp6)))
1370 ;; (augmult (mul -1 b exp5 (inv exp7)
1371 ;; (power exp4 exp7)))
1372 ;; (augmult (mul b b (list '(rat) -1 8)
1373 ;; (power c -3)
1374 ;; (inv p)
1375 ;; (power exp4
1376 ;; (* -2 p)))))
1377 (add (augmult (mul (inv (power c (add p 1//2)))
1378 (power exp4 exp6)
1379 (inv exp6)))
1380 (augmult (mul -1 b
1381 (inv (power c (add p (div 3 2))))
1382 (inv exp7)
1383 (power exp4 exp7)))
1384 (augmult (mul b b '((rat simp) -1 8)
1385 (inv (power c (add p (div 5 2))))
1386 (inv p)
1387 (power exp4
1388 (* -2 p)))))))
1389 (when (= controlpow 2)
1390 ;; x^2/R^(p+1/2)
1392 ;; We computed this result above, so just multiply by
1393 ;; the coefficient and add it to the result.
1394 (setq result (add result (augmult (mul coef res2)))
1395 count 3)
1396 (go loop))
1397 jump3
1398 (setq count 4
1399 m 3)
1400 jump
1401 ;; coef*x^m/R^(p+1/2). m >= 3
1402 (setq partres
1403 (let ((denom (+ p p (- m))))
1404 ;; denom = 2*p-m
1406 ;; G&R 2.263, eq 1:
1408 ;; integrate(x^m/sqrt(R^(2*p+1)),x) =
1409 ;; x^(m-1)/c/(m-2*p)/sqrt(R^(2*p-1))
1410 ;; - b*(2*m-2*p-1)/2/(m-2*p)*integrate(x^(m-1)/sqrt(R^(2*p+1)),x)
1411 ;; + (m-1)*a/(m-2*p)/c*integrate(x^(m-2)/sqrt(R^(2*p+1)),x)
1413 ;; The two integrals here were computed above in res2
1414 ;; and res1, respectively.
1415 (add (augmult (mul* (power x (1- m))
1416 *ec-1* (div -1 denom)
1417 (power (polfoo c b a x)
1418 (add 1//2 (- p)))))
1419 (augmult (mul b (+ p p 1 (* -2 m))
1420 -1//2
1421 *ec-1* (inv denom) res2))
1422 (augmult (mul a (1- m) *ec-1* (inv denom) res1)))))
1424 ;; Move on to next higher power
1425 (incf m)
1426 (when (> m controlpow)
1427 (setq result (add result (augmult (mul coef partres))))
1428 (go loop))
1429 jump4
1430 (setq res1 res2
1431 res2 partres)
1432 (when (= m (+ p p))
1433 (setq partres
1434 (let ((expr (nummdenn (list (list (1- m) 1)) p c b a x)))
1435 (add (mul x expr)
1436 (mul -1 (distrint (cdr ($expand expr)) x)))))
1437 (go on))
1438 (go jump)
1439 loop
1440 ;; Done with first term of polynomial. Exit if we're done.
1441 (setq poszpowlist (cdr poszpowlist))
1442 (when (null poszpowlist) (return result))
1443 (setq coef (cadar poszpowlist) controlpow (caar poszpowlist))
1444 (when (= count 4) (go jump4))
1445 (when (= count 1) (go jump1))
1446 (when (= count 2) (go jump2))
1447 (go jump3))))
1449 ;; Integrate functions of the form coef*R^(pow-1/2)/x^m. NEGPOWLIST
1450 ;; contains the list of coef's and m's.
1451 (defun denmnumn (negpowlist pow c b a x)
1452 (let ((exp1 (inv x)) ;; exp1 = 1/x
1453 (exp2 (+ pow pow -1))) ;; exp2 = 2*pow-1
1454 (prog (result controlpow coef count res1 res2 m partres signa ea-1
1455 (p (+ pow pow -1))) ;; p = 2*pow-1.
1456 ;; NOTE: p is not the same here as in other routines!
1457 ;; Why is there this special case for negpowlist?
1458 ;; CASE1 calls this in this way.
1459 (when (eq (car negpowlist) 't)
1460 (setq negpowlist (cdr negpowlist))
1461 (go there))
1462 (setq signa (checksigntm (power a 2)))
1463 (when (eq signa '$zero)
1464 (return (nonconstquadenum negpowlist p c b x)))
1465 (setq ea-1 (inv a))
1466 there
1467 (setq result 0
1468 controlpow (caar negpowlist)
1469 coef (cadar negpowlist))
1470 (when (zerop controlpow)
1471 ;; integrate(sqrt(R)).
1472 ;; I don't think we can normally get here.
1473 (setq result (augmult (mul coef
1474 (numn (add (mul p 1//2) 1//2)
1475 c b a x)))
1476 count 1)
1477 (go loop))
1478 jump1
1479 ;; Handle integrate(sqrt(R^(2*pow-1))/x),x
1480 (setq res1 (den1numn pow c b a x))
1481 (when (equal controlpow 1)
1482 (setq result (add result (augmult (mul coef res1)))
1483 count 2)
1484 (go loop))
1485 jump2
1486 ;; Handle integrate(sqrt(R^(2*pow-1))/x^2,x)
1487 (unless (= p 1)
1488 ;; integrate(sqrt(R^(2*pow-1))/x^2,x)
1490 ;; We can use integration by parts to get
1492 ;; integrate(sqrt(R^(2*pow-1))/x^2,x) =
1493 ;; -R^(pow-1/2)/x
1494 ;; + (2*pow-1)*b/2*integrate(sqrt(R^(2*pow-3))/x,x)
1495 ;; + (2*pow-1)*c*integrate(sqrt(R^(2*pow-3)),x)
1496 (setq res2
1497 (add (augmult (mul -1 exp1
1498 (power (polfoo c b a x)
1499 (add pow -1//2))))
1500 (augmult (mul b (div exp2 2)
1501 (den1numn (1- pow) c b a x)))
1502 (augmult (mul c exp2 (numn (- pow 2) c b a x))))))
1503 (when (= p 1)
1504 ;; integrate(sqrt(R)/x^2,x)
1506 ;; G&R 2.267, eq. 2
1508 ;; integrate(sqrt(R)/x^2,x) =
1509 ;; -sqrt(R)/x
1510 ;; + b/2*integrate(1/x/sqrt(R),x)
1511 ;; + c*integrate(1/sqrt(R),x)
1513 (setq res2 (add (augmult (mul -1 (power (polfoo c b a x) 1//2)
1514 exp1))
1515 (augmult (mul b 1//2 (den1den1 c b a x)))
1516 (augmult (mul c (den1 c b a x))))))
1517 (when (equal controlpow 2)
1518 (setq result (add result (augmult (mul coef res2)))
1519 count 3)
1520 (go loop))
1521 jump3
1522 (setq count 4
1523 m 3)
1524 jump
1525 ;; The general case sqrt(R^(2*p-1))/x^m
1527 ;; G&R 2.265
1529 ;; integrate(sqrt(R^(2*p-1))/x^m,x) =
1530 ;; -sqrt(R^(2*p+1))/(m-1)/a/x^(m-1)
1531 ;; + (2*p-2*m+3)*b/2/(m-1)/a*integrate(sqrt(R^(2*p-3))/x^(m-1),x)
1532 ;; + (2*p-m+2)*c/(m-1)/a*integrate(sqrt(R^(2*n-3))/x^(m-2),x)
1534 ;; NOTE: The p here is 2*pow-1. And we're
1535 ;; integrating R^(pow-1/2).
1537 (setq partres
1538 (add (augmult (mul (div -1 (1- m))
1539 ea-1
1540 (power x (1+ (- m)))
1541 (power (polfoo c b a x)
1542 (add (div p 2) 1))))
1543 (augmult (mul (inv (+ m m -2))
1544 ea-1 b
1545 (+ p 4 (* -2 m))
1546 res2))
1547 (augmult (mul c ea-1
1548 (+ p 3 (- m))
1549 (inv (1- m)) res1))))
1550 (incf m)
1551 (when (> m controlpow)
1552 (setq result (add result (augmult (mul coef partres))))
1553 (go loop))
1554 jump4
1555 (setq res1 res2
1556 res2 partres)
1557 (go jump)
1558 loop
1559 (setq negpowlist (cdr negpowlist))
1560 (when (null negpowlist) (return result))
1561 (setq coef (cadar negpowlist)
1562 controlpow (caar negpowlist))
1563 (when (= count 4)
1564 (go jump4))
1565 (when (= count 1)
1566 (go jump1))
1567 (when (= count 2)
1568 (go jump2))
1569 (go jump3))))
1571 ;; Like denmnumn, but a = 0.
1572 (defun nonconstquadenum (negpowlist p c b x)
1573 (prog (result coef m)
1574 (cond ((equal p 1)
1575 (return (case1 negpowlist c b x))))
1576 (setq result 0)
1577 loop
1578 (setq m (caar negpowlist)
1579 coef (cadar negpowlist))
1580 (setq result (add result (augmult (mul coef (casegen m p c b x))))
1581 negpowlist (cdr negpowlist))
1582 (cond ((null negpowlist) (return result)))
1583 (go loop)))
1585 ;; Integrate (c*x^2+b*x)^(p-1/2)/x^m
1586 (defun casegen (m p c b x)
1587 (let ((exp1 (power (polfoo c b 0 x) (div p 2))) ;; exp1 = R^(p/2)
1588 (exp3 (power x (1+ (- m))))) ;; exp3 = 1/x^(m-1)
1589 (cond ((= p 1)
1590 ;; sqrt(c*x^2+b*x)/x^m
1591 (case1 (list (list m 1)) c b x))
1592 ((zerop m)
1593 ;; (c*x^2+b*x)^(p-1/2)
1594 (case0 p c b x))
1595 ((= m (1+ p))
1596 ;; (c*x^2+b*x)^(p-1/2)/x^(p+1)
1597 (add (augmult (mul -1 exp1 (inv (1- m)) exp3))
1598 (augmult (mul b 1//2 (casegen (1- m) (- p 2) c b x)))
1599 (augmult (mul c (casegen (- m 2) (- p 2) c b x)))))
1600 ((= m 1)
1601 ;; (c*x^2+b*x)^(p-1/2)/x
1603 (add (augmult (mul (inv p) exp1))
1604 (augmult (mul b 1//2 (case0 (- p 2) c b x)))))
1606 ;; (c*x^2+b*x)^(p-1/2)/x^m
1607 (add (augmult (mul -1 exp1 (inv (- m (1+ p))) exp3))
1608 (augmult (mul -1 p b 1//2 (inv (- m (1+ p)))
1609 (casegen (1- m) (- p 2) c b x))))))))
1611 ;; Integrate things like sqrt(c*x^2+b*x))/x^m.
1612 (defun case1 (negpowlist c b x)
1613 (declare (special *ec-1*))
1614 (let ((exp1 (power c -1//2)) ;; exp1 = 1/sqrt(c)
1615 (eb-1 (inv b))) ;; eb-1 = 1/b
1616 (prog ((result 0) (controlpow (caar negpowlist)) (coef (cadar negpowlist))
1617 m1 count res1 res2 m signc signb partres res)
1618 (setq m1 (- controlpow 2))
1619 (when (zerop controlpow)
1620 (setq result (augmult (mul coef (case0 1 c b x)))
1621 count 1)
1622 (go loop))
1623 jump1
1624 ;; sqrt(R)/x
1625 (when (= controlpow 1)
1626 (setq result
1627 (add result
1628 (augmult (mul coef (den1numn 1 c b 0 x))))
1629 count 2)
1630 (go loop))
1631 jump2
1632 ;; sqrt(R)/x^2
1633 (when (= controlpow 2)
1634 (setq result
1635 (add result
1636 (augmult (mul coef
1637 (denmnumn '(t (2 1)) 1 c b 0 x))))
1638 count 3)
1639 (go loop))
1640 jump3
1641 (setq signb (checksigntm (power b 2)))
1642 (when (eq signb '$zero)
1643 (setq count 5)
1644 (go jump5))
1645 (setq count 4
1647 signc (checksigntm *ec-1*))
1648 (when (eq signc '$positive)
1649 (setq res
1650 (augmult (mul* 2 exp1
1651 `((%log)
1652 ,(add (power (mul c x) 1//2)
1653 (power (add b (mul c x)) 1//2))))))
1654 (go jump4))
1655 (setq res
1656 (augmult (mul* 2 exp1
1657 `((%atan)
1658 ,(power (mul c x
1659 (inv (add b (mul -1 c x))))
1660 1//2)))))
1661 jump4
1662 (incf m)
1663 (setq res (add (augmult (mul -2 (power (polfoo c b 0 x) 1//2)
1664 eb-1 (inv (+ m m -1))
1665 (power x (- m))))
1666 (augmult (mul (div -2 (+ m m -1))
1667 c (1- m) eb-1 res))))
1668 (when (= m m1)
1669 (setq res2 res)
1670 (go jump4))
1671 (when (= (1- m) m1)
1672 (if (null res2)
1673 (return nil))
1674 (setq res1 res
1675 partres (add (augmult (mul -1
1676 (power (polfoo c b 0 x) 1//2)
1677 (r1m m)
1678 (power x (- m))))
1679 (augmult (mul b 1//2 (r1m m) res1))
1680 (augmult (mul c (r1m m) res2))))
1681 (go on))
1682 (go jump4)
1683 jump5
1684 (setq m controlpow)
1685 (when (zerop m)
1686 (setq partres (mul* exp1 `((%log) ,x)))
1687 (go on))
1688 (setq partres (mul -1 exp1 (power x (- m)) (r1m m)))
1690 (setq result (add result (augmult (mul coef partres))))
1691 loop
1692 (setq negpowlist (cdr negpowlist))
1693 (when (null negpowlist) (return result))
1694 (setq coef (cadar negpowlist)
1695 controlpow (caar negpowlist))
1696 (when (= count 5) (go jump5))
1697 (when (= count 1) (go jump1))
1698 (when (= count 2) (go jump2))
1699 (when (= count 3) (go jump3))
1700 (setq m1 (- controlpow 2))
1701 (when (= m1 m)
1702 (setq res2 res1))
1703 (go jump4))))
1705 (defun r1m (m)
1706 (div 1 m))
1708 ;; Integrate (c*x^2+b*x)^(p-1/2)
1709 (defun case0 (power c b x)
1710 (let ((exp1 '((rat simp) 1 4))
1711 (exp2 (add b (mul 2 c x)))
1712 (exp3 (power c '((rat simp) -3 2)))
1713 (exp4 (add (mul 2 c x) (mul -1 b))))
1714 ;; exp1 = 1/4
1715 ;; exp2 = b+2*c*x
1716 ;; exp3 = 1/c^(3/2)
1717 ;; exp4 = 2*c*x-b
1718 (declare (special *ec-1*))
1719 (prog (signc p result)
1720 (setq signc (checksigntm *ec-1*)
1721 p 1)
1722 ;; sqrt(c*x^2+b*x)
1724 ;; This could be handled by numn. Why don't we?
1725 (when (eq signc '$positive)
1726 (setq result
1727 (add (augmult (mul exp1 *ec-1* exp2
1728 (power (polfoo c b 0 x) 1//2)))
1729 (augmult (mul* b b '((rat) -1 8)
1730 exp3
1731 `((%log)
1732 ,(add exp2
1733 (mul 2
1734 (power c 1//2)
1735 (power (polfoo c b 0 x) 1//2)))))))))
1736 (when (eq signc '$negative)
1737 (setq result
1738 (add (augmult (mul exp1 *ec-1* exp4
1739 (power (polfoo (mul -1 c) b 0 x) 1//2)))
1740 (augmult (mul* b b '((rat) 1 8)
1741 exp3
1742 `((%asin) ,(mul (inv b) exp4)))))))
1743 loop
1744 (when (equal power p) (return result))
1745 (incf p 2)
1747 ;; integrate(sqrt(R^(2*n+1)),x) =
1748 ;; (2*c*x+b)/4/(n+1)/c*sqrt(R^(2*n+1))
1749 ;; + (2*n+1)*del/8/(n+1)/c*integrate(sqrt(R^(2*n-1)),x)
1751 (setq result (add (augmult (mul 1//2 *ec-1* (inv (1+ p)) exp2
1752 (power (polfoo c b 0 x)
1753 (div p 2))))
1754 (augmult (mul p b b '((rat simp) -1 4)
1755 *ec-1* (inv (1+ p)) result))))
1756 (go loop))))
1758 ;; Integrate R^(p-1/2)/x, p >= 1.
1759 (defun den1numn (p c b a x)
1760 (cond ((= p 1)
1761 ;; integrate(sqrt(R)/x,x)
1763 ;; G&R 2.267 eq. 1
1765 ;; integrate(sqrt(R)/x,x) =
1766 ;; sqrt(R)
1767 ;; + a*integrate(1/x/sqrt(R),x)
1768 ;; + b/2*integrate(1/sqrt(R),x)
1769 (add (power (polfoo c b a x) 1//2)
1770 (augmult (mul a (den1den1 c b a x)))
1771 (augmult (mul b 1//2 (den1 c b a x)))))
1773 ;; General case
1775 ;; G&R 2.265
1777 ;; integrate(sqrt(R^(2*p-1)/x,x) =
1778 ;; R^(p-1/2)/(2*p-1)
1779 ;; + b/2*integrate(sqrt(R^(2*p-3)),x)
1780 ;; + a*integrate(sqrt(2^(2*p-3))/x,x)
1781 (add (augmult (mul (power (polfoo c b a x)
1782 (add p -1//2))
1783 (inv (+ p p -1))))
1784 (augmult (mul a (den1numn (+ p -1) c b a x)))
1785 (augmult (mul b 1//2 (numn (+ p -2) c b a x)))))))
1787 ;; L is a list of expressions that INTIRA should be applied to.
1788 ;; Sum up the results of applying INTIRA to each.
1789 (defun distrint (l x)
1790 (addn (mapcar #'(lambda (e)
1791 (let ((ie (intira e x)))
1792 (if ie
1794 `((%integrate simp) ,e ,x))))