Add translation for plog (using TRANSLATE-WITH-FLONUM-OP)
[maxima.git] / src / hypgeo.lisp
blob4d17783bafab9ec3d0dcd476b911979c1fd7c49c
1 ;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
2 ;;;
3 ;;; ** (c) Copyright 1976, 1983 Massachusetts Institute of Technology **
4 ;;;
5 ;;;
6 ;;; These are the main routines for finding the Laplace Transform
7 ;;; of special functions --- written by Yannis Avgoustis
8 ;;; --- modified by Edward Lafferty
9 ;;; Latest mod by jpg 8/21/81
10 ;;;
11 ;;; This program uses the programs on ELL;HYP FASL.
12 ;;;
13 ;;; References:
14 ;;;
15 ;;; Definite integration using the generalized hypergeometric functions
16 ;;; Avgoustis, Ioannis Dimitrios
17 ;;; Thesis. 1977. M.S.--Massachusetts Institute of Technology. Dept.
18 ;;; of Electrical Engineering and Computer Science
19 ;;; http://dspace.mit.edu/handle/1721.1/16269
20 ;;;
21 ;;; Avgoustis, I. D., Symbolic Laplace Transforms of Special Functions,
22 ;;; Proceedings of the 1977 MACSYMA Users' Conference, pp 21-41
24 (in-package :maxima)
26 (macsyma-module hypgeo)
28 (declare-top (special $expintrep))
30 (defmvar $prefer_d nil
31 "When NIL express a parabolic cylinder function as hypergeometric function.")
33 ;; The properties NOUN and VERB give correct linear display
34 (defprop $specint %specint verb)
35 (defprop %specint $specint noun)
37 (defvar *hyp-return-noun-form-p* t
38 "Return noun form instead of internal Lisp symbols for integrals
39 that we don't support.")
41 (defvar *hyp-return-noun-flag* nil
42 "Flag to signal that we have no result and to return a noun.")
44 (defvar *debug-hypgeo* nil
45 "Print debug information if enabled.")
47 ;; The variables *var* and *par* are global to this file only.
48 ;; They are initialized in the routine defexec. The values are never changed.
49 ;; These globals are introduced to avoid passing the values of *par* and *var*
50 ;; through all functions of this file.
52 (defvar *var* nil
53 "Variable of integration of Laplace transform.")
55 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
57 ;;; Helper function for this file
59 (defun substl (p1 p2 p3)
60 (cond ((eq p1 p2) p3)
61 (t (maxima-substitute p1 p2 p3))))
63 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
65 ;;; Test functions for pattern match, which use the globals var and *par*
67 ;; Not used here. This is only used in defint.lisp. Should either
68 ;; move it to defint.lisp or change defint.lisp to use freevar02.
69 (defun freevar0 (m)
70 (cond ((equal m 0) nil)
71 (t (freevar m))))
73 ;;; Test functions which do not depend on globals
75 ;; Test if EXP is 1 or %e.
76 (defun expor1p (expr)
77 (or (equal expr 1)
78 (eq expr '$%e)))
80 (defun has (expr x)
81 (not (free expr x)))
83 (defun free-not-zero-p (expr x)
84 (and (not (equal expr 0)) (free expr x)))
86 (defun free2 (expr x y)
87 (and (free expr x) (free expr y)))
89 (defun has-not-alike1-p (expr x)
90 (and (not (alike1 expr x)) (has expr x)))
92 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
94 ;;; Some shortcuts for special functions.
96 ;; Lommel's little s[u,v](z) function.
97 (defun littleslommel (m n z)
98 (list '(mqapply simp) (list '($%s simp array) m n) z))
100 ;; Whittaker's M function
101 (defun mwhit (a i1 i2)
102 (list '(mqapply simp) (list '($%m simp array) i1 i2) a))
104 ;; Whittaker's W function
105 (defun wwhit (a i1 i2)
106 (list '(mqapply simp) (list '($%w simp array) i1 i2) a))
108 ;; Jacobi P
109 (defun pjac (x n a b)
110 (list '(mqapply simp) (list '($%p simp array) n a b) x))
112 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
114 ;;; Two general pattern for the routine lt-sf-log.
116 ;; Recognize c*u^v + a and a=0.
117 (defun m2-arbpow1 (expr var2)
118 (m2 expr
119 `((mplus)
120 ((coeffpt)
121 (c free ,var2) ; more special to ensure that c is constant
122 ((mexpt) (u has ,var2) (v free ,var2)))
123 ((coeffpp) (a zerp)))))
125 ;; Recognize c*u^v*(a+b*u)^w+d and d=0. This is a generalization of arbpow1.
126 (defun m2-arbpow2 (expr var2)
127 (m2 expr
128 `((mplus)
129 ((mtimes)
130 ((coefftt) (c free ,var2))
131 ((mexpt) (u equal ,var2) (v free ,var2))
132 ((mexpt)
133 ((mplus) (a free ,var2) ((coefft) (b free ,var2) (u equal ,var2)))
134 (w free-not-zero-p ,var2)))
135 ((coeffpp) (d zerp)))))
137 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
139 ;;; The pattern to match special functions in the routine lt-sf-log.
141 ;; Recognize asin(w)
142 (defun m2-asin (expr var2)
143 (m2 expr
144 `((mplus)
145 ((coeffpt) (u nonzerp)
146 ((%asin) (w has ,var2)))
147 ((coeffpp) (a equal 0)))))
149 ;; Recognize atan(w)
150 (defun m2-atan (expr var2)
151 (m2 expr
152 `((mplus)
153 ((coeffpt) (u nonzerp)
154 ((%atan) (w has ,var2)))
155 ((coeffpp) (a equal 0)))))
157 ;; Recognize bessel_j(v,w)
158 (defun m2-onej (expr var2)
159 (m2 expr
160 `((mplus)
161 ((coeffpt)
162 (u nonzerp)
163 ((%bessel_j) (v free ,var2) (w has ,var2)))
164 ((coeffpp) (a zerp)))))
166 ;; Recognize bessel_j(v1,w1)*bessel_j(v2,w2)
167 (defun m2-twoj (expr var2)
168 (m2 expr
169 `((mplus)
170 ((coeffpt)
171 (u nonzerp)
172 ((%bessel_j) (v1 free ,var2) (w1 has ,var2))
173 ((%bessel_j) (v2 free ,var2) (w2 has ,var2)))
174 ((coeffpp) (a zerp)))))
176 ;; Recognize bessel_y(v1,w1)*bessel_y(v2,w2)
177 (defun m2-twoy (expr var2)
178 (m2 expr
179 `((mplus)
180 ((coeffpt)
181 (u nonzerp)
182 ((%bessel_y) (v1 free ,var2) (w1 has ,var2))
183 ((%bessel_y) (v2 free ,var2) (w2 has ,var2)))
184 ((coeffpp) (a zerp)))))
186 ;; Recognize bessel_k(v1,w1)*bessel_k(v2,w2)
187 (defun m2-twok (expr var2)
188 (m2 expr
189 `((mplus)
190 ((coeffpt)
191 (u nonzerp)
192 ((%bessel_k) (v1 free ,var2) (w1 has ,var2))
193 ((%bessel_k) (v2 free ,var2) (w2 has ,var2)))
194 ((coeffpp) (a zerp)))))
196 ;; Recognize bessel_k(v1,w1)*bessel_y(v2,w2)
197 (defun m2-onekoney (expr var2)
198 (m2 expr
199 `((mplus)
200 ((coeffpt)
201 (u nonzerp)
202 ((%bessel_k) (v1 free ,var2) (w1 has ,var2))
203 ((%bessel_y) (v2 free ,var2) (w2 has ,var2)))
204 ((coeffpp) (a zerp)))))
206 ;; Recognize bessel_j(v,w)^2
207 (defun m2-onej^2 (expr var2)
208 (m2 expr
209 `((mplus)
210 ((coeffpt)
211 (u nonzerp)
212 ((mexpt)
213 ((%bessel_j) (v free ,var2) (w has ,var2))
215 ((coeffpp) (a zerp)))))
217 ;; Recognize bessel_y(v,w)^2
218 (defun m2-oney^2 (expr var2)
219 (m2 expr
220 `((mplus)
221 ((coeffpt)
222 (u nonzerp)
223 ((mexpt)
224 ((%bessel_y) (v free ,var2) (w has ,var2))
226 ((coeffpp) (a zerp)))))
228 ;; Recognize bessel_k(v,w)^2
229 (defun m2-onek^2 (expr var2)
230 (m2 expr
231 `((mplus)
232 ((coeffpt)
233 (u nonzerp)
234 ((mexpt)
235 ((%bessel_k) (v free ,var2) (w has ,var2))
237 ((coeffpp) (a zerp)))))
239 ;; Recognize bessel_i(v,w)
240 (defun m2-onei (expr var2)
241 (m2 expr
242 `((mplus)
243 ((coeffpt)
244 (u nonzerp)
245 ((%bessel_i) (v free ,var2) (w has ,var2)))
246 ((coeffpp) (a zerp)))))
248 ;; Recognize bessel_i(v1,w1)*bessel_i(v2,w2)
249 (defun m2-twoi (expr var2)
250 (m2 expr
251 `((mplus)
252 ((coeffpt)
253 (u nonzerp)
254 ((%bessel_i) (v1 free ,var2) (w1 has ,var2))
255 ((%bessel_i) (v2 free ,var2) (w2 has ,var2)))
256 ((coeffpp) (a zerp)))))
258 ;; Recognize hankel_1(v1,w1)*hankel_1(v2,w2), product of 2 Hankel 1 functions.
259 (defun m2-two-hankel_1 (expr var2)
260 (m2 expr
261 `((mplus)
262 ((coeffpt)
263 (u nonzerp)
264 ((%hankel_1) (v1 free ,var2) (w1 has ,var2))
265 ((%hankel_1) (v2 free ,var2) (w2 has ,var2)))
266 ((coeffpp) (a zerp)))))
268 ;; Recognize hankel_2(v1,w1)*hankel_2(v2,w2), product of 2 Hankel 2 functions.
269 (defun m2-two-hankel_2 (expr var2)
270 (m2 expr
271 `((mplus)
272 ((coeffpt)
273 (u nonzerp)
274 ((%hankel_2) (v1 free ,var2) (w1 has ,var2))
275 ((%hankel_2) (v2 free ,var2) (w2 has ,var2)))
276 ((coeffpp) (a zerp)))))
278 ;; Recognize hankel_1(v1,w1)*hankel_2(v2,w2), product of 2 Hankel functions.
279 (defun m2-hankel_1*hankel_2 (expr var2)
280 (m2 expr
281 `((mplus)
282 ((coeffpt)
283 (u nonzerp)
284 ((%hankel_1) (v1 free ,var2) (w1 has ,var2))
285 ((%hankel_2) (v2 free ,var2) (w2 has ,var2)))
286 ((coeffpp) (a zerp)))))
288 ;; Recognize bessel_y(v1,w1)*bessel_j(v2,w2)
289 (defun m2-oneyonej (expr var2)
290 (m2 expr
291 `((mplus)
292 ((coeffpt)
293 (u nonzerp)
294 ((%bessel_y) (v1 free ,var2) (w1 has ,var2))
295 ((%bessel_j) (v2 free ,var2) (w2 has ,var2)))
296 ((coeffpp) (a zerp)))))
298 ;; Recognize bessel_k(v1,w1)*bessel_j(v2,w2)
299 (defun m2-onekonej (expr var2)
300 (m2 expr
301 `((mplus)
302 ((coeffpt)
303 (u nonzerp)
304 ((%bessel_k) (v1 free ,var2) (w1 has ,var2))
305 ((%bessel_j) (v2 free ,var2) (w2 has ,var2)))
306 ((coeffpp) (a zerp)))))
308 ;; Recognize bessel_y(v1,w1)*hankel_1(v2,w2)
309 (defun m2-bessel_y*hankel_1 (expr var2)
310 (m2 expr
311 `((mplus)
312 ((coeffpt)
313 (u nonzerp)
314 ((%bessel_y) (v1 free ,var2) (w1 has ,var2))
315 ((%hankel_1) (v2 free ,var2) (w2 has ,var2)))
316 ((coeffpp) (a zerp)))))
318 ;; Recognize bessel_y(v1,w1)*hankel_2(v2,w2)
319 (defun m2-bessel_y*hankel_2 (expr var2)
320 (m2 expr
321 `((mplus)
322 ((coeffpt)
323 (u nonzerp)
324 ((%bessel_y) (v1 free ,var2) (w1 has ,var2))
325 ((%hankel_2) (v2 free ,var2) (w2 has ,var2)))
326 ((coeffpp) (a zerp)))))
328 ;; Recognize bessel_k(v1,w1)*hankel_1(v2,w2)
329 (defun m2-bessel_k*hankel_1 (expr var2)
330 (m2 expr
331 `((mplus)
332 ((coeffpt)
333 (u nonzerp)
334 ((%bessel_k) (v1 free ,var2) (w1 has ,var2))
335 ((%hankel_1) (v1 free ,var2) (w2 has ,var2)))
336 ((coeffpp) (a zerp)))))
338 ;; Recognize bessel_k(v1,w1)*hankel_2(v2,w2)
339 (defun m2-bessel_k*hankel_2 (expr var2)
340 (m2 expr
341 `((mplus)
342 ((coeffpt)
343 (u nonzerp)
344 ((%bessel_k) (v1 free ,var2) (w1 has ,var2))
345 ((%hankel_2) (v2 free ,var2) (w2 has ,var2)))
346 ((coeffpp) (a zerp)))))
348 ;; Recognize bessel_i(v1,w1)*bessel_j(v2,w2)
349 (defun m2-oneionej (expr var2)
350 (m2 expr
351 `((mplus)
352 ((coeffpt)
353 (u nonzerp)
354 ((%bessel_i) (v1 free ,var2) (w1 has ,var2))
355 ((%bessel_j) (v2 free ,var2) (w2 has ,var2)))
356 ((coeffpp) (a zerp)))))
358 ;; Recognize bessel_i(v1,w1)*hankel_1(v2,w2)
359 (defun m2-bessel_i*hankel_1 (expr var2)
360 (m2 expr
361 `((mplus)
362 ((coeffpt)
363 (u nonzerp)
364 ((%bessel_i) (v1 free ,var2) (w1 has ,var2))
365 ((%hankel_1) (v2 free ,var2) (w2 has ,var2)))
366 ((coeffpp) (a zerp)))))
368 ;; Recognize bessel_i(v1,w1)*hankel_2(v2,w2)
369 (defun m2-bessel_i*hankel_2 (expr var2)
370 (m2 expr
371 `((mplus)
372 ((coeffpt)
373 (u nonzerp)
374 ((%bessel_i) (v1 free ,var2) (w1 has ,var2))
375 ((%hankel_2) (v2 free ,var2) (w2 has ,var2)))
376 ((coeffpp) (a zerp)))))
378 ;; Recognize hankel_1(v1,w1)*bessel_j(v2,w2)
379 (defun m2-hankel_1*bessel_j (expr var2)
380 (m2 expr
381 `((mplus)
382 ((coeffpt)
383 (u nonzerp)
384 ((%hankel_1) (v1 free ,var2) (w1 has ,var2))
385 ((%bessel_j) (v2 free ,var2) (w2 has ,var2)))
386 ((coeffpp) (a zerp)))))
388 ;; Recognize hankel_2(v1,w1)*bessel_j(v2,w2)
389 (defun m2-hankel_2*bessel_j (expr var2)
390 (m2 expr
391 `((mplus)
392 ((coeffpt)
393 (u nonzerp)
394 ((%hankel_2) (v1 free ,var2) (w1 has ,var2))
395 ((%bessel_j) (v2 free ,var2) (w2 has ,var2)))
396 ((coeffpp) (a zerp)))))
398 ;; Recognize bessel_i(v1,w1)*bessel_y(v2,w2)
399 (defun m2-oneioney (expr var2)
400 (m2 expr
401 `((mplus)
402 ((coeffpt)
403 (u nonzerp)
404 ((%bessel_i) (v1 free ,var2) (w1 has ,var2))
405 ((%bessel_y) (v2 free ,var2) (w2 has ,var2)))
406 ((coeffpp) (a zerp)))))
408 ;; Recognize bessel_i(v1,w1)*bessel_k(v2,w2)
409 (defun m2-oneionek (expr var2)
410 (m2 expr
411 `((mplus)
412 ((coeffpt)
413 (u nonzerp)
414 ((%bessel_i) (v1 free ,var2) (w1 has ,var2))
415 ((%bessel_k) (v2 free ,var2) (w2 has ,var2)))
416 ((coeffpp) (a zerp)))))
418 ;; Recognize bessel_i(v,w)^2
419 (defun m2-onei^2 (expr var2)
420 (m2 expr
421 `((mplus)
422 ((coeffpt)
423 (u nonzerp)
424 ((mexpt)
425 ((%bessel_i) (v free ,var2) (w has ,var2))
427 ((coeffpp) (a zerp)))))
429 ;; Recognize hankel_1(v,w)^2
430 (defun m2-hankel_1^2 (expr var2)
431 (m2 expr
432 `((mplus)
433 ((coeffpt)
434 (u nonzerp)
435 ((mexpt)
436 ((%hankel_1) (v free ,var2) (w has ,var2))
438 ((coeffpp) (a zerp)))))
440 ;; Recognize hankel_2(v,w)^2
441 (defun m2-hankel_2^2 (expr var2)
442 (m2 expr
443 `((mplus)
444 ((coeffpt)
445 (u nonzerp)
446 ((mexpt)
447 ((%hankel_2) (v free ,var2) (w has ,var2))
449 ((coeffpp) (a zerp)))))
451 ;; Recognize bessel_y(v,w)
452 (defun m2-oney (expr var2)
453 (m2 expr
454 `((mplus)
455 ((coeffpt)
456 (u nonzerp)
457 ((%bessel_y) (v free ,var2) (w has ,var2)))
458 ((coeffpp) (a zerp)))))
460 ;; Recognize bessel_k(v,w)
461 (defun m2-onek (expr var2)
462 (m2 expr
463 `((mplus)
464 ((coeffpt)
465 (u nonzerp)
466 ((%bessel_k) (v free ,var2) (w has ,var2)))
467 ((coeffpp) (a zerp)))))
469 ;; Recognize hankel_1(v,w)
470 (defun m2-hankel_1 (expr var2)
471 (m2 expr
472 `((mplus)
473 ((coeffpt)
474 (u nonzerp)
475 ((%hankel_1) (v free ,var2) (w has ,var2)))
476 ((coeffpp) (a zerp)))))
478 ;; Recognize hankel_2(v,w)
479 (defun m2-hankel_2 (expr var2)
480 (m2 expr
481 `((mplus)
482 ((coeffpt)
483 (u nonzerp)
484 ((%hankel_2) (v free ,var2) (w has ,var2)))
485 ((coeffpp) (a zerp)))))
487 ;; Recognize log(w)
488 (defun m2-onelog (expr var2)
489 (m2 expr
490 `((mplus)
491 ((coeffpt)
492 (u nonzerp)
493 ((%log) (w has ,var2)))
494 ((coeffpp) (a zerp)))))
496 ;; Recognize erf(w)
497 (defun m2-onerf (expr var2)
498 (m2 expr
499 `((mplus)
500 ((coeffpt)
501 (u nonzerp)
502 ((%erf) (w has ,var2)))
503 ((coeffpp) (a zerp)))))
505 ;; Recognize erfc(w)
506 (defun m2-onerfc (expr var2)
507 (m2 expr
508 `((mplus)
509 ((coeffpt)
510 (u nonzerp)
511 ((%erfc) (w has ,var2)))
512 ((coeffpp) (a zerp)))))
514 ;; Recognize fresnel_s(w)
515 (defun m2-onefresnel_s (expr var2)
516 (m2 expr
517 `((mplus)
518 ((coeffpt)
519 (u nonzerp)
520 ((%fresnel_s) (w has ,var2)))
521 ((coeffpp) (a zerp)))))
523 ;; Recognize fresnel_c(w)
524 (defun m2-onefresnel_c (expr var2)
525 (m2 expr
526 `((mplus)
527 ((coeffpt)
528 (u nonzerp)
529 ((%fresnel_c) (w has ,var2)))
530 ((coeffpp) (a zerp)))))
532 ;; Recognize expintegral_e(v,w)
533 (defun m2-oneexpintegral_e (expr var2)
534 (m2 expr
535 `((mplus)
536 ((coeffpt)
537 (u nonzerp)
538 ((%expintegral_e) (v free ,var2) (w has ,var2)))
539 ((coeffpp) (a zerp)))))
541 ;; Recognize expintegral_ei(w)
542 (defun m2-oneexpintegral_ei (expr var2)
543 (m2 expr
544 `((mplus)
545 ((coeffpt)
546 (u nonzerp)
547 ((%expintegral_ei) (w has ,var2)))
548 ((coeffpp) (a zerp)))))
550 ;; Recognize expintegral_e1(w)
551 (defun m2-oneexpintegral_e1 (expr var2)
552 (m2 expr
553 `((mplus)
554 ((coeffpt)
555 (u nonzerp)
556 ((%expintegral_e1) (w has ,var2)))
557 ((coeffpp) (a zerp)))))
559 ;; Recognize expintegral_si(w)
560 (defun m2-oneexpintegral_si (expr var2)
561 (m2 expr
562 `((mplus)
563 ((coeffpt)
564 (u nonzerp)
565 ((%expintegral_si) (w has ,var2)))
566 ((coeffpp) (a zerp)))))
568 ;; Recognize expintegral_shi(w)
569 (defun m2-oneexpintegral_shi (expr var2)
570 (m2 expr
571 `((mplus)
572 ((coeffpt)
573 (u nonzerp)
574 ((%expintegral_shi) (w has ,var2)))
575 ((coeffpp) (a zerp)))))
577 ;; Recognize expintegral_ci(w)
578 (defun m2-oneexpintegral_ci (expr var2)
579 (m2 expr
580 `((mplus)
581 ((coeffpt)
582 (u nonzerp)
583 ((%expintegral_ci) (w has ,var2)))
584 ((coeffpp) (a zerp)))))
586 ;; Recognize expintegral_chi(w)
587 (defun m2-oneexpintegral_chi (expr var2)
588 (m2 expr
589 `((mplus)
590 ((coeffpt)
591 (u nonzerp)
592 ((%expintegral_chi) (w has ,var2)))
593 ((coeffpp) (a zerp)))))
595 ;; Recognize kelliptic(w), (new would be elliptic_kc)
596 (defun m2-onekelliptic (expr var2)
597 (m2 expr
598 `((mplus)
599 ((coeffpt)
600 (u nonzerp)
601 (($kelliptic) (w has ,var2)))
602 ((coeffpp) (a zerp)))))
604 ;; Recognize elliptic_kc
605 (defun m2-elliptic_kc (expr var2)
606 (m2 expr
607 `((mplus)
608 ((coeffpt)
609 (u nonzerp)
610 ((%elliptic_kc) (w has ,var2)))
611 ((coeffpp) (a zerp)))))
613 ;; Recognize %e(w), (new would be elliptic_ec)
614 (defun m2-onee (expr var2)
615 (m2 expr
616 `((mplus)
617 ((coeffpt)
618 (u nonzerp)
619 (($%e) (w has ,var2)))
620 ((coeffpp) (a zerp)))))
622 ;; Recognize elliptic_ec
623 (defun m2-elliptic_ec (expr var2)
624 (m2 expr
625 `((mplus)
626 ((coeffpt)
627 (u nonzerp)
628 ((%elliptic_ec) (w has ,var2)))
629 ((coeffpp) (a zerp)))))
631 ;; Recognize gamma_incomplete(w1, w2), Incomplete Gamma function
632 (defun m2-onegammaincomplete (expr var2)
633 (m2 expr
634 `((mplus)
635 ((coeffpt)
636 (u nonzerp)
637 ((%gamma_incomplete) (w1 free ,var2) (w2 has ,var2)))
638 ((coeffpp) (a zerp)))))
640 ;; Recognize gamma_incomplete_lower(w1,w2), gamma(a)-gamma_incomplete(w1,w2)
641 (defun m2-onegamma-incomplete-lower (expr var2)
642 (m2 expr
643 `((mplus)
644 ((coeffpt)
645 (u nonzerp)
646 ((%gamma_incomplete_lower) (w1 free ,var2) (w2 has ,var2)))
647 ((coeffpp) (a zerp)))))
649 ;; Recognize Struve H function.
650 (defun m2-struve_h (expr var2)
651 (m2 expr
652 `((mplus)
653 ((coeffpt)
654 (u nonzerp)
655 ((%struve_h) (v free ,var2) (w has ,var2)))
656 ((coeffpp)(a zerp)))))
658 ;; Recognize Struve L function.
659 (defun m2-struve_l (expr var2)
660 (m2 expr
661 `((mplus)
662 ((coeffpt)
663 (u nonzerp)
664 ((%struve_l) (v free ,var2) (w has ,var2)))
665 ((coeffpp) (a zerp)))))
667 ;; Recognize Lommel s[v1,v2](w) function.
668 (defun m2-ones (expr var2)
669 (m2 expr
670 `((mplus)
671 ((coeffpt)
672 (u nonzerp)
673 ((mqapply)
674 (($%s array) (v1 free ,var2) (v2 free ,var2)) (w has ,var2)))
675 ((coeffpp) (a zerp)))))
677 ;; Recognize S[v1,v2](w), Lommel function
678 (defun m2-oneslommel (expr var2)
679 (m2 expr
680 `((mplus)
681 ((coeffpt)
682 (u nonzerp)
683 ((mqapply)
684 (($slommel array) (v1 free ,var2) (v2 free ,var2)) (w has ,var2)))
685 ((coeffpp) (a zerp)))))
687 ;; Recognize parabolic_cylinder_d function
688 (defun m2-parabolic_cylinder_d (expr var2)
689 (m2 expr
690 `((mplus)
691 ((coeffpt)
692 (u nonzerp)
693 (($parabolic_cylinder_d) (v free ,var2) (w has ,var2)))
694 ((coeffpp) (a zerp)))))
696 ;; Recognize kbatmann(v,w), Batemann function
697 (defun m2-onekbateman (expr var2)
698 (m2 expr
699 `((mplus)
700 ((coeffpt)
701 (u nonzerp)
702 ((mqapply)
703 (($kbateman array) (v free ,var2)) (w has ,var2)))
704 ((coeffpp) (a zerp)))))
706 ;; Recognize %l[v1,v2](w), Generalized Laguerre function
707 (defun m2-onel (expr var2)
708 (m2 expr
709 `((mplus)
710 ((coeffpt)
711 (u nonzerp)
712 ((mqapply)
713 (($%l array) (v1 free ,var2) (v2 free ,var2)) (w has ,var2)))
714 ((coeffpp) (a zerp)))))
716 ;; Recognize gen_laguerre(v1,v2,w), Generalized Laguerre function
717 (defun m2-one-gen-laguerre (expr var2)
718 (m2 expr
719 `((mplus)
720 ((coeffpt)
721 (u nonzerp)
722 ((%gen_laguerre) (v1 free ,var2) (v2 free ,var2) (w has ,var2)))
723 ((coeffpp) (a zerp)))))
725 ;; Recognize laguerre(v1,w), Laguerre function
726 (defun m2-one-laguerre (expr var2)
727 (m2 expr
728 `((mplus)
729 ((coeffpt)
730 (u nonzerp)
731 ((%laguerre) (v1 free ,var2) (w has ,var2)))
732 ((coeffpp) (a zerp)))))
734 ;; Recognize %c[v1,v2](w), Gegenbauer function
735 (defun m2-onec (expr var2)
736 (m2 expr
737 `((mplus)
738 ((coeffpt)
739 (u nonzerp)
740 ((mqapply)
741 (($%c array) (v1 free ,var2) (v2 free ,var2)) (w has ,var2)))
742 ((coeffpp) (a zerp)))))
744 ;; Recognize %t[v1](w), Chebyshev function of the first kind
745 (defun m2-onet (expr var2)
746 (m2 expr
747 `((mplus)
748 ((coeffpt)
749 (u nonzerp)
750 ((mqapply) (($%t array) (v1 free ,var2)) (w has ,var2)))
751 ((coeffpp) (a zerp)))))
753 ;; Recognize %u[v1](w), Chebyshev function of the second kind
754 (defun m2-oneu (expr var2)
755 (m2 expr
756 `((mplus)
757 ((coeffpt)
758 (u nonzerp)
759 ((mqapply) (($%u array) (v1 free ,var2)) (w has ,var2)))
760 ((coeffpp) (a zerp)))))
762 ;; Recognize %p[v1,v2,v3](w), Jacobi function
763 (defun m2-onepjac (expr var2)
764 (m2 expr
765 `((mplus)
766 ((coeffpt)
767 (u nonzerp)
768 ((mqapply)
769 (($%p array)
770 (v1 free ,var2) (v2 free ,var2) (v3 free ,var2)) (w has ,var2)))
771 ((coeffpp) (a zerp)))))
773 ;; Recognize jacobi_p function
774 (defun m2-jacobi_p (expr var2)
775 (m2 expr
776 `((mplus)
777 ((coeffpt)
778 (u nonzerp)
779 (($jacobi_p)
780 (v1 free ,var2) (v2 free ,var2) (v3 free ,var2) (w has ,var2)))
781 ((coeffpp) (a zerp)))))
783 ;; Recognize %p[v1,v2](w), Associated Legendre P function
784 (defun m2-hyp-onep (expr var2)
785 (m2 expr
786 `((mplus)
787 ((coeffpt)
788 (u nonzerp)
789 ((mqapply)
790 (($%p array) (v1 free ,var2) (v2 free ,var2)) (w has ,var2)))
791 ((coeffpp) (a zerp)))))
793 ;; Recognize assoc_legendre_p function
794 (defun m2-assoc_legendre_p (expr var2)
795 (m2 expr
796 `((mplus)
797 ((coeffpt)
798 (u nonzerp)
799 (($assoc_legendre_p) (v1 free ,var2) (v2 free ,var2) (w has ,var2)))
800 ((coeffpp) (a zerp)))))
802 ;; Recognize %p[v1](w), Legendre P function
803 (defun m2-onep0 (expr var2)
804 (m2 expr
805 `((mplus)
806 ((coeffpt)
807 (u nonzerp)
808 ((mqapply)(($%p array) (v1 free ,var2)) (w has ,var2)))
809 ((coeffpp) (a zerp)))))
811 ;; Recognize %p[v1](w), Legendre P function
812 (defun m2-legendre_p (expr var2)
813 (m2 expr
814 `((mplus)
815 ((coeffpt)
816 (u nonzerp)
817 (($legendre_p) (v free ,var2)) (w has ,var2))
818 ((coeffpp) (a zerp)))))
820 ;; Recognize hermite(v1,w), Hermite function
821 (defun m2-one-hermite (expr var2)
822 (m2 expr
823 `((mplus)
824 ((coeffpt)
825 (u nonzerp)
826 ((%hermite) (v1 free ,var2) (w has ,var2)))
827 ((coeffpp) (a zerp)))))
829 ;; Recognize %q[v1,v2](w), Associated Legendre function of the second kind
830 (defun m2-oneq (expr var2)
831 (m2 expr
832 `((mplus)
833 ((coeffpt)
834 (u nonzerp)
835 ((mqapply)
836 (($%q array) (v1 free ,var2) (v2 free ,var2)) (w has ,var2)))
837 ((coeffpp) (a zerp)))))
839 ;; Recognize assoc_legendre_q function
840 (defun m2-assoc_legendre_q (expr var2)
841 (m2 expr
842 `((mplus)
843 ((coeffpt)
844 (u nonzerp)
845 (($assoc_legendre_q) (v1 free ,var2) (v2 free ,var2) (w has ,var2)))
846 ((coeffpp) (a zerp)))))
848 ;; Recognize %w[v1,v2](w), Whittaker W function.
849 (defun m2-onew (expr var2)
850 (m2 expr
851 `((mplus)
852 ((coeffpt)
853 (u nonzerp)
854 ((mqapply)
855 (($%w array) (v1 free ,var2) (v2 free ,var2)) (w has ,var2)))
856 ((coeffpp) (a zerp)))))
858 ;; Recognize whittaker_w function.
859 (defun m2-whittaker_w (expr var2)
860 (m2 expr
861 `((mplus)
862 ((coeffpt)
863 (u nonzerp)
864 (($whittaker_w) (v1 free ,var2) (v2 free ,var2) (w has ,var2)))
865 ((coeffpp) (a zerp)))))
867 ;; Recognize %m[v1,v2](w), Whittaker M function
868 (defun m2-onem (expr var2)
869 (m2 expr
870 `((mplus)
871 ((coeffpt)
872 (u nonzerp)
873 ((mqapply)
874 (($%m array) (v1 free ,var2) (v2 free ,var2)) (w has ,var2)))
875 ((coeffpp) (a zerp)))))
877 ;; Recognize whittaker_m function.
878 (defun m2-whittaker_m (expr var2)
879 (m2 expr
880 `((mplus)
881 ((coeffpt)
882 (u nonzerp)
883 (($whittaker_m) (v1 free ,var2) (v2 free ,var2) (w has ,var2)))
884 ((coeffpp) (a zerp)))))
886 ;; Recognize %f[v1,v2](w1,w2,w3), Hypergeometric function
887 (defun m2-onef (expr var2)
888 (m2 expr
889 `((mplus)
890 ((coeffpt)
891 (u nonzerp)
892 ((mqapply)
893 (($%f array) (v1 free ,var2) (v2 free ,var2))
894 (w1 free ,var2)
895 (w2 free ,var2)
896 (w3 has ,var2)))
897 ((coeffpp) (a zerp)))))
899 ;; Recognize hypergeometric function
900 (defun m2-hypergeometric (expr var2)
901 (m2 expr
902 `((mplus)
903 ((coeffpt)
904 (u nonzerp)
905 ((%hypergeometric) (w1 free ,var2) (w2 free ,var2) (w3 has ,var2)))
906 ((coeffpp) (a zerp)))))
908 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
910 ;;; Pattern for the routine hypgeo-exec.
911 ;;; RECOGNIZES L.T.E. "U*%E^(A*X+E*F(X)-P*X+C)+D".
913 (defun m2-ltep (expr var2 par)
914 (m2 expr
915 `((mplus)
916 ((coeffpt)
917 (u nonzerp)
918 ((mexpt)
920 ((mplus)
921 ((coeffpt) (a free2 ,var2 ,par) (x alike1 ,var2))
922 ((coeffpt) (e free2 ,var2 ,par) (f has ,var2))
923 ((mtimes) -1 (p alike1 ,par) (x alike1 ,var2))
924 ((coeffpp) (c free2 ,var2 ,par)))))
925 ((coeffpp) (d equal 0)))))
927 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
929 ;;; Pattern for the routine defexec.
930 ;;; This is trying to match EXP to u*%e^(a*x+e*f+c)+d
931 ;;; where a, c, and e are free of x, f is free of p, and d is 0.
933 (defun m2-defltep (expr var2)
934 (m2 expr
935 `((mplus)
936 ((coeffpt)
937 (u nonzerp)
938 ((mexpt)
940 ((mplus)
941 ((coeffpt) (a free ,var2) (x alike1 ,var2))
942 ((coeffpt) (e free ,var2) (f has-not-alike1-p ,var2))
943 ((coeffpp) (c free ,var2)))))
944 ((coeffpp) (d equal 0)))))
946 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
948 ;;; $specint is the Maxima User function
950 (defmfun $specint (expr var2)
951 (prog ($radexpand *checkcoefsignlist*)
952 (setq $radexpand '$all)
953 (return (defintegrate expr var2))))
955 (defun defintegrate (expr var2)
956 ;; This used to have $exponentialize enabled for everything, but I
957 ;; don't think we should do that. If various routines want
958 ;; $exponentialize, let them set it themselves. So, for here, we
959 ;; want to expand the form with $exponentialize to convert trig and
960 ;; hyperbolic functions to exponential functions that we can handle.
961 (let ((form (let (($exponentialize t))
962 ($factor (resimplify expr))))) ; At first factor the integrand.
964 ;; Because we call defintegrate recursively, we add code to end the
965 ;; recursion safely.
967 (when (atom form)
968 (cond ((and (numberp form) (zerop form)) (return-from defintegrate 0))
969 (t (return-from defintegrate (list '(%specint simp) form var2)))))
971 ;; We try to find a constant denominator. This is necessary to get results
972 ;; for integrands like u(t)/(a+b+c+...).
974 (let ((den ($denom form)))
975 (when (and (not (equal 1 den)) ($freeof var2 den))
976 (return-from defintegrate
977 (div (defintegrate (mul den form) var2) den))))
979 ;; We search for a sum of Exponential functions which we can integrate.
980 ;; This code finds result for Trigonometric or Hyperbolic functions with
981 ;; a factor t^-1 or t^-2 e.g. t^-1*sin(a*t).
983 (let* ((l (m2-defltep form var2))
984 (s (mul -1 (cdras 'a l)))
985 (u ($expand (cdras 'u l)))
986 (l1))
987 (cond
988 ((setq l1 (m2-sum-with-exp-case1 u var2))
989 ;; c * t^-1 * (%e^(-a*t) - %e^(-b*t)) + d
990 (let ((c (cdras 'c l1))
991 (a (mul -1 (cdras 'a l1)))
992 (b (mul -1 (cdras 'b l1)))
993 (d (cdras 'd l1)))
994 (add (mul c (take '(%log) (div (add s b) (add s a))))
995 (defintegrate (mul d (power '$%e (mul -1 s var2))) var2))))
997 ((setq l1 (m2-sum-with-exp-case2 u var2))
998 ;; c * t^(-3/2) * (%e^(-a*t) - %e^(-b*t)) + d
999 (let ((c (cdras 'c l1))
1000 (a (mul -1 (cdras 'a l1)))
1001 (b (mul -1 (cdras 'b l1)))
1002 (d (cdras 'd l1)))
1003 (add (mul 2 c
1004 (power '$%pi '((rat simp) 1 2))
1005 (sub (power (add s b) '((rat simp) 1 2))
1006 (power (add s a) '((rat simp) 1 2))))
1007 (defintegrate (mul d (power '$%e (mul -1 s var2))) var2))))
1009 ((setq l1 (m2-sum-with-exp-case3 u var2))
1010 ;; c * t^-2 * (1 - 2 * %e^(-a*t) + %e^(2*a*t)) + d
1011 (let ((c (cdras 'c l1))
1012 (a (div (cdras 'a l1) -2))
1013 (d (cdras 'd l1)))
1014 (add (mul c
1015 (add (mul (add s a a) (take '(%log) (add s a a)))
1016 (mul s (take '(%log) s))
1017 (mul -2 (add s a) (take '(%log) (add s a)))))
1018 (defintegrate (mul d (power '$%e (mul -1 s var2))) var2))))
1020 ((setq l1 (m2-sum-with-exp-case4 u var2))
1021 ;; c * t^-1 * (1 - 2 * %e^(-a*t) + %e^(2*a*t)) + d
1022 (let ((c (cdras 'c l1))
1023 (a (div (cdras 'a l1) (mul 4 '$%i)))
1024 (d (cdras 'd l1)))
1025 (add (mul -1 c
1026 (take '(%log)
1027 (add 1
1028 (div (mul 4 a a)
1029 (mul (sub s (mul 2 '$%i a))
1030 (sub s (mul 2 '$%i a)))))))
1031 (defintegrate (mul d (power '$%e (mul -1 s var2))) var2))))
1033 ((setq l1 (m2-sum-with-exp-case5 u var2))
1034 ;; c * t^-1 * (1 - %e^(2*a*t)) + d
1035 (let ((c (cdras 'c l1))
1036 (a (cdras 'a l1))
1037 (d (cdras 'd l1)))
1038 (add (mul c (take '(%log) (div (sub s a) s)))
1039 (defintegrate (mul d (power '$%e (mul -1 s var2))) var2))))
1042 ;; At this point we expand the integrand.
1043 (distrdefexecinit ($expand form) var2))))))
1045 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1047 ;;; Five pattern to find sums of Exponential functions which we can integrate.
1049 ;; Case 1: c * u^-1 * (%e^(-a*u) - %e^(-b*u))
1050 (defun m2-sum-with-exp-case1 (expr var2)
1051 (m2 expr
1052 `((mplus)
1053 ((coefft)
1054 (c free ,var2)
1055 ((mexpt) (u alike1 ,var2) -1)
1056 ((mexpt) $%e
1057 ((mplus)
1058 ((coeffpt) (a nonzerp) (u alike1 ,var2))
1059 ((coeffpp) (z1 zerp)))))
1060 ((coefft)
1061 (c2 equal-times-minus-one c)
1062 ((mexpt) (u alike1 ,var2) -1)
1063 ((mexpt) $%e
1064 ((mplus)
1065 ((coeffpt) (b nonzerp) (u alike1 ,var2))
1066 ((coeffpp) (z2 zerp)))))
1067 ((coeffpp) (d true)))))
1069 ;; Case 2: c * u^(-3/2) * (%e^(-a*u) - %e^(-b*u))
1070 (defun m2-sum-with-exp-case2 (expr var2)
1071 (m2 expr
1072 `((mplus)
1073 ((coefft)
1074 (c free ,var2)
1075 ((mexpt) (u alike1 ,var2) ((rat) -3 2))
1076 ((mexpt) $%e
1077 ((mplus)
1078 ((coeffpt) (a nonzerp) (u alike1 ,var2))
1079 ((coeffpp) (z1 zerp)))))
1080 ((coefft)
1081 (c2 equal-times-minus-one c)
1082 ((mexpt) (u alike1 ,var2) ((rat) -3 2))
1083 ((mexpt) $%e
1084 ((mplus)
1085 ((coeffpt) (b nonzerp) (u alike1 ,var2))
1086 ((coeffpp) (z2 zerp)))))
1087 ((coeffpp) (d true)))))
1089 ;; Case 3: c * u^-2 * (1 - 2 * %e^(-a*u) + %e^(2*a*u))
1090 (defun m2-sum-with-exp-case3 (expr var2)
1091 (m2 expr
1092 `((mplus)
1093 ((coefft)
1094 (c free ,var2)
1095 ((mexpt) (u alike1 ,var2) -2))
1096 ((coefft)
1097 (c2 equal c)
1098 ((mexpt) (u alike1 ,var2) -2)
1099 ((mexpt) $%e
1100 ((mplus)
1101 ((coeffpt) (a nonzerp) (u alike1 ,var2))
1102 ((coeffpp) (z1 zerp)))))
1103 ((coefft)
1104 (c3 equal-times-minus-two c)
1105 ((mexpt) (u alike1 ,var2) -2)
1106 ((mexpt) $%e
1107 ((mplus)
1108 ((coeffpt) (b equal-div-two a) (u alike1 ,var2))
1109 ((coeffpp) (z2 zerp)))))
1110 ((coeffpp) (d true)))))
1112 ;; Case 4: c * t^-1 * (1 - 2 * %e^(-a*t) + %e^(2*a*t))
1113 (defun m2-sum-with-exp-case4 (expr var2)
1114 (m2 expr
1115 `((mplus)
1116 ((coefft)
1117 (c free ,var2)
1118 ((mexpt) (u alike1 ,var2) -1))
1119 ((coefft)
1120 (c2 equal c)
1121 ((mexpt) (u alike1 ,var2) -1)
1122 ((mexpt) $%e
1123 ((mplus)
1124 ((coeffpt) (a nonzerp) (u alike1 ,var2))
1125 ((coeffpp) (z1 zerp)))))
1126 ((coefft)
1127 (c3 equal-times-minus-two c)
1128 ((mexpt) (u alike1 ,var2) -1)
1129 ((mexpt) $%e
1130 ((mplus)
1131 ((coeffpt) (b equal-div-two a) (u alike1 ,var2))
1132 ((coeffpp) (z2 zerp)))))
1133 ((coeffpp) (d true)))))
1135 ;; Case 5: c* t^-1 * (1 - %e^(2*a*t))
1136 (defun m2-sum-with-exp-case5 (expr var2)
1137 (m2 expr
1138 `((mplus)
1139 ((coefft)
1140 (c free ,var2)
1141 ((mexpt) (u alike1 ,var2) -1))
1142 ((coefft)
1143 (c2 equal-times-minus-one c)
1144 ((mexpt) (u alike1 ,var2) -1)
1145 ((mexpt) $%e
1146 ((mplus)
1147 ((coeffpt) (a nonzerp) (u alike1 ,var2))
1148 ((coeffpp) (z1 zerp)))))
1149 ((coeffpp) (d true)))))
1151 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1153 ;;; Test functions for the pattern m2-sum-with-exp-case<n>
1155 (defun equal-times-minus-one (a b)
1156 (equal a (mul -1 b)))
1158 (defun equal-times-minus-two (a b)
1159 (equal a (mul -2 b)))
1161 (defun equal-div-two (a b)
1162 (equal a (div b 2)))
1164 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1166 ;;; Called by defintegrate.
1167 ;;; Call for every term of a sum defexec and add up the results.
1169 ;; Evaluate the transform of a sum as sum of transforms.
1170 (defun distrdefexecinit (expr var2)
1171 (cond ((equal (caar expr) 'mplus)
1172 (distrdefexec (cdr expr) var2))
1173 (t (defexec expr var2))))
1175 ;; FUN is a list of addends. Compute the transform of each addend and
1176 ;; add them up.
1177 (defun distrdefexec (expr var2)
1178 (cond ((null expr) 0)
1179 (t (add (defexec (car expr) var2)
1180 (distrdefexec (cdr expr) var2)))))
1182 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1184 ;;; Called after transformation of a integrand to a new representation.
1185 ;;; Evaluate the transform of a sum as sum of transforms.
1187 (defun sendexec (r a)
1188 (distrexecinit ($expand (mul (init r) a))))
1190 ;; Compute r*exp(-p*t), where t is the variable of integration and
1191 ;; p is the parameter of the Laplace transform.
1192 (defun init (r)
1193 (mul r (power '$%e (mul -1 *var* *par*))))
1195 (defun distrexecinit (expr)
1196 (cond ((and (consp expr)
1197 (consp (car expr))
1198 (equal (caar expr) 'mplus))
1199 (distrexec (cdr expr)))
1200 (t (hypgeo-exec expr))))
1202 (defun distrexec (expr)
1203 (cond ((null expr) 0)
1204 (t (add (hypgeo-exec (car expr))
1205 (distrexec (cdr expr))))))
1207 ;; It dispatches according to the kind of transform it matches.
1208 (defun hypgeo-exec (expr)
1209 (prog (l u a c e f)
1210 (cond ((setq l (m2-ltep expr *var* *par*))
1211 (setq u (cdras 'u l)
1212 a (cdras 'a l)
1213 c (cdras 'c l)
1214 e (cdras 'e l)
1215 f (cdras 'f l))
1216 (return (ltscale u c a e f))))
1217 (return (setq *hyp-return-noun-flag* 'other-trans-to-follow))))
1219 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1221 ;;; Compute transform of EXP wrt the variable of integration VAR.
1223 (defun defexec (expr var2)
1224 (let* ((*par* 'psey) ; Set parameter of Laplace transform
1225 (*var* var2) ; Set variable of integration
1226 (*hyp-return-noun-flag* nil) ; Reset the flag
1227 (form expr)
1228 (l (m2-defltep expr var2))
1229 (s (cdras 'a l))) ; Get the parameter of the Laplace transform.
1231 ;; If we have not found a parameter, we try to factor the integrand.
1233 (when (and (numberp s) (equal s 0))
1234 (setq l (m2-defltep ($factor form) *var*))
1235 (setq s (cdras 'a l)))
1237 (cond (l
1238 ;; EXP is an expression of the form u*%e^(s*t+e*f+c). So s
1239 ;; is basically the parameter of the Laplace transform.
1240 (let ((result (negtest l s)))
1241 ;; At this point we construct the noun form if one of the
1242 ;; called routines set the global flag. If the global flag
1243 ;; is not set, the noun form has been already constructed.
1244 (if (and *hyp-return-noun-form-p* *hyp-return-noun-flag*)
1245 (list '(%specint simp) expr *var*)
1246 result)))
1248 ;; If necessary we construct the noun form.
1249 (if *hyp-return-noun-form-p*
1250 (list '(%specint simp) expr *var*)
1251 'other-defint-to-follow-defexec)))))
1253 ;; L is the integrand of the transform, after pattern matching. S is
1254 ;; the parameter (p) of the transform.
1255 (defun negtest (l s)
1256 (prog (u e f c)
1257 (cond ((eq ($asksign ($realpart s)) '$neg)
1258 ;; The parameter of transform must have a negative
1259 ;; realpart. Break out the integrand into its various
1260 ;; components.
1261 (setq u (cdras 'u l)
1262 e (cdras 'e l)
1263 f (cdras 'f l)
1264 c (cdras 'c l))
1265 (when (equal e 0) (setq f 1))
1266 ;; To compute the transform, we replace A with PSEY for
1267 ;; simplicity. After the transform is computed, replace
1268 ;; PSEY with A.
1270 ;; FIXME: Sometimes maxima will ask for the sign of PSEY.
1271 ;; But that doesn't occur in the original expression, so
1272 ;; it's very confusing. What should we do?
1274 ;; We know psey must be positive. psey is a substitution
1275 ;; for the paratemter a and we have checked the sign.
1276 ;; So it is the best to add a rule for the sign of psey.
1278 (mfuncall '$assume `((mgreaterp) ,*par* 0))
1280 (return
1281 (prog1
1282 (maxima-substitute
1283 (mul -1 s)
1284 *par*
1285 (ltscale u c 0 e f))
1287 ;; We forget the rule after finishing the calculation.
1288 (mfuncall '$forget `((mgreaterp) ,*par* 0))))))
1290 (return
1291 (setq *hyp-return-noun-flag* 'other-defint-to-follow-negtest))))
1293 ;; Compute the transform of
1295 ;; U * %E^(-VAR * (*PAR* - PAR0) + E*F + C)
1296 (defun ltscale (u c par0 e f)
1297 (mul (power '$%e c)
1298 (substl (sub *par* par0) *par* (lt-exec u e f))))
1300 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1302 ;;; Compute the transform of u*%e^(-p*t+e*f)
1304 (defun lt-exec (u e f)
1305 (let (l a)
1306 (cond ((setq l (m2-sum u *var*))
1307 ;; We have found a summation.
1308 (mul (cdras 'c l)
1309 (take '(%sum)
1310 (sendexec 1 (cdras 'u l))
1311 (cdras 'i l)
1312 (cdras 'l l)
1313 (cdras 'h l))))
1315 ((setq l (m2-unit_step u *var*))
1316 ;; We have found the Unit Step function.
1317 (setq u (cdras 'u l)
1318 a (cdras 'a l))
1319 (mul (power '$%e (mul a *par*))
1320 (sendexec (cond (($freeof *var* u) u)
1321 (t (maxima-substitute (sub *var* a) *var* u)))
1322 1)))
1324 ((equal e 0)
1325 ;; The simple case of u*%e^(-p*t)
1326 (lt-sf-log u))
1327 ((and (not (equal e 0))
1328 (setq l (m2-c*t^v u *var*)))
1329 ;; We have u*%e^(-p*t+e*f). Try to see if U is of the form
1330 ;; c*t^v. If so, we can handle it here.
1331 (lt-exp l e f))
1333 ;; The complicated case. Remove the e*f term and move it to u.
1334 (lt-sf-log (mul u (power '$%e (mul e f))))))))
1336 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1338 ;;; Pattern for the routine lt-exec
1340 ;; Recognize c*sum(u,index,low,high)
1341 (defun m2-sum (expr var2)
1342 (m2 expr
1343 `((mplus)
1344 ((coeffpt)
1345 (c free ,var2)
1346 ((%sum) (u true) (i true) (l true) (h true)))
1347 ((coeffpp) (d zerp)))))
1349 ;; Recognize u(t)*unit_step(x-a)
1350 (defun m2-unit_step (expr var2)
1351 (m2 expr
1352 `((mplus)
1353 ((coeffpt)
1354 (u nonzerp)
1355 (($unit_step) ((mplus) (x alike1 ,var2) ((coeffpp) (a true)))))
1356 ((coeffpp) (d zerp)))))
1358 ;; Recognize c*t^v.
1359 ;; This is a duplicate of m2-arbpow1. Look if we can use it.
1360 (defun m2-c*t^v (expr var2)
1361 (m2 expr
1362 `((mtimes)
1363 ((coefftt) (c free ,var2))
1364 ((mexpt) (u alike1 ,var2) (v free ,var2)))))
1366 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1367 ;;;
1368 ;;; Algorithm 1: Laplace transform of c*t^v*exp(-s*t+e*f)
1370 ;;; L contains the pattern for c*t^v.
1371 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1373 (defun lt-exp (l e f)
1374 (let ((c (cdras 'c l))
1375 (v (cdras 'v l)))
1376 (cond ((m2-t^2 f *var*)
1377 (setq e (inv (mul -8 e)) v (add v 1))
1378 (f24p146test c v e))
1379 ((m2-sqroott f *var*)
1380 ;; We don't do the transformation at this place. Because we take the
1381 ;; square of e we lost the sign and get wrong results.
1382 ;(setq e (mul* e e (inv 4)) v (add v 1))
1383 (f35p147test c v e))
1384 ((m2-t^-1 f *var*)
1385 (setq e (mul -4 e) v (add v 1))
1386 (f29p146test c v e)) ; We have to call with the constant c.
1387 ((and (equal v 0) ; We have to test for v=0 and to call
1388 (m2-e^-t f *var*))
1389 (f36p147 c e)) ; with the constant c.
1390 ((and (equal v 0) (m2-e^t f *var*))
1391 (f37p147 c (mul -1 e)))
1393 (setq *hyp-return-noun-flag* 'other-lt-exponential-to-follow)))))
1395 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1397 ;;; Pattern for the routine lt-exp
1399 ;; Recognize t^2
1400 (defun m2-t^2 (expr var2)
1401 (m2 expr `((mexpt) (u alike1 ,var2) 2)))
1403 ;; Recognize sqrt(t)
1404 (defun m2-sqroott (expr var2)
1405 (m2 expr `((mexpt) (u alike1 ,var2) ((rat) 1 2))))
1407 ;; Recognize t^-1
1408 (defun m2-t^-1 (expr var2)
1409 (m2 expr `((mexpt) (u alike1 ,var2) -1)))
1411 ;; Recognize %e^-t
1412 (defun m2-e^-t (expr var2)
1413 (m2 expr `((mexpt) $%e ((mtimes) -1 (u alike1 ,var2)))))
1415 ;; Recognize %e^t
1416 (defun m2-e^t (expr var2)
1417 (m2 expr `((mexpt) $%e (u alike1 ,var2))))
1419 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1421 ;;; Algorithm 1.1: Laplace transform of c*t^v*exp(-a*t^2)
1423 ;;; Table of Integral Transforms
1425 ;;; p. 146, formula 24:
1427 ;;; t^(v-1)*exp(-t^2/8/a)
1428 ;;; -> gamma(v)*2^v*a^(v/2)*exp(a*p^2)*D[-v](2*p*sqrt(a))
1430 ;;; Re(a) > 0, Re(v) > 0
1431 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1433 (defun f24p146test (c v a)
1434 (cond ((and (eq ($asksign a) '$pos)
1435 (eq ($asksign v) '$pos))
1436 ;; Both a and v must be positive
1437 (f24p146 c v a))
1439 (setq *hyp-return-noun-flag* 'fail-on-f24p146test))))
1441 (defun f24p146 (c v a)
1442 (mul c
1443 (take '(%gamma) v)
1444 (power 2 v)
1445 (power a (div v 2))
1446 (power '$%e (mul a *par* *par*))
1447 (dtford (mul 2 *par* (power a '((rat simp) 1 2)))
1448 (mul -1 v))))
1450 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1452 ;;; Algorithm 1.2: Laplace transform of c*t^v*exp(-a*sqrt(t))
1454 ;;; Table of Integral Transforms
1456 ;;; p. 147, formula 35:
1458 ;;; (2*t)^(v-1)*exp(-2*sqrt(a)*sqrt(t))
1459 ;;; -> gamma(2*v)*p^(-v)*exp(a/p/2)*D[-2*v](sqrt(2*a/p))
1461 ;;; Re(v) > 0, Re(p) > 0
1462 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1464 ;; Check if conditions for f35p147 hold
1465 (defun f35p147test (c v a)
1466 (cond ((eq ($asksign (add v 1)) '$pos)
1467 ;; v must be positive
1468 (f35p147 c v a))
1470 ;; Set a global flag. When *hyp-return-noun-form-p* is T the noun
1471 ;; form will be constructed in the routine DEFEXEC.
1472 (setq *hyp-return-noun-flag* 'fail-on-f35p147test))))
1474 (defun f35p147 (c v a)
1475 ;; We have not done the calculation v->v+1 and a-> a^2/4
1476 ;; and substitute here accordingly.
1477 (let ((v (add v 1)))
1478 (mul c
1479 (take '(%gamma) (add v v))
1480 (power 2 (sub 1 v)) ; Is this supposed to be here?
1481 (power *par* (mul -1 v))
1482 (power '$%e (mul a a '((rat simp) 1 8) (inv *par*)))
1483 ;; We need an additional factor -1 to get the expected results.
1484 ;; What is the mathematically reason?
1485 (dtford (mul -1 a (inv (power (mul 2 *par*) '((rat simp) 1 2))))
1486 (mul -2 v)))))
1488 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1490 ;; Express a parabolic cylinder function as either a parabolic
1491 ;; cylinder function or as hypergeometric function.
1493 ;; Tables of Integral Transforms, p. 386 gives this definition:
1495 ;; D[v](z) = 2^(v/2+1/4)*z^(-1/2)*W[v/2+1/4,1/4](z^2/2)
1497 (defun dtford (z v)
1498 (let ((inv4 (inv 4)))
1499 (cond ((or $prefer_d
1500 (whittindtest (add (div v 2) inv4) inv4))
1501 ;; At this time the Parabolic Cylinder D function is not implemented
1502 ;; as a simplifying function. We call nevertheless the simplifier
1503 ;; to simplify the arguments. When we implement the function
1504 ;; The symbol has to be changed to the noun form.
1505 (take '($parabolic_cylinder_d) v z))
1506 (t (simpdtf z v)))))
1508 (defun whittindtest (i1 i2)
1509 (or (maxima-integerp (add i2 i2))
1510 (neginp (sub (sub '((rat simp) 1 2) i2) i1))
1511 (neginp (sub (add '((rat simp) 1 2) i2) i1))))
1513 ;; Return T if a is a non-positive integer.
1514 ;; (Do we really want maxima-integerp or hyp-integerp here?)
1515 (defun neginp (a)
1516 (cond ((maxima-integerp a)
1517 (or (zerop1 a)
1518 (eq ($sign a) '$neg)))))
1520 ;; Express parabolic cylinder function as a hypergeometric function.
1522 ;; A&S 19.3.1 says
1524 ;; U(a,x) = D[-a-1/2](x)
1526 ;; and A&S 19.12.3 gives
1528 ;; U(a,+/-x) = sqrt(%pi)*2^(-1/4-a/2)*exp(-x^2/4)/gamma(3/4+a/2)
1529 ;; *M(a/2+1/4,1/2,x^2/2)
1530 ;; -/+ sqrt(%pi)*2^(1/4-a/2)*x*exp(-x^2/4)/gamma(1/4+a/2)
1531 ;; *M(a/2+3/4,3/2,x^2/2)
1533 ;; So
1535 ;; D[v](z) = U(-v-1/2,z)
1536 ;; = sqrt(%pi)*2^(v/2+1/2)*x*exp(-x^2/4)
1537 ;; *M(1/2-v/2,3/2,x^2/2)/gamma(-v/2)
1538 ;; + sqrt(%pi)*2^(v/2)*exp(-x^2/4)/gamma(1/2-v/2)
1539 ;; *M(-v/2,1/2,x^2/2)
1541 (defun simpdtf (z v)
1542 (let ((inv2 '((rat simp) 1 2))
1543 (pow (power '$%e (mul z z '((rat simp) -1 4)))))
1544 (add (mul (power 2 (div (sub v 1) 2))
1546 -2 (power '$%pi inv2) ; gamma(-1/2)
1547 (inv (take '(%gamma) (mul v -1 inv2)))
1549 (hgfsimp-exec (list (sub inv2 (div v 2)))
1550 (list '((rat simp) 3 2))
1551 (mul z z inv2)))
1552 (mul (power 2 (div v 2))
1553 (power '$%pi inv2) ; gamma(1/2)
1555 (inv (take '(%gamma) (sub inv2 (mul v inv2))))
1556 (hgfsimp-exec (list (mul v -1 inv2))
1557 (list inv2)
1558 (mul z z inv2))))))
1560 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1562 ;;; Algorithm 1.3: Laplace transform of t^v*exp(1/t)
1564 ;;; Table of Integral Transforms
1566 ;;; p. 146, formula 29:
1568 ;;; t^(v-1)*exp(-a/t/4)
1569 ;;; -> 2*(a/p/4)^(v/2)*bessel_k(v, sqrt(a)*sqrt(p))
1571 ;;; Re(a) > 0
1572 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1574 ;; Check if conditions for f29p146test hold
1575 (defun f29p146test (c v a)
1576 (cond ((eq ($asksign a) '$pos)
1577 (f29p146 c v a))
1579 (setq *hyp-return-noun-flag* 'fail-on-f29p146test))))
1581 (defun f29p146 (c v a)
1582 (mul 2 c
1583 (power (mul a '((rat simp) 1 4) (inv *par*))
1584 (div v 2))
1585 (ktfork a v)))
1587 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1589 ;; bessel_k(v, sqrt(a)*sqrt(p)) in terms of bessel_k or in terms of
1590 ;; hypergeometric functions.
1592 ;; Choose bessel_k if the order v is an integer. (Why?)
1594 (defun ktfork (a v)
1595 (let ((z (power (mul a *par*) '((rat simp) 1 2))))
1596 (cond ((maxima-integerp v)
1597 (take '(%bessel_k) v z))
1599 (simpktf z v)))))
1601 ;; Express the Bessel K function in terms of hypergeometric functions.
1603 ;; K[v](z) = %pi/2*(bessel_i(-v,z)-bessel(i,z))/sin(v*%pi)
1605 ;; and
1607 ;; bessel_i(v,z) = (z/2)^v/gamma(v+1)*0F1(;v+1;z^2/4)
1609 (defun simpktf (z v)
1610 (let ((dz2 (div z 2)))
1611 (mul '$%pi
1612 '((rat simp) 1 2)
1613 (inv (take '(%sin) (mul v '$%pi)))
1614 (sub (mul (power dz2 (mul -1 v))
1615 (inv (take '(%gamma) (sub 1 v)))
1616 (hgfsimp-exec nil
1617 (list (sub 1 v))
1618 (mul z z '((rat simp) 1 4))))
1619 (mul (power dz2 v)
1620 (inv (take '(%gamma) (add v 1)))
1621 (hgfsimp-exec nil
1622 (list (add v 1))
1623 (mul z z '((rat simp) 1 4))))))))
1625 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1627 ;;; Algorithm 1.4: Laplace transform of exp(exp(-t))
1629 ;;; Table of Integral Transforms
1631 ;;; p. 147, formula 36:
1633 ;;; exp(-a*exp(-t))
1634 ;;; -> a^(-p)*gamma(p,a)
1635 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1637 (defun f36p147 (c a)
1638 (let ((-a (mul -1 a)))
1639 (mul c
1640 (power -a (mul -1 *par*))
1641 `((%gamma_incomplete_lower simp) ,*par* ,-a))))
1643 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1645 ;;; Algorithm 1.5: Laplace transform of exp(exp(t))
1647 ;;; Table of Integral Transforms
1649 ;;; p. 147, formula 36:
1651 ;;; exp(-a*exp(t))
1652 ;;; -> a^(-p)*gamma_incomplete(-p,a)
1653 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1655 (defun f37p147 (c a)
1656 (mul c
1657 (power a *par*)
1658 (take '(%gamma_incomplete) (mul -1 *par*) a)))
1660 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1662 ;;; Algorithm 2: Laplace transform of u(t)*%e^(-p*t).
1664 ;;; u contains one or more special functions. Dispatches according to the
1665 ;;; special functions involved in the Laplace transformable expression.
1667 ;;; We have three general types of integrands:
1669 ;;; 1. Call a function to return immediately the Laplace transform,
1670 ;;; e.g. call lt-arbpow, lt-arbpow2, lt-log, whittest to return the
1671 ;;; Laplace transform.
1672 ;;; 2. Call lt-ltp directly or via an "expert function on Laplace transform",
1673 ;;; transform the special function to a representation in terms of one
1674 ;;; hypergeometric function and do the integration
1675 ;;; e.g. for a direct call of lt-ltp asin, atan or via lt2j for
1676 ;;; an integrand with two bessel function.
1677 ;;; 3. Call fractest, fractest1, ... which transform the involved special
1678 ;;; function to a new representation. Send the transformed expression with
1679 ;;; the routine sendexec to the integrator and try to integrate the new
1680 ;;; representation, e.g. gamma_incomplete is first transformed to a new
1681 ;;; representation.
1682 ;;;
1683 ;;; The ordering of the calls to match a pattern is important.
1684 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1686 (defun lt-sf-log (u)
1687 (prog (l index1 index11 index2 index21 arg1 arg2 rest)
1689 ;; Laplace transform of asin(w)
1690 (cond ((setq l (m2-asin u *var*))
1691 (setq arg1 (cdras 'w l)
1692 rest (cdras 'u l))
1693 (return (lt-ltp 'asin rest arg1 nil))))
1695 ;; Laplace transform of atan(w)
1696 (cond ((setq l (m2-atan u *var*))
1697 (setq arg1 (cdras 'w l)
1698 rest (cdras 'u l))
1699 (return (lt-ltp 'atan rest arg1 nil))))
1701 ;; Laplace transform of two Bessel J functions
1702 (cond ((setq l (m2-twoj u *var*))
1703 (setq index1 (cdras 'v1 l)
1704 index2 (cdras 'v2 l)
1705 arg1 (cdras 'w1 l)
1706 arg2 (cdras 'w2 l)
1707 rest (cdras 'u l))
1708 (return (lt2j rest arg1 arg2 index1 index2))))
1710 ;; Laplace transform of two hankel_1 functions
1711 (cond ((setq l (m2-two-hankel_1 u *var*))
1712 (setq index1 (cdras 'v1 l)
1713 index2 (cdras 'v2 l)
1714 arg1 (cdras 'w1 l)
1715 arg2 (cdras 'w2 l)
1716 rest (cdras 'u l))
1717 ;; Call the code for the symbol %h.
1718 (return (fractest rest arg1 arg2 index1 1 index2 1 '2htjory))))
1720 ;; Laplace transform of two hankel_2 functions
1721 (cond ((setq l (m2-two-hankel_2 u *var*))
1722 (setq index1 (cdras 'v1 l)
1723 index2 (cdras 'v2 l)
1724 arg1 (cdras 'w1 l)
1725 arg2 (cdras 'w2 l)
1726 rest (cdras 'u l))
1727 ;; Call the code for the symbol %h.
1728 (return (fractest rest arg1 arg2 index1 2 index2 2 '2htjory))))
1730 ;; Laplace transform of hankel_1 * hankel_2
1731 (cond ((setq l (m2-hankel_1*hankel_2 u *var*))
1732 (setq index1 (cdras 'v1 l)
1733 index2 (cdras 'v2 l)
1734 arg1 (cdras 'w1 l)
1735 arg2 (cdras 'w2 l)
1736 rest (cdras 'u l))
1737 ;; Call the code for the symbol %h.
1738 (return (fractest rest arg1 arg2 index1 1 index2 2 '2htjory))))
1740 ;; Laplace transform of two Bessel Y functions
1741 (cond ((setq l (m2-twoy u *var*))
1742 (setq index1 (cdras 'v1 l)
1743 index2 (cdras 'v2 l)
1744 arg1 (cdras 'w1 l)
1745 arg2 (cdras 'w2 l)
1746 rest (cdras 'u l))
1747 (return (fractest rest arg1 arg2 index1 nil index2 nil '2ytj))))
1749 ;; Laplace transform of two Bessel K functions
1750 (cond ((setq l (m2-twok u *var*))
1751 (setq index1 (cdras 'v1 l)
1752 index2 (cdras 'v2 l)
1753 arg1 (cdras 'w1 l)
1754 arg2 (cdras 'w2 l)
1755 rest (cdras 'u l))
1756 (return (fractest rest arg1 arg2 index1 nil index2 nil '2kti))))
1758 ;; Laplace transform of Bessel K and Bessel Y functions
1759 (cond ((setq l (m2-onekoney u *var*))
1760 (setq index1 (cdras 'v1 l)
1761 index2 (cdras 'v2 l)
1762 arg1 (cdras 'w1 l)
1763 arg2 (cdras 'w2 l)
1764 rest (cdras 'u l))
1765 (return (fractest rest arg1 arg2 index1 nil index2 nil 'ktiytj))))
1767 ;; Laplace transform of Bessel I and Bessel J functions
1768 (cond ((setq l (m2-oneionej u *var*))
1769 (setq index1 (cdras 'v1 l)
1770 index2 (cdras 'v2 l)
1771 index21 (cdras 'v21 l)
1772 arg1 (mul '$%i (cdras 'w1 l))
1773 arg2 (cdras 'w2 l)
1774 rest (mul (power '$%i (neg index1)) (cdras 'u l)))
1775 (return (lt2j rest arg1 arg2 index1 index2))))
1777 ;; Laplace transform of Bessel I and Hankel 1 functions
1778 (cond ((setq l (m2-bessel_i*hankel_1 u *var*))
1779 (setq index1 (cdras 'v1 l)
1780 index2 (cdras 'v2 l)
1781 arg1 (mul '$%i (cdras 'w1 l))
1782 arg2 (cdras 'w2 l)
1783 rest (mul (power '$%i (neg index1)) (cdras 'u l)))
1784 (return (fractest1 rest arg1 arg2 index1 index2 1 'besshtjory))))
1786 ;; Laplace transform of Bessel I and Hankel 2 functions
1787 (cond ((setq l (m2-bessel_i*hankel_2 u *var*))
1788 (setq index1 (cdras 'v1 l)
1789 index2 (cdras 'v2 l)
1790 arg1 (mul '$%i (cdras 'w1 l))
1791 arg2 (cdras 'w2 l)
1792 rest (mul (power '$%i (neg index1)) (cdras 'u l)))
1793 (return (fractest1 rest arg1 arg2 index1 index2 2 'besshtjory))))
1795 ;; Laplace transform of Bessel Y and Bessel J functions
1796 (cond ((setq l (m2-oneyonej u *var*))
1797 (setq index1 (cdras 'v1 l)
1798 index2 (cdras 'v2 l)
1799 arg1 (cdras 'w1 l)
1800 arg2 (cdras 'w2 l)
1801 rest (cdras 'u l))
1802 (return (fractest1 rest arg2 arg1 index2 index1 nil 'bessytj))))
1804 ;; Laplace transform of Bessel K and Bessel J functions
1805 (cond ((setq l (m2-onekonej u *var*))
1806 (setq index1 (cdras 'v1 l)
1807 index2 (cdras 'v2 l)
1808 arg1 (cdras 'w1 l)
1809 arg2 (cdras 'w2 l)
1810 rest (cdras 'u l))
1811 (return (fractest1 rest arg2 arg1 index2 index1 nil 'besskti))))
1813 ;; Laplace transform of Hankel 1 and Bessel J functions
1814 (cond ((setq l (m2-hankel_1*bessel_j u *var*))
1815 (setq index1 (cdras 'v1 l)
1816 index2 (cdras 'v2 l)
1817 arg1 (cdras 'w1 l)
1818 arg2 (cdras 'w2 l)
1819 rest (cdras 'u l))
1820 (return (fractest1 rest arg2 arg1 index2 index1 1 'besshtjory))))
1822 ;; Laplace transform of Hankel 2 and Bessel J functions
1823 (cond ((setq l (m2-hankel_2*bessel_j u *var*))
1824 (setq index1 (cdras 'v1 l)
1825 index2 (cdras 'v2 l)
1826 arg1 (cdras 'w1 l)
1827 arg2 (cdras 'w2 l)
1828 rest (cdras 'u l))
1829 (return (fractest1 rest arg2 arg1 index2 index1 2 'besshtjory))))
1831 ;; Laplace transform of Bessel Y and Hankel 1 functions
1832 (cond ((setq l (m2-bessel_y*hankel_1 u *var*))
1833 (setq index1 (cdras 'v1 l)
1834 index2 (cdras 'v2 l)
1835 arg1 (cdras 'w1 l)
1836 arg2 (cdras 'w2 l)
1837 rest (cdras 'u l))
1838 (return (fractest1 rest arg2 arg1 index2 index1 1 'htjoryytj))))
1840 ;; Laplace transform of Bessel Y and Hankel 2 functions
1841 (cond ((setq l (m2-bessel_y*hankel_2 u *var*))
1842 (setq index1 (cdras 'v1 l)
1843 index2 (cdras 'v2 l)
1844 arg1 (cdras 'w1 l)
1845 arg2 (cdras 'w2 l)
1846 rest (cdras 'u l))
1847 (return (fractest1 rest arg2 arg1 index2 index1 2 'htjoryytj))))
1849 ;; Laplace transform of Bessel K and Hankel 1 functions
1850 (cond ((setq l (m2-bessel_k*hankel_1 u *var*))
1851 (setq index1 (cdras 'v1 l)
1852 index2 (cdras 'v2 l)
1853 arg1 (cdras 'w1 l)
1854 arg2 (cdras 'w2 l)
1855 rest (cdras 'u l))
1856 (return (fractest1 rest arg2 arg1 index2 index1 1 'htjorykti))))
1858 ;; Laplace transform of Bessel K and Hankel 2 functions
1859 (cond ((setq l (m2-bessel_k*hankel_2 u *var*))
1860 (setq index1 (cdras 'v1 l)
1861 index2 (cdras 'v2 l)
1862 arg1 (cdras 'w1 l)
1863 arg2 (cdras 'w2 l)
1864 rest (cdras 'u l))
1865 (return (fractest1 rest arg2 arg1 index2 index1 2 'htjorykti))))
1867 ;; Laplace transform of Bessel I and Bessel Y functions
1868 (cond ((setq l (m2-oneioney u *var*))
1869 (setq index1 (cdras 'v1 l)
1870 index2 (cdras 'v2 l)
1871 arg1 (mul '$%i (cdras 'w1 l))
1872 arg2 (cdras 'w2 l)
1873 rest (mul (power '$%i (neg index1)) (cdras 'u l)))
1874 (return (fractest1 rest arg1 arg2 index1 index2 nil 'bessytj))))
1876 ;; Laplace transform of Bessel I and Bessel K functions
1877 (cond ((setq l (m2-oneionek u *var*))
1878 (setq index1 (cdras 'v1 l)
1879 index2 (cdras 'v2 l)
1880 arg1 (mul '$%i (cdras 'w1 l))
1881 arg2 (cdras 'w2 l)
1882 rest (mul (power '$%i (neg index1)) (cdras 'u l)))
1883 (return (fractest1 rest arg1 arg2 index1 index2 nil 'besskti))))
1885 ;; Laplace transform of Struve H function
1886 (cond ((setq l (m2-struve_h u *var*))
1887 (setq index1 (cdras 'v l)
1888 arg1 (cdras 'w l)
1889 rest (cdras 'u l))
1890 (return (lt1hstruve rest arg1 index1))))
1892 ;; Laplace transform of Struve L function
1893 (cond ((setq l (m2-struve_l u *var*))
1894 (setq index1 (cdras 'v l)
1895 arg1 (cdras 'w l)
1896 rest (cdras 'u l))
1897 (return (lt1lstruve rest arg1 index1))))
1899 ;; Laplace transform of little Lommel s function
1900 (cond ((setq l (m2-ones u *var*))
1901 (setq index1 (cdras 'v1 l)
1902 index2 (cdras 'v2 l)
1903 arg1 (cdras 'w l)
1904 rest (cdras 'u l))
1905 (return (lt1s rest arg1 index1 index2))))
1907 ;; Laplace transform of Lommel S function
1908 (cond ((setq l (m2-oneslommel u *var*))
1909 (setq index1 (cdras 'v1 l)
1910 index2 (cdras 'v2 l)
1911 arg1 (cdras 'w l)
1912 rest (cdras 'u l))
1913 (return (fractest2 rest arg1 index1 index2 'slommel))))
1915 ;; Laplace transform of Bessel Y function
1916 (cond ((setq l (m2-oney u *var*))
1917 (setq index1 (cdras 'v l)
1918 arg1 (cdras 'w l)
1919 rest (cdras 'u l))
1920 (return (lt1yref rest arg1 index1))))
1922 ;; Laplace transform of Bessel K function
1923 (cond ((setq l (m2-onek u *var*))
1924 (setq index1 (cdras 'v l)
1925 arg1 (cdras 'w l)
1926 rest (cdras 'u l))
1927 (cond ((zerop1 index1)
1928 ;; Special case for a zero index
1929 (return (lt-bessel_k0 rest arg1)))
1931 (return (fractest2 rest arg1 index1 nil 'kti))))))
1933 ;; Laplace transform of Parabolic Cylinder function
1934 (cond ((setq l (m2-parabolic_cylinder_d u *var*))
1935 (setq index1 (cdras 'v l)
1936 arg1 (cdras 'w l)
1937 rest (cdras 'u l))
1938 (return (fractest2 rest arg1 index1 nil 'd))))
1940 ;; Laplace transform of Incomplete Gamma function
1941 (cond ((setq l (m2-onegammaincomplete u *var*))
1942 (setq arg1 (cdras 'w1 l)
1943 arg2 (cdras 'w2 l)
1944 rest (cdras 'u l))
1945 (return (fractest2 rest arg1 arg2 nil 'gamma_incomplete))))
1947 ;; Laplace transform of Batemann function
1948 (cond ((setq l (m2-onekbateman u *var*))
1949 (setq index1 (cdras 'v l)
1950 arg1 (cdras 'w l)
1951 rest (cdras 'u l))
1952 (return (fractest2 rest arg1 index1 nil 'kbateman))))
1954 ;; Laplace transform of Bessel J function
1955 (cond ((setq l (m2-onej u *var*))
1956 (setq index1 (cdras 'v l)
1957 arg1 (cdras 'w l)
1958 rest (cdras 'u l))
1959 (return (lt1j rest arg1 index1))))
1961 ;; Laplace transform of lower incomplete Gamma function
1962 (cond ((setq l (m2-onegamma-incomplete-lower u *var*))
1963 (setq arg1 (cdras 'w1 l)
1964 arg2 (cdras 'w2 l)
1965 rest (cdras 'u l))
1966 (return (lt1gamma-incomplete-lower rest arg1 arg2))))
1968 ;; Laplace transform of Hankel 1 function
1969 (cond ((setq l (m2-hankel_1 u *var*))
1970 (setq index1 (cdras 'v l)
1971 arg1 (cdras 'w l)
1972 rest (cdras 'u l))
1973 (return (fractest2 rest arg1 index1 1 'htjory))))
1975 ;; Laplace transform of Hankel 2 function
1976 (cond ((setq l (m2-hankel_2 u *var*))
1977 (setq index1 (cdras 'v l)
1978 arg1 (cdras 'w l)
1979 rest (cdras 'u l))
1980 (return (fractest2 rest arg1 index1 2 'htjory))))
1982 ;; Laplace transform of Whittaker M function
1983 (cond ((setq l (m2-onem u *var*))
1984 (setq index1 (cdras 'v1 l)
1985 index11 (cdras 'v2 l)
1986 arg1 (cdras 'w l)
1987 rest (cdras 'u l))
1988 (return (lt1m rest arg1 index1 index11))))
1990 ;; Laplace transform of Whittaker M function
1991 (cond ((setq l (m2-whittaker_m u *var*))
1992 (setq index1 (cdras 'v1 l)
1993 index2 (cdras 'v2 l)
1994 arg1 (cdras 'w l)
1995 rest (cdras 'u l))
1996 (return (lt1m rest arg1 index1 index2))))
1998 ;; Laplace transform of the Generalized Laguerre function, %l[v1,v2](w)
1999 (cond ((setq l (m2-onel u *var*))
2000 (setq index1 (cdras 'v1 l)
2001 index11 (cdras 'v2 l)
2002 arg1 (cdras 'w l)
2003 rest (cdras 'u l))
2004 (return (integertest rest arg1 index1 index11 'l))))
2006 ;; Laplace transform for the Generalized Laguerre function
2007 ;; We call the routine for %l[v1,v2](w).
2008 (cond ((setq l (m2-one-gen-laguerre u *var*))
2009 (setq index1 (cdras 'v1 l)
2010 index2 (cdras 'v2 l)
2011 arg1 (cdras 'w l)
2012 rest (cdras 'u l))
2013 (return (integertest rest arg1 index1 index2 'l))))
2015 ;; Laplace transform for the Laguerre function
2016 ;; We call the routine for %l[v1,0](w).
2017 (cond ((setq l (m2-one-laguerre u *var*))
2018 (setq index1 (cdras 'v1 l)
2019 arg1 (cdras 'w l)
2020 rest (cdras 'u l))
2021 (return (integertest rest arg1 index1 0 'l))))
2023 ;; Laplace transform of Gegenbauer function
2024 (cond ((setq l (m2-onec u *var*))
2025 (setq index1 (cdras 'v1 l)
2026 index11 (cdras 'v2 l)
2027 arg1 (cdras 'w l)
2028 rest (cdras 'u l))
2029 (return (integertest rest arg1 index1 index11 'c))))
2031 ;; Laplace transform of Chebyshev function of the first kind
2032 (cond ((setq l (m2-onet u *var*))
2033 (setq index1 (cdras 'v1 l)
2034 arg1 (cdras 'w l)
2035 rest (cdras 'u l))
2036 (return (integertest rest arg1 index1 nil 't))))
2038 ;; Laplace transform of Chebyshev function of the second kind
2039 (cond ((setq l (m2-oneu u *var*))
2040 (setq index1 (cdras 'v1 l)
2041 arg1 (cdras 'w l)
2042 rest (cdras 'u l))
2043 (return (integertest rest arg1 index1 nil 'u))))
2045 ;; Laplace transform for the Hermite function, hermite(index1,arg1)
2046 (cond ((setq l (m2-one-hermite u *var*))
2047 (setq index1 (cdras 'v1 l)
2048 arg1 (cdras 'w l)
2049 rest (cdras 'u l))
2050 (return
2051 (cond ((and (maxima-integerp index1)
2052 (or (mevenp index1)
2053 (moddp index1)))
2054 ;; When index1 is an even or odd integer, we transform
2055 ;; directly to a hypergeometric function. For this case we
2056 ;; get a Laplace transform when the arg is the
2057 ;; square root of the variable.
2058 (sendexec rest (hermite-to-hypergeometric index1 arg1)))
2060 (integertest rest arg1 index1 nil 'he))))))
2062 ;; Laplace transform of %p[v1,v2](w), Associated Legendre P function
2063 (cond ((setq l (m2-hyp-onep u *var*))
2064 (setq index1 (cdras 'v1 l)
2065 index11 (cdras 'v2 l)
2066 arg1 (cdras 'w l)
2067 rest (cdras 'u l))
2068 (return (lt1p rest arg1 index1 index11))))
2070 ;; Laplace transform of Associated Legendre P function
2071 (cond ((setq l (m2-assoc_legendre_p u *var*))
2072 (setq index1 (cdras 'v1 l)
2073 index2 (cdras 'v2 l)
2074 arg1 (cdras 'w l)
2075 rest (cdras 'u l))
2076 (return (lt1p rest arg1 index1 index2))))
2078 ;; Laplace transform of %p[v1,v2,v3](w), Jacobi function
2079 (cond ((setq l (m2-onepjac u *var*))
2080 (setq index1 (cdras 'v1 l)
2081 index2 (cdras 'v2 l)
2082 index21 (cdras 'v3 l)
2083 arg1 (cdras 'w l)
2084 rest (cdras 'u l))
2085 (return (pjactest rest arg1 index1 index2 index21))))
2087 ;; Laplace transform of Jacobi P function
2088 (cond ((setq l (m2-jacobi_p u *var*))
2089 (setq index1 (cdras 'v1 l)
2090 index2 (cdras 'v2 l)
2091 index21 (cdras 'v3 l)
2092 arg1 (cdras 'w l)
2093 rest (cdras 'u l))
2094 (return (pjactest rest arg1 index1 index2 index21))))
2096 ;; Laplace transform of Associated Legendre function of the second kind
2097 (cond ((setq l (m2-oneq u *var*))
2098 (setq index1 (cdras 'v1 l)
2099 index11 (cdras 'v2 l)
2100 arg1 (cdras 'w l)
2101 rest (cdras 'u l))
2102 (return (lt1q rest arg1 index1 index11))))
2104 ;; Laplace transform of Associated Legendre function of the second kind
2105 (cond ((setq l (m2-assoc_legendre_q u *var*))
2106 (setq index1 (cdras 'v1 l)
2107 index2 (cdras 'v2 l)
2108 arg1 (cdras 'w l)
2109 rest (cdras 'u l))
2110 (return (lt1q rest arg1 index1 index2))))
2112 ;; Laplace transform of %p[v1](w), Legendre P function
2113 (cond ((setq l (m2-onep0 u *var*))
2114 (setq index1 (cdras 'v1 l)
2115 index11 0
2116 arg1 (cdras 'w l)
2117 rest (cdras 'u l))
2118 (return (lt1p rest arg1 index1 index11))))
2120 ;; Laplace transform of Legendre P function
2121 (cond ((setq l (m2-legendre_p u *var*))
2122 (setq index1 (cdras 'v1 l)
2123 arg1 (cdras 'w l)
2124 rest (cdras 'u l))
2125 (return (lt1p rest arg1 index1 0))))
2127 ;; Laplace transform of Whittaker W function
2128 (cond ((setq l (m2-onew u *var*))
2129 (setq index1 (cdras 'v1 l)
2130 index11 (cdras 'v2 l)
2131 arg1 (cdras 'w l)
2132 rest (cdras 'u l))
2133 (return (whittest rest arg1 index1 index11))))
2135 ;; Laplace transform of Whittaker W function
2136 (cond ((setq l (m2-whittaker_w u *var*))
2137 (setq index1 (cdras 'v1 l)
2138 index2 (cdras 'v2 l)
2139 arg1 (cdras 'w l)
2140 rest (cdras 'u l))
2141 (return (whittest rest arg1 index1 index2))))
2143 ;; Laplace transform of square of Bessel J function
2144 (cond ((setq l (m2-onej^2 u *var*))
2145 (setq index1 (cdras 'v l)
2146 arg1 (cdras 'w l)
2147 rest (cdras 'u l))
2148 (return (lt1j^2 rest arg1 index1))))
2150 ;; Laplace transform of square of Hankel 1 function
2151 (cond ((setq l (m2-hankel_1^2 u *var*))
2152 (setq index1 (cdras 'v l)
2153 arg1 (cdras 'w l)
2154 rest (cdras 'u l))
2155 (return (fractest rest arg1 arg1 index1 1 index1 1 '2htjory))))
2157 ;; Laplace transform of square of Hankel 2 function
2158 (cond ((setq l (m2-hankel_2^2 u *var*))
2159 (setq index1 (cdras 'v l)
2160 arg1 (cdras 'w l)
2161 rest (cdras 'u l))
2162 (return (fractest rest arg1 arg1 index1 2 index1 2 '2htjory))))
2164 ;; Laplace transform of square of Bessel Y function
2165 (cond ((setq l (m2-oney^2 u *var*))
2166 (setq index1 (cdras 'v l)
2167 arg1 (cdras 'w l)
2168 rest (cdras 'u l))
2169 (return (fractest rest arg1 arg1 index1 nil index1 nil '2ytj))))
2171 ;; Laplace transform of square of Bessel K function
2172 (cond ((setq l (m2-onek^2 u *var*))
2173 (setq index1 (cdras 'v l)
2174 arg1 (cdras 'w l)
2175 rest (cdras 'u l))
2176 (return (fractest rest arg1 arg1 index1 nil index1 nil '2kti))))
2178 ;; Laplace transform of two Bessel I functions
2179 (cond ((setq l (m2-twoi u *var*))
2180 (setq index1 (cdras 'v1 l)
2181 index2 (cdras 'v2 l)
2182 arg1 (mul '$%i (cdras 'w1 l))
2183 arg2 (mul '$%i (cdras 'w2 l))
2184 rest (mul (power '$%i (neg index1))
2185 (power '$%i (neg index1))
2186 (cdras 'u l)))
2187 (return (lt2j rest arg1 arg2 index1 index2))))
2189 ;; Laplace transform of Bessel I. We use I[v](w)=%i^n*J[n](%i*w).
2190 (cond ((setq l (m2-onei u *var*))
2191 (setq index1 (cdras 'v l)
2192 arg1 (mul '$%i (cdras 'w l))
2193 rest (mul (power '$%i (neg index1)) (cdras 'u l)))
2194 (return (lt1j rest arg1 index1))))
2196 ;; Laplace transform of square of Bessel I function
2197 (cond ((setq l (m2-onei^2 u *var*))
2198 (setq index1 (cdras 'v l)
2199 arg1 (mul '$%i (cdras 'w l))
2200 rest (mul (power '$%i (neg index1))
2201 (power '$%i (neg index1))
2202 (cdras 'u l)))
2203 (return (lt1j^2 rest arg1 index1))))
2205 ;; Laplace transform of Erf function
2206 (cond ((setq l (m2-onerf u *var*))
2207 (setq arg1 (cdras 'w l)
2208 rest (cdras 'u l))
2209 (return (lt1erf rest arg1))))
2211 ;; Laplace transform of the logarithmic function.
2212 ;; We add an algorithm for the Laplace transform and call the routine
2213 ;; lt-log. The old code is still present, but isn't called.
2214 (cond ((setq l (m2-onelog u *var*))
2215 (setq arg1 (cdras 'w l)
2216 rest (cdras 'u l))
2217 (return (lt-log rest arg1))))
2219 ;; Laplace transform of Erfc function
2220 (cond ((setq l (m2-onerfc u *var*))
2221 (setq arg1 (cdras 'w l)
2222 rest (cdras 'u l))
2223 (return (fractest2 rest arg1 nil nil 'erfc))))
2225 ;; Laplace transform of expintegral_ei.
2226 ;; Maxima uses the build in transformation to the gamma_incomplete
2227 ;; function and simplifies the log functions of the transformation. We do
2228 ;; not use the dispatch mechanism of fractest2, but call sendexec directly
2229 ;; with the transformed function.
2230 (cond ((setq l (m2-oneexpintegral_ei u *var*))
2231 (setq arg1 (cdras 'w l)
2232 rest (cdras 'u l))
2233 (let (($expintrep '%gamma_incomplete)
2234 ($logexpand '$all))
2235 (return (sratsimp (sendexec rest (ftake '%expintegral_ei arg1)))))))
2237 ;; Laplace transform of expintegral_e1
2238 (cond ((setq l (m2-oneexpintegral_e1 u *var*))
2239 (setq arg1 (cdras 'w l)
2240 rest (cdras 'u l))
2241 (let (($expintrep '%gamma_incomplete)
2242 ($logexpand '$all))
2243 (return (sratsimp (sendexec rest (ftake '%expintegral_e1 arg1)))))))
2245 ;; Laplace transform of expintegral_e
2246 (cond ((setq l (m2-oneexpintegral_e u *var*))
2247 (setq arg1 (cdras 'v l)
2248 arg2 (cdras 'w l)
2249 rest (cdras 'u l))
2250 (let (($expintrep '%gamma_incomplete)
2251 ($logexpand '$all))
2252 (return (sratsimp (sendexec rest (ftake '%expintegral_e arg1 arg2)))))))
2254 ;; Laplace transform of expintegral_si
2255 (cond ((setq l (m2-oneexpintegral_si u *var*))
2256 (setq arg1 (cdras 'w l)
2257 rest (cdras 'u l))
2258 ;; We transform to the hypergeometric representation.
2259 (return
2260 (sendexec rest (expintegral_si-to-hypergeometric arg1)))))
2262 ;; Laplace transform of expintegral_shi
2263 (cond ((setq l (m2-oneexpintegral_shi u *var*))
2264 (setq arg1 (cdras 'w l)
2265 rest (cdras 'u l))
2266 ;; We transform to the hypergeometric representation.
2267 (return
2268 (sendexec rest (expintegral_shi-to-hypergeometric arg1)))))
2270 ;; Laplace transform of expintegral_ci
2271 (cond ((setq l (m2-oneexpintegral_ci u *var*))
2272 (setq arg1 (cdras 'w l)
2273 rest (cdras 'u l))
2274 ;; We transform to the hypergeometric representation.
2275 ;; Because we have Logarithmic terms in the transformation,
2276 ;; we switch on the flag $logexpand and do a ratsimp.
2277 (let (($logexpand '$super))
2278 (return
2279 (sratsimp
2280 (sendexec rest (expintegral_ci-to-hypergeometric arg1)))))))
2282 ;; Laplace transform of expintegral_chi
2283 (cond ((setq l (m2-oneexpintegral_chi u *var*))
2284 (setq arg1 (cdras 'w l)
2285 rest (cdras 'u l))
2286 ;; We transform to the hypergeometric representation.
2287 ;; Because we have Logarithmic terms in the transformation,
2288 ;; we switch on the flag $logexpand and do a ratsimp.
2289 (let (($logexpand '$super))
2290 (return
2291 (sratsimp
2292 (sendexec rest (expintegral_chi-to-hypergeometric arg1)))))))
2294 ;; Laplace transform of Complete elliptic integral of the first kind
2295 (cond ((setq l (m2-onekelliptic u *var*))
2296 (setq arg1 (cdras 'w l)
2297 rest (cdras 'u l))
2298 (return (lt1kelliptic rest arg1))))
2300 ;; Laplace transform of Complete elliptic integral of the first kind
2301 (cond ((setq l (m2-elliptic_kc u *var*))
2302 (setq arg1 (cdras 'w l)
2303 rest (cdras 'u l))
2304 (return (lt1kelliptic rest arg1))))
2306 ;; Laplace transform of Complete elliptic integral of the second kind
2307 (cond ((setq l (m2-onee u *var*))
2308 (setq arg1 (cdras 'w l)
2309 rest (cdras 'u l))
2310 (return (lt1e rest arg1))))
2312 ;; Laplace transform of Complete elliptic integral of the second kind
2313 (cond ((setq l (m2-elliptic_ec u *var*))
2314 (setq arg1 (cdras 'w l)
2315 rest (cdras 'u l))
2316 (return (lt1e rest arg1))))
2318 ;; Laplace transform of %f[v1,v2](w1,w2,w3), Hypergeometric function
2319 ;; We support the Laplace transform of the build in symbol %f. We do
2320 ;; not use the mechanism of defining an "Expert on Laplace transform",
2321 ;; the expert function does a call to lt-ltp. We do this call directly.
2322 (cond ((setq l (m2-onef u *var*))
2323 (setq rest (cdras 'u l)
2324 arg1 (cdras 'w3 l)
2325 index1 (list (cdras 'w1 l) (cdras 'w2 l)))
2326 (return (lt-ltp 'f rest arg1 index1))))
2328 ;; Laplace transform of Hypergeometric function
2329 (cond ((setq l (m2-hypergeometric u *var*))
2330 (setq rest (cdras 'u l)
2331 arg1 (cdras 'w3 l)
2332 index1 (list (cdras 'w1 l) (cdras 'w2 l)))
2333 (return (lt-ltp 'f rest arg1 index1))))
2335 ;; Laplace transform of c * t^v * (a+t)^w
2336 ;; It is possible to combine arbpow2 and arbpow.
2337 (cond ((setq l (m2-arbpow2 u *var*))
2338 (setq rest (cdras 'c l)
2339 arg1 (cdras 'a l)
2340 arg2 (cdras 'b l)
2341 index1 (cdras 'v l)
2342 index2 (cdras 'w l))
2343 (return (lt-arbpow2 rest arg1 arg2 index1 index2))))
2345 ;; Laplace transform of c * t^v
2346 (cond ((setq l (m2-arbpow1 u *var*))
2347 (setq arg1 (cdras 'u l)
2348 arg2 (cdras 'c l)
2349 index1 (cdras 'v l))
2350 (return (mul arg2 (lt-arbpow arg1 index1)))))
2352 ;; We have specialized the pattern for arbpow1. Now a lot of integrals
2353 ;; will fail correctly and we have to return a noun form.
2354 (return (setq *hyp-return-noun-flag* 'other-j-cases-next))))
2356 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2358 ;;; Algorithm 2.1: Laplace transform of c*t^u
2360 ;;; Table of Integral Transforms
2362 ;;; p. 137, formula 1:
2364 ;;; t^u
2365 ;;; -> gamma(u+1)*p^(-u-1)
2367 ;;; Re(u) > -1
2368 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2370 (defun lt-arbpow (expr pow)
2371 (cond ((or (eq expr *var*) (equal pow 0))
2372 (f1p137test pow))
2374 (setq *hyp-return-noun-flag* 'lt-arbow-failed))))
2376 ;; Check if conditions for f1p137 hold
2377 (defun f1p137test (pow)
2378 (cond ((eq ($asksign ($realpart (add pow 1))) '$pos)
2379 (f1p137 pow))
2381 (setq *hyp-return-noun-flag* 'fail-in-arbpow))))
2383 (defun f1p137 (pow)
2384 (mul (take '(%gamma) (add pow 1))
2385 (power *par* (sub (mul -1 pow) 1))))
2387 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2389 ;;; Algorithm 2.2: Laplace transform of c*t^v*(1+t)^w
2391 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2393 (defun lt-arbpow2 (c a b pow1 pow2)
2394 (if (eq ($asksign (add pow1 1)) '$pos)
2395 (cond
2396 ((equal pow1 0)
2397 ;; The Laplace transform is an Incomplete Gamma function.
2398 (mul c
2399 (power a (add pow2 1))
2400 (inv b)
2401 (power (mul *par* a (inv b)) (mul -1 (add pow2 1)))
2402 (power '$%e (mul *par* a (inv b)))
2403 (take '(%gamma_incomplete) (add pow2 1) (mul *par* a (inv b)))))
2404 ((not (maxima-integerp (add pow1 pow2 2)))
2405 ;; The general result is a Hypergeometric U function U(a,b,z) which can
2406 ;; be represented by two Hypergeometic 1F1 functions for the special
2407 ;; case that the index b is not an integer value.
2408 (add (mul c
2409 (power a (add pow1 pow2 1))
2410 (inv (power b (add pow1 1)))
2411 (take '(%gamma) (add pow1 pow2 1))
2412 (power (mul *par* a (inv b)) (mul -1 (add pow1 pow2 1)))
2413 (hgfsimp-exec (list (mul -1 pow2))
2414 (list (mul -1 (add pow1 pow2)))
2415 (mul *par* a (inv b))))
2416 (mul c
2417 (power a (add pow1 pow2 1))
2418 (inv (power b (add pow1 1)))
2419 (take '(%gamma) (add pow1 1))
2420 (take '(%gamma) (mul -1 (add pow1 pow2 1)))
2421 (inv (take '(%gamma) (mul -1 pow2)))
2422 (hgfsimp-exec (list (add pow1 1))
2423 (list (add pow1 pow2 2))
2424 (mul *par* a (inv b))))))
2426 ;; The most general case is a result with the Hypergeometric U function.
2427 (mul c
2428 (power a (add pow1 pow2 1))
2429 (inv (power b (add pow1 1)))
2430 (take '(%gamma) (add pow1 1))
2431 (take '($hypergeometric_u)
2432 (add pow1 1)
2433 (add pow1 pow2 2)
2434 (mul *par* a (inv b))))))
2435 (setq *hyp-return-noun-flag* 'lt-arbpow2-failed)))
2437 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2439 ;;; Algorithm 2.3: Laplace transform of the Logarithmic function
2441 ;;; c*t^(v-1)*log(a*t)
2442 ;;; -> c*gamma(v)*s^(-v)*(psi[0](v)-log(s/a))
2444 ;;; This is the formula for an expression with log(t) scaled like 1/a*F(s/a).
2446 ;;; For the following cases we have to add further algorithm:
2447 ;;; log(1+a*x), log(x+a), log(x)^2.
2448 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2450 (defun lt-log (rest arg)
2451 (let* ((l (m2-c*t^v rest *var*))
2452 (c (cdras 'c l))
2453 (v (add (cdras 'v l) 1))) ; because v -> v-1
2454 (cond
2455 ((and l (eq ($asksign v) '$pos))
2456 (let* ((l1 (m2-a*t arg *var*))
2457 (a (cdras 'a l1)))
2458 (cond (l1
2459 (mul c
2460 (take '(%gamma) v)
2461 (inv (power *par* v))
2462 (sub (take '(mqapply) (list '($psi array) 0) v)
2463 (take '(%log) (div *par* a)))))
2465 (setq *hyp-return-noun-flag* 'lt-log-failed)))))
2467 (setq *hyp-return-noun-flag* 'lt-log-failed)))))
2469 ;; Pattern for lt-log.
2470 ;; Extract the argument of a function: a*t+c for c=0.
2471 (defun m2-a*t (expr var2)
2472 (m2 expr
2473 `((mplus)
2474 ((mtimes) (u alike1 ,var2) (a free ,var2))
2475 ((coeffpp) (c equal 0)))))
2477 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2478 ;;; Algorithm 2.4: Laplace transform of the Whittaker function
2480 ;;; Test for Whittaker W function. Simplify this if possible, or
2481 ;;; convert to Whittaker M function.
2483 ;;; We have r * %w[i1,i2](a)
2485 ;;; Formula 16, p. 217
2487 ;;; t^(v-1)*%w[k,u](a*t)
2488 ;;; -> gamma(u+v+1/2)*gamma(v-u+1/2)*a^(u+1/2)/
2489 ;;; (gamma(v-k+1)*(p+a/2)^(u+v+1/2)
2490 ;;; *2f1(u+v+1/2,u-k+1/2;v-k+1;(p-a/2)/(p+a/2))
2492 ;;; For Re(v +/- mu) > -1/2
2493 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2495 (defun whittest (r a i1 i2)
2496 (let (n m)
2497 (cond ((f16p217test r a i1 i2))
2498 ((and
2499 (not
2500 (and (maxima-integerp (setq n (sub (sub '((rat simp) 1 2) i2) i1)))
2501 (member ($sign n) '($zero $neg $nz))))
2502 (not
2503 (and (maxima-integerp (setq m (sub (add '((rat simp) 1 2) i2) i1)))
2504 (member ($sign m) '($zero $neg $nz)))))
2505 ;; 1/2-u-k and 1/2+u-k are not zero or a negative integer
2506 ;; Transform to Whittaker M and try again.
2507 (distrexecinit ($expand (mul (init r) (wtm a i1 i2)))))
2509 ;; Both conditions fails, return a noun form.
2510 (setq *hyp-return-noun-flag* 'whittest-failed)))))
2512 (defun f16p217test (r a i1 i2)
2513 ;; We have r*%w[i1,i2](a)
2514 (let ((l (m2-c*t^v r *var*)))
2515 ;; Make sure r is of the form c*t^v
2516 (when l
2517 (let* ((v (add (cdras 'v l) 1))
2518 (c (cdras 'c l)))
2519 ;; Check that v + i2 + 1/2 > 0 and v - i2 + 1/2 > 0.
2520 (when (and (eq ($asksign (add (add v i2) '((rat simp) 1 2))) '$pos)
2521 (eq ($asksign (add (sub v i2) '((rat simp) 1 2))) '$pos))
2522 ;; Ok, we satisfy the conditions. Now extract the arg.
2523 ;; The transformation is only valid for an argument a*t. We have
2524 ;; to special the pattern to make sure that we satisfy the condition.
2525 (let ((l (m2-a*t a *var*)))
2526 (when l
2527 (let ((a (cdras 'a l)))
2528 ;; We're ready now to compute the transform.
2529 (mul c
2530 (power a (add i2 '((rat simp) 1 2)))
2531 (take '(%gamma) (add (add v i2) '((rat simp) 1 2)))
2532 (take '(%gamma) (add (sub v i2) '((rat simp) 1 2)))
2533 (inv (mul (take '(%gamma) (add (sub v i1) 1))
2534 (power (add *par* (div a 2))
2535 (add (add i2 v) '((rat simp) 1 2)))))
2536 (hgfsimp-exec (list (add (add i2 v '((rat simp) 1 2)))
2537 (add (sub i2 i1) '((rat simp) 1 2)))
2538 (list (add (sub v i1) 1))
2539 (div (sub *par* (div a 2))
2540 (add *par* (div a 2)))))))))))))
2542 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2543 ;;; Algorithm 2.5: Laplace transform of bessel_k(0,a*t)
2545 ;;; The general algorithm handles the Bessel K function for an order |v|<1.
2546 ;;; but does not include the special case v=0. Return the Laplace transform:
2548 ;;; bessel_k(0,a*t) --> acosh(s/a)/sqrt(s^2-a^2)
2550 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2552 (defun lt-bessel_k0 (rest arg)
2553 (let* ((l (m2-c*t^v rest *var*))
2554 (c (cdras 'c l))
2555 (v (cdras 'v l))
2556 (l (m2-a*t arg *var*))
2557 (a (cdras 'a l)))
2558 (cond ((and l (zerop1 v))
2559 (mul c
2560 (take '(%acosh) (div *par* a))
2561 (inv (power (sub (mul *par* *par*) (mul a a))
2562 '((rat simp) 1 2)))))
2564 (setq *hyp-return-noun-flag* 'lt-bessel_k-failed)))))
2566 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2568 ;;; DISPATCH FUNCTIONS TO CHANGE THE REPRESENTATION OF SPECIAL FUNCTIONS
2570 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2572 ;; Laplace transform of a product of Bessel functions. A1, A2 are
2573 ;; the args of the two functions. I1, I2 are the indices of each
2574 ;; function. I11, I21 are secondary indices of each function, if any.
2575 ;; FLG is a symbol indicating how we should handle the special
2576 ;; functions (and also indicates what the special functions are.)
2578 ;; I11 and I21 are for the Hankel functions.
2580 (defun fractest (r a1 a2 i1 i11 i2 i21 flg)
2581 (cond ((or (and (listp i1) (equal (caar i1) 'rat)
2582 (listp i2) (equal (caar i2) 'rat))
2583 (eq flg '2htjory))
2584 ;; We have to Bessel or Hankel functions. Both indizes have to be
2585 ;; rational numbers or we have two Hankel functions.
2586 (sendexec r
2587 (cond ((eq flg '2ytj)
2588 (mul (ytj i1 a1)
2589 (ytj i2 a2)))
2590 ((eq flg '2htjory)
2591 (mul (htjory i1 i11 a1)
2592 (htjory i2 i21 a2)))
2593 ((eq flg 'ktiytj)
2594 (mul (kti i1 a1)
2595 (ytj i2 a2)))
2596 ((eq flg '2kti)
2597 (mul (kti i1 a1)
2598 (kti i2 a2))))))
2600 (setq *hyp-return-noun-flag* 'product-of-y-with-nofract-indices))))
2602 ;; Laplace transform of a product of Bessel functions. A1, A2 are
2603 ;; the args of the two functions. I1, I2 are the indices of each
2604 ;; function. I is a secondary index to one function, if any.
2605 ;; FLG is a symbol indicating how we should handle the special
2606 ;; functions (and also indicates what the special functions are.)
2608 ;; I is for the kind of Hankel function.
2610 (defun fractest1 (r a1 a2 i1 i2 i flg)
2611 (cond ((or (and (listp i2)
2612 (equal (caar i2) 'rat))
2613 (eq flg 'besshtjory))
2614 ;; We have two Bessel or Hankel functions. The second index has to
2615 ;; be a rational number or one of the functions is a Hankel function
2616 ;; and the second function is Bessel J or Bessel I
2617 (sendexec r
2618 (cond ((eq flg 'bessytj)
2619 (mul (take '(%bessel_j) i1 a1)
2620 (ytj i2 a2)))
2621 ((eq flg 'besshtjory)
2622 (mul (take '(%bessel_j) i1 a1)
2623 (htjory i2 i a2)))
2624 ((eq flg 'htjoryytj)
2625 (mul (htjory i1 i a1)
2626 (ytj i2 a2)))
2627 ((eq flg 'besskti)
2628 (mul (take '(%bessel_j) i1 a1)
2629 (kti i2 a2)))
2630 ((eq flg 'htjorykti)
2631 (mul (htjory i1 i a1)
2632 (kti i2 a2))))))
2634 (setq *hyp-return-noun-flag* 'product-of-i-y-of-nofract-index))))
2636 ;; Laplace transform of a single special function. A is the arg of
2637 ;; the special function. I1, I11 are the indices of the function. FLG
2638 ;; is a symbol indicating how we should handle the special functions
2639 ;; (and also indicates what the special functions are.)
2641 ;; I11 is the kind of Hankel function
2643 (defun fractest2 (r a1 i1 i11 flg)
2644 (cond ((or (and (listp i1)
2645 (equal (caar i1) 'rat))
2646 (eq flg 'd)
2647 (eq flg 'kbateman)
2648 (eq flg 'gamma_incomplete)
2649 (eq flg 'htjory)
2650 (eq flg 'erfc)
2651 (eq flg 'slommel)
2652 (eq flg 'ytj))
2653 ;; The index is a rational number or flg has the value of one of the
2654 ;; above special functions.
2655 (sendexec r
2656 (cond ((eq flg 'ytj)
2657 (ytj i1 a1))
2658 ((eq flg 'htjory)
2659 (htjory i1 i11 a1))
2660 ((eq flg 'd)
2661 (dtw i1 a1))
2662 ((eq flg 'kbateman)
2663 (kbatemantw i1 a1))
2664 ((eq flg 'gamma_incomplete)
2665 (gamma_incomplete-to-gamma-incomplete-lower a1 i1))
2666 ((eq flg 'kti)
2667 (kti i1 a1))
2668 ((eq flg 'erfc)
2669 (erfctd a1))
2670 ((eq flg 'slommel)
2671 (slommeltjandy i1 i11 a1)))))
2673 (setq *hyp-return-noun-flag* 'y-of-nofract-index))))
2675 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2677 (defun integertest (r arg i1 i2 flg)
2678 (cond ((maxima-integerp i1)
2679 (dispatchpoltrans r arg i1 i2 flg))
2681 (setq *hyp-return-noun-flag* 'index-should-be-an-integer-in-polys))))
2683 (defun dispatchpoltrans (r x i1 i2 flg)
2684 (sendexec r
2685 (cond ((eq flg 'l)(ltw x i1 i2))
2686 ((eq flg 'he)(hetd x i1))
2687 ((eq flg 'c)(ctpjac x i1 i2))
2688 ((eq flg 't)(ttpjac x i1))
2689 ((eq flg 'u)(utpjac x i1)))))
2691 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2692 ;; (-1)^n*n!*laguerre(n,a,x) = U(-n,a+1,x)
2694 ;; W[k,u](z) = exp(-z/2)*z^(u+1/2)*U(1/2+u-k,1+2*u,z)
2696 ;; So
2698 ;; laguerre(n,a,x) = (-1)^n*U(-n,a+1,x)/n!
2700 ;; U(-n,a+1,x) = exp(z/2)*z^(-a/2-1/2)*W[1/2+a/2+n,a/2](z)
2702 ;; Finally,
2704 ;; laguerre(n,a,x) = (-1)^n/n!*exp(z/2)*z^(-a/2-1/2)*M[1/2+a/2+n,a/2](z)
2706 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2708 (defun ltw (x n a)
2709 (let ((diva2 (div a 2)))
2710 (mul (take '(%gamma) (add n a 1))
2711 (inv (take '(%gamma) (add a 1)))
2712 (inv (take '(%gamma) (add n 1)))
2713 (power x (sub '((rat simp) -1 2) diva2))
2714 (power '$%e (div x 2))
2715 (list '(mqapply simp)
2716 (list '($%m simp array)
2717 (add '((rat simp) 1 2) diva2 n) diva2) x))))
2719 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2720 ;; Hermite He function as a parabolic cylinder function
2722 ;; Tables of Integral Transforms
2724 ;; p. 386
2726 ;; D[n](z) = (-1)^n*exp(z^2/4)*diff(exp(-z^2/2),z,n);
2728 ;; p. 369
2730 ;; He[n](x) = (-1)^n*exp(x^2/2)*diff(exp(-x^2/2),x,n)
2731 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2733 (defun hetd (x n)
2734 (mul (power '$%e (mul x x '((rat simp) 1 4)))
2735 ;; At this time the Parabolic Cylinder D function is not implemented
2736 ;; as a simplifying function. We call nevertheless the simplifier.
2737 (take '($parabolic_cylinder_d) n x)))
2739 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2741 ;; Transform Gegenbauer function to Jacobi P function
2742 ;; ultraspherical(n,v,x) = gamma(2*v+n)*gamma(v+1/2)/gamma(2*v)/gamma(v+n+1/2)
2743 ;; *jacobi_p(n,v-1/2,v-1/2,x)
2744 (defun ctpjac (x n v)
2745 (let ((inv2 '((rat simp) 1 2)))
2746 (mul (take '(%gamma) (add v v n))
2747 (inv (take '(%gamma) (add v v)))
2748 (take '(%gamma) (add inv2 v))
2749 (inv (take '(%gamma) (add v inv2 n)))
2750 (pjac x n (sub v inv2) (sub v inv2)))))
2752 ;; Transform Chebyshev T function to Jacobi P function
2753 ;; chebyshev_t(n,x) = gamma(n+1)*sqrt(%pi)/gamma(n+1/2)*jacobi_p(n,-1/2,-1/2,x)
2754 (defun ttpjac (x n)
2755 (let ((inv2 '((rat simp) 1 2)))
2756 (mul (take '(%gamma) n 1)
2757 (power '$%pi inv2) ; gamma(1/2)
2758 (inv (take '(%gamma) (add inv2 n)))
2759 (pjac x n (mul -1 inv2) (mul -1 inv2)))))
2761 ;; Transform Chebyshev U function to Jacobi P function
2762 ;; chebyshev_u(n,x) = gamma(n+2)*sqrt(%pi)/2/gamma(3/2+n)*jacobi_p(n,1/2,1/2,x)
2763 (defun utpjac (x n)
2764 (let ((inv2 '((rat simp) 1 2)))
2765 (mul (take '(%gamma) (add n 2))
2766 inv2
2767 (power '$%pi inv2) ; gamma(1/2)
2768 (inv (take '(%gamma) (add inv2 n 1)))
2769 (pjac x n inv2 inv2))))
2771 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2773 (defun pjactest (rest arg index1 index2 index3)
2774 (cond ((maxima-integerp index1)
2775 (lt-ltp 'onepjac
2776 rest
2778 (list index1 index2 index3)))
2780 (setq *hyp-return-noun-flag* 'ind-should-be-an-integer-in-polys))))
2782 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2784 ;;; Laplace transform of a single Bessel Y function.
2786 ;;; REST is the multiplier, ARG1 is the arg, and INDEX1 is the order of
2787 ;;; the Bessel Y function.
2788 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2790 (defun lt1yref (rest arg1 index1)
2791 ;; If the index is an integer, use LT1Y. Otherwise, convert Bessel
2792 ;; Y to Bessel J and compute the transform of that. We do this
2793 ;; because converting Y to J for an integer index doesn't work so
2794 ;; well without taking limits.
2795 (cond ((maxima-integerp index1)
2796 ;; Do not call lt1y but lty directly.
2797 ;; lt1y calls lt-ltp with the flag 'oney. lt-ltp checks this flag
2798 ;; and calls lty. So we can do it at this place and the algorithm is
2799 ;; more simple.
2800 (lty rest arg1 index1))
2801 (t (fractest2 rest arg1 index1 nil 'ytj))))
2803 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2805 ;;; TRANSFORMATIONS TO CHANGE THE REPRESENTATION OF SPECIAL FUNCTIONS
2807 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2809 ;; erfc in terms of D, parabolic cylinder function
2811 ;; Tables of Integral Transforms
2813 ;; p 387:
2814 ;; erfc(x) = (%pi*x)^(-1/2)*exp(-x^2/2)*W[-1/4,1/4](x^2)
2816 ;; p 386:
2817 ;; D[v](z) = 2^(v/2+1/2)*z^(-1/2)*W[v/2+1/4,1/4](z^2/2)
2819 ;; So
2821 ;; erfc(x) = %pi^(-1/2)*2^(1/4)*exp(-x^2/2)*D[-1](x*sqrt(2))
2823 (defun erfctd (x)
2824 (let ((inv2 '((rat simp) 1 2)))
2825 (mul (power 2 inv2) ; Should this be 2^(1/4)?
2826 (inv (power '$%pi inv2))
2827 (power '$%e (mul -1 inv2 x x))
2828 ;; At this time the Parabolic Cylinder D function is not implemented
2829 ;; as a simplifying function. We call nevertheless the simplifier
2830 ;; to simplify the arguments. When we implement the function
2831 ;; The symbol has to be changed to the noun form.
2832 (take '($parabolic_cylinder_d) -1 (mul (power 2 inv2) x)))))
2834 ;; Lommel S function in terms of Bessel J and Bessel Y.
2835 ;; Luke gives
2837 ;; S[u,v](z) = s[u,v](z) + {2^(u-1)*gamma((u-v+1)/2)*gamma((u+v+1)/2)}
2838 ;; * {sin[(u-v)*%pi/2]*bessel_j(v,z)
2839 ;; - cos[(u-v)*%pi/2]*bessel_y(v,z)
2841 (defun slommeltjandy (m n z)
2842 (let ((arg (mul '((rat simp) 1 2) '$%pi (sub m n))))
2843 (add (littleslommel m n z)
2844 (mul (power 2 (sub m 1))
2845 (take '(%gamma) (div (sub (add m 1) n) 2))
2846 (take '(%gamma) (div (add m n 1) 2))
2847 (sub (mul (take '(%sin) arg)
2848 (take '(%bessel_j) n z))
2849 (mul (take '(%cos) arg)
2850 (take '(%bessel_y) n z)))))))
2852 ;; Whittaker W function in terms of Whittaker M function
2854 ;; A&S 13.1.34
2856 ;; W[k,u](z) = gamma(-2*u)/gamma(1/2-u-k)*M[k,u](z)
2857 ;; + gamma(2*u)/gamma(1/2+u-k)*M[k,-u](z)
2859 (defun wtm (a i1 i2)
2860 (add (mul (take '(%gamma) (mul -2 i2))
2861 (mwhit a i1 i2)
2862 (inv (take '(%gamma) (sub (sub '((rat simp) 1 2) i2) i1))))
2863 (mul (take '(%gamma) (add i2 i2))
2864 (mwhit a i1 (mul -1 i2))
2865 (inv (take '(%gamma) (sub (add '((rat simp) 1 2) i2) i1))))))
2867 ;; Incomplete gamma function in terms of Whittaker W function
2869 ;; Tables of Integral Transforms, p. 387
2871 ;; gamma_incomplete(a,x) = x^((a-1)/2)*exp(-x/2)*W[(a-1)/2,a/2](x)
2873 (defun gammaincompletetw (a x)
2874 (mul (power x (div (sub a 1) 2))
2875 (power '$%e (div x -2))
2876 (wwhit x (div (sub a 1) 2)(div a 2))))
2878 ;;; Incomplete Gamma function in terms of lower incomplete Gamma function
2880 ;;; Only for a=0 we use the general representation as a Whittaker W function:
2882 ;;; gamma_incomplete(a,x) = x^((a-1)/2)*exp(-x/2)*W[(a-1)/2,a/2](x)
2884 ;;; In all other cases we transform to a lower incomplete Gamma function:
2886 ;;; gamma_incomplete(a,x) = gamma(a)- gamma_incomplete_lower(a,x)
2888 ;;; The lower incomplete Gamma function will be further transformed to a Hypergeometric 1F1
2889 ;;; representation. With this change we get more simple and correct results for
2890 ;;; the Laplace transform of the Incomplete Gamma function.
2892 (defun gamma_incomplete-to-gamma-incomplete-lower (a x)
2893 (if (or (eq ($sign a) '$zero)
2894 (and (integerp a) (< a 0)))
2895 ;; The representation as a Whittaker W function for a=0 or a negative
2896 ;; integer (The gamma function is not defined for this case.)
2897 (mul (power x (div (sub a 1) 2))
2898 (power '$%e (div x -2))
2899 (wwhit x (div (sub a 1) 2) (div a 2)))
2900 ;; In all other cases the representation as a lower incomplete Gamma function
2901 (sub (take '(%gamma) a)
2902 (list '(%gamma_incomplete_lower simp) a x))))
2904 ;; Bessel Y in terms of Bessel J
2906 ;; A&S 9.1.2:
2908 ;; bessel_y(v,z) = bessel_j(v,z)*cot(v*%pi)-bessel_j(-v,z)/sin(v*%pi)
2910 (defun ytj (i a)
2911 (sub (mul (take '(%bessel_j) i a)
2912 (take '(%cot) (mul i '$%pi)))
2913 (mul (take '(%bessel_j) (mul -1 i) a)
2914 (inv (take '(%sin) (mul i '$%pi))))))
2916 ;; Parabolic cylinder function in terms of Whittaker W function.
2918 ;; See Table of Integral Transforms, p.386:
2920 ;; D[v](z) = 2^(v/2+1/4)*z^(-1/2)*W[v/2+1/4,1/4](z^2/2)
2922 (defun dtw (i a)
2923 (mul (power 2 (add (div i 2) '((rat simp) 1 4)))
2924 (power a '((rat simp) -1 2))
2925 (wwhit (mul a a '((rat simp) 1 2))
2926 (add (div i 2) '((rat simp) 1 4))
2927 '((rat simp) 1 4))))
2929 ;; Bateman's function in terms of Whittaker W function
2931 ;; See Table of Integral Transforms, p.386:
2933 ;; k[2*v](z) = 1/gamma(v+1)*W[v,1/2](2*z)
2935 (defun kbatemantw (v a)
2936 (div (wwhit (add a a) (div v 2) '((rat simp) 1 2))
2937 (take '(%gamma) (add (div v 2) 1))))
2939 ;; Bessel K in terms of Bessel I
2941 ;; A&S 9.6.2
2943 ;; bessel_k(v,z) = %pi/2*(bessel_i(-v,z)-bessel_i(v,z))/sin(v*%pi)
2945 (defun kti (i a)
2946 (mul '$%pi
2947 '((rat simp) 1 2)
2948 (inv (take '(%sin) (mul i '$%pi)))
2949 (sub (take '(%bessel_i) (mul -1 i) a)
2950 (take '(%bessel_i) i a))))
2952 ;; Express Hankel function in terms of Bessel J or Y function.
2954 ;; A&S 9.1.3
2956 ;; H[v,1](z) = %i*csc(v*%pi)*(exp(-v*%pi*%i)*bessel_j(v,z) - bessel_j(-v,z))
2958 ;; A&S 9.1.4:
2959 ;; H[v,2](z) = %i*csc(v*%pi)*(bessel_j(-v,z) - exp(-v*%pi*%i)*bessel_j(v,z))
2961 ;; Both formula are not valid for v an integer.
2962 ;; For this case use the definitions of the Hankel functions:
2963 ;; H[v,1](z) = bessel_j(v,z) + %i* bessel_y(v,z)
2964 ;; H[v,2](z) = bessel_j(v,z) - %i* bessel_y(v,z)
2966 ;; All this can be implemented more simple.
2967 ;; We do not need the transformation to bessel_j for rational numbers,
2968 ;; because the correct transformation for bessel_y is already implemented.
2969 ;; It is enough to use the definitions for the Hankel functions.
2971 (defun htjory (v sort z)
2972 ;; V is the order, SORT is the kind of Hankel function (1 or 2), Z
2973 ;; is the arg.
2974 (cond ((and (consp v)
2975 (consp (car v))
2976 (equal (caar v) 'rat))
2977 ;; If the order is a rational number of some sort,
2979 ;; (bessel_j(-v,z) - bessel_j(v,z)*exp(-v*%pi*%i))/(%i*sin(v*%pi*%i))
2980 (div (numjory v sort z 'j)
2981 (mul '$%i (take '(%sin) (mul v '$%pi)))))
2982 ((equal sort 1)
2983 ;; Transform hankel_1(v,z) to bessel_j(v,z)+%i*bessel_y(v,z)
2984 (add (take '(%bessel_j) v z)
2985 (mul '$%i (take '(%bessel_y) v z))))
2986 ((equal sort 2)
2987 ;; Transform hankel_2(v,z) to bessel_j(v,z)-%i*bessel_y(v,z)
2988 (sub (take '(%bessel_j) v z)
2989 (mul '$%i (take '(%bessel_y) v z))))
2991 ;; We should never reach this point of code.
2992 ;; Problem: The user input for the symbol %h[v,sort](t) is not checked.
2993 ;; Therefore the user can generate this error as long as we do not cut
2994 ;; out the support for the Laplace transform of the symbol %h.
2995 (merror "htjory: Called with wrong sort of Hankel functions."))))
2997 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2999 ;;; Three helper functions only used by htjory
3001 ;; Bessel J or Y, depending on if FLG is 'J or not.
3002 (defun desjy (v z flg)
3003 (cond ((eq flg 'j)
3004 (take '(%bessel_j) v z))
3006 (take '(%bessel_y) v z))))
3008 (defun numjory (v sort z flg)
3009 (cond ((equal sort 1)
3010 ;; bessel(-v, z) - exp(-v*%pi*%i)*bessel(v, z)
3012 ;; Where bessel is bessel_j if FLG is 'j. Otherwise, bessel
3013 ;; is bessel_y.
3015 ;; bessel_y(-v, z) - exp(-v*%pi*%i)*bessel_y(v, z)
3016 (sub (desjy (mul -1 v) z flg)
3017 (mul (power '$%e (mul -1 v '$%pi '$%i))
3018 (desjy v z flg))))
3020 ;; exp(-v*%pi*%i)*bessel(v,z) - bessel(-v,z), where bessel is
3021 ;; bessel_j or bessel_y, depending on if FLG is 'j or not.
3022 (sub (mul (power '$%e (mul v '$%pi '$%i))
3023 (desmjy v z flg))
3024 (desmjy (mul -1 v) z flg)))))
3026 (defun desmjy (v z flg)
3027 (cond ((eq flg 'j)
3028 ;; bessel_j(v,z)
3029 (take '(%bessel_j) v z))
3031 ;; -bessel_y(v,z)
3032 (mul -1 (take '(%bessel_y) v z)))))
3034 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3036 ;;; TRANSFORM TO HYPERGEOMETRIC FUNCTION WITHOUT USING THE ROUTINE REF
3038 ;;; This functions are called in the routine lt-sf-log to get the
3039 ;;; representation in terms of a hypergeometric function.
3040 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3042 ;; The algorithm of the implemented Hermite function %he does not work for
3043 ;; the known Laplace transforms. For an even or odd integer order, we
3044 ;; can represent the Hermite function by the Hypergeometric function 1F1.
3045 ;; With this representations we get the expected Laplace transforms.
3046 (defun hermite-to-hypergeometric (order arg)
3047 (cond
3048 ((and (maxima-integerp order)
3049 (mevenp order))
3050 ;; Transform to 1F1 for order an even integer
3051 (mul (power 2 order)
3052 (power '$%pi (div 1 2))
3053 (inv (take '(%gamma) (div (sub 1 order) 2)))
3054 (list '(mqapply simp)
3055 (list '($%f array simp) 1 1)
3056 (list '(mlist) (div order -2))
3057 (list '(mlist) '((rat simp) 1 2))
3058 (mul arg arg))))
3060 ((and (maxima-integerp order)
3061 (moddp order))
3062 ;; Transform to 1F1 for order an odd integer
3063 (mul -2 arg
3064 (power 2 order)
3065 (power '$%pi '((rat simp) 1 2))
3066 (inv (take '(%gamma) (div order -2)))
3067 (list '(mqapply simp)
3068 (list '($%f simp array) 1 1)
3069 (list '(mlist simp) (div (sub 1 order) 2))
3070 (list '(mlist simp) '((rat simp) 3 2))
3071 (mul arg arg))))
3073 ;; The general case, transform to 2F0
3074 ;; For this case we have no Laplace transform.
3075 (mul (power (mul 2 arg) order)
3076 (list '(mqapply simp)
3077 (list '($%f array simp) 2 0)
3078 (list '(mlist simp) (div order 2) (div (sub 1 order) 2))
3079 (list '(mlist simp))
3080 (div -1 (mul arg arg)))))))
3082 ;;; Hypergeometric representation of the Exponential Integral Si
3083 ;;; Si(z) = z*1F2([1/2],[3/2,3/2],-z^2/4)
3084 (defun expintegral_si-to-hypergeometric (arg)
3085 (mul arg
3086 (list '(mqapply simp)
3087 (list '($%f array simp) 1 2)
3088 (list '(mlist simp) '((rat simp) 1 2))
3089 (list '(mlist simp) '((rat simp) 3 2) '((rat simp) 3 2))
3090 (div (mul -1 arg arg) 4))))
3092 ;;; Hypergeometric representation of the Exponential Integral Shi
3093 ;;; Shi(z) = z*1F2([1/2],[3/2,3/2],z^2/4)
3094 (defun expintegral_shi-to-hypergeometric (arg)
3095 (mul arg
3096 (list '(mqapply simp)
3097 (list '($%f simp array) 1 2)
3098 (list '(mlist simp) '((rat simp) 1 2))
3099 (list '(mlist simp) '((rat simp) 3 2) '((rat simp) 3 2))
3100 (div (mul arg arg) 4))))
3102 ;;; Hypergeometric representation of the Exponential Integral Ci
3103 ;;; Ci(z) = -z^2/4*2F3([1,1],[2,2,3/2],-z^2/4)+log(z)+%gamma
3104 (defun expintegral_ci-to-hypergeometric (arg)
3105 (add (mul (div (mul -1 arg arg) 4)
3106 (list '(mqapply simp)
3107 (list '($%f simp array) 2 3)
3108 (list '(mlist simp) 1 1)
3109 (list '(mlist simp) 2 2 '((rat simp) 3 2))
3110 (div (mul -1 arg arg) 4)))
3111 (take '(%log) arg)
3112 '$%gamma))
3114 ;;; Hypergeometric representation of the Exponential Integral Chi
3115 ;;; Chi(z) = z^2/4*2F3([1,1],[2,2,3/2],z^2/4)+log(z)+%gamma
3116 (defun expintegral_chi-to-hypergeometric (arg)
3117 (add (mul (div (mul arg arg) 4)
3118 (list '(mqapply simp)
3119 (list '($%f array simp) 2 3)
3120 (list '(mlist simp) 1 1)
3121 (list '(mlist simp) 2 2 '((rat simp) 3 2))
3122 (div (mul arg arg) 4)))
3123 (take '(%log) arg)
3124 '$%gamma))
3126 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3128 ;;; EXPERTS ON LAPLACE TRANSFORMS
3129 ;;;
3130 ;;; LT<foo> functions are various experts on Laplace transforms of the
3131 ;;; function <foo>. The expression being transformed is
3132 ;;; r*<foo>(args). The first arg of each expert is r, The remaining
3133 ;;; args are the arg(s) and/or parameters.
3134 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3136 ;; Laplace transform of one Bessel J
3137 (defun lt1j (rest arg index)
3138 (lt-ltp 'onej rest arg index))
3140 ;; Laplace transform of two Bessel J functions.
3141 ;; The argument of each must be the same, but the orders may be different.
3142 (defun lt2j (rest arg1 arg2 index1 index2)
3143 (cond ((not (equal arg1 arg2))
3144 (setq *hyp-return-noun-flag* 'product-of-bessel-with-different-args))
3146 ;; Call lt-ltp two transform and integrate two Bessel J functions.
3147 (lt-ltp 'twoj rest arg1 (list 'list index1 index2)))))
3149 ;; Laplace transform of a square of a Bessel J function
3150 (defun lt1j^2 (rest arg index)
3151 (cond ((alike1 index '((rat) -1 2))
3152 ;; Special case: Laplace transform of bessel_j(v,arg)^2, v = -1/2.
3153 ;; For this case the algorithm for the product of two Bessel functions
3154 ;; does not work. Call the integrator with the hypergeometric
3155 ;; representation: 2/%pi/arg*1/2*(1+0F1([], [1/2], -arg*arg)).
3156 (sendexec (mul (div 2 '$%pi)
3157 (inv arg)
3158 rest)
3159 (add '((rat simp) 1 2)
3160 (mul '((rat simp) 1 2)
3161 (list '(mqapply simp)
3162 (list '($%f simp array) 1 0)
3163 (list '(mlist simp) )
3164 (list '(mlist simp) '((rat simp) 1 2))
3165 (mul -1 (mul arg arg)))))))
3167 (lt-ltp 'twoj rest arg (list 'list index index)))))
3169 ;; Laplace transform of Incomplete Gamma function
3170 (defun lt1gamma-incomplete-lower (rest arg1 arg2)
3171 (lt-ltp 'gamma-incomplete-lower rest arg2 arg1))
3173 ;; Laplace transform of Whittaker M function
3174 (defun lt1m (r a i1 i2)
3175 (lt-ltp 'onem r a (list i1 i2)))
3177 ;; Laplace transform of Jacobi function
3178 (defun lt1p (r a i1 i2)
3179 (lt-ltp 'hyp-onep r a (list i1 i2)))
3181 ;; Laplace transform of Associated Legendre function of the second kind
3182 (defun lt1q (r a i1 i2)
3183 (lt-ltp 'oneq r a (list i1 i2)))
3185 ;; Laplace transform of Erf function
3186 (defun lt1erf (rest arg)
3187 (lt-ltp 'onerf rest arg nil))
3189 ;; Laplace transform of Log function
3190 (defun lt1log (rest arg)
3191 (lt-ltp 'onelog rest arg nil))
3193 ;; Laplace transform of Complete elliptic integral of the first kind
3194 (defun lt1kelliptic (rest arg)
3195 (lt-ltp 'onekelliptic rest arg nil))
3197 ;; Laplace transform of Complete elliptic integral of the second kind
3198 (defun lt1e (rest arg)
3199 (lt-ltp 'onee rest arg nil))
3201 ;; Laplace transform of Struve H function
3202 (defun lt1hstruve (rest arg1 index1)
3203 (lt-ltp 'hs rest arg1 index1))
3205 ;; Laplace transform of Struve L function
3206 (defun lt1lstruve (rest arg1 index1)
3207 (lt-ltp 'hl rest arg1 index1))
3209 ;; Laplace transform of Lommel s function
3210 (defun lt1s (rest arg1 index1 index2)
3211 (lt-ltp 's rest arg1 (list index1 index2)))
3213 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3215 ;;; TRANSFORM TO HYPERGEOMETRIC FUNCTION AND DO THE INTEGRATION
3217 ;;; FLG = special function we're transforming
3218 ;;; REST = other stuff
3219 ;;; ARG = arg of special function
3220 ;;; INDEX = index of special function.
3222 ;;; So we're transforming REST*FLG(INDEX, ARG).
3223 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3225 (defun lt-ltp (flg rest arg index)
3226 (let (l l1)
3227 (when (and (listp index)
3228 (eq (car index) 'list))
3229 (setq index (list (cadr index) (caddr index))))
3230 (cond ((setq l
3231 (m2-d*x^m*%e^a*x
3232 ($factor (mul rest
3233 (car (setq l1 (ref flg index arg)))))
3234 *var* *par*))
3235 ;; Convert the special function to a hypgergeometric
3236 ;; function. L1 is the special function converted to the
3237 ;; hypergeometric function. d*x^m*%e^a*x looks for that
3238 ;; factor in the expanded form.
3239 (%$etest l l1))
3241 ;; We currently don't know how to handle this yet.
3242 ;; We add the return of a noun form.
3243 (setq *hyp-return-noun-flag* 'other-ca-later)))))
3245 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3246 ;; Dispatch function to convert the given function to a hypergeometric
3247 ;; function.
3249 ;; The first arg is a symbol naming the function; the last is the
3250 ;; argument to the function. The second arg is the index (or list of
3251 ;; indices) to the function. Not used if the function doesn't have
3252 ;; any indices
3254 ;; The result is a list of 2 elements: The first element is a
3255 ;; multiplier; the second, the hypergeometric function itself.
3256 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3258 (defun ref (flg index arg)
3259 (case flg
3260 (onej (j1tf index arg))
3261 (twoj (j2tf (car index) (cadr index) arg))
3262 (hs (hstf index arg))
3263 (hl (lstf index arg))
3264 (s (stf (car index) (cadr index) arg))
3265 (onerf (erftf arg))
3266 (onelog (logtf arg))
3267 (onekelliptic (kelliptictf arg)) ; elliptic_kc
3268 (onee (etf arg)) ; elliptic_ec
3269 (onem (mtf (car index) (cadr index) arg))
3270 (hyp-onep (ptf (car index) (cadr index) arg))
3271 (oneq (qtf (car index) (cadr index) arg))
3272 (gamma-incomplete-lower (gamma-incomplete-lower-tf index arg))
3273 (onepjac (pjactf (car index) (cadr index) (caddr index) arg))
3274 (asin (asintf arg))
3275 (atan (atantf arg))
3277 ;; Transform %f to internal representation FPQ
3278 (list 1 (ref-fpq (rest (car index)) (rest (cadr index)) arg)))))
3280 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3282 ;;; TRANSFORM FUNCTION IN TERMS OF HYPERGEOMETRIC FUNCTION
3284 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3286 ;; Create a hypergeometric form that we recognize. The function is
3287 ;; %f[n,m](p; q; arg). We represent this as a list of the form
3288 ;; (fpq (<length p> <length q>) <p> <q> <arg>)
3290 (defun ref-fpq (p q arg)
3291 (list 'fpq (list (length p) (length q))
3292 p q arg))
3294 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3296 ;; Whittaker M function in terms of hypergeometric function
3298 ;; A&S 13.1.32:
3300 ;; M[k,u](z) = exp(-z/2)*z^(1/2+u)*M(1/2+u-k,1+2*u,z)
3302 (defun mtf (i1 i2 arg)
3303 (list (mul (power arg (add i2 '((rat simp) 1 2)))
3304 (power '$%e (div arg -2)))
3305 (ref-fpq (list (add '((rat simp) 1 2) i2 (mul -1 i1)))
3306 (list (add i2 i2 1))
3307 arg)))
3309 ;; Jacobi P in terms of hypergeometric function
3311 ;; A&S 15.4.6:
3313 ;; F(-n,a+1+b+n; a+1; x) = n!/poch(a+1,n)*jacobi_p(n,a,b,1-2*x)
3315 ;; jacobi_p(n,a,b,x) = poch(a+1,n)/n!*F(-n,a+1+b+n; a+1; (1-x)/2)
3316 ;; = gamma(a+n+1)/gamma(a+1)/n!*F(-n,a+1+b+n; a+1; (1-x)/2)
3318 ;; We have a problem:
3319 ;; We transform the argument x -> (1-x)/2. But an argument with a constant
3320 ;; part is not integrable with the implemented algorithm for the hypergeometric
3321 ;; function. It might be possible to get a result for an argument y=1-2*x
3322 ;; with x=t^-2. But for this case the routine lt-ltp fails. The routine
3323 ;; recognize a constant term in the argument, but does not take into account
3324 ;; that the constant term might vanish, when we transform to a hypergeometric
3325 ;; function.
3326 ;; Because of this the Laplace transform for the following functions does not
3327 ;; work too: Legendre P, Chebyshev T, Chebyshev U, and Gegenbauer.
3329 (defun pjactf (n a b x)
3330 (list (mul (take '(%gamma) (add n a 1))
3331 (inv (take '(%gamma) (add a 1)))
3332 (inv (take '(%gamma) (add n 1))))
3333 (ref-fpq (list (mul -1 n) (add n a b 1))
3334 (list (add a 1))
3335 (sub '((rat simp) 1 2) (div x 2)))))
3337 ;; ArcSin in terms of hypergeometric function
3339 ;; A&S 15.1.6:
3341 ;; F(1/2,1/2; 3/2; z^2) = asin(z)/z
3343 ;; asin(z) = z*F(1/2,1/2; 3/2; z^2)
3345 (defun asintf (arg)
3346 (let ((inv2 '((rat simp) 1 2)))
3347 (list arg
3348 (ref-fpq (list inv2 inv2)
3349 (list '((rat simp) 3 2))
3350 (mul arg arg)))))
3352 ;; ArcTan in terms of hypergeometric function
3354 ;; A&S 15.1.5
3356 ;; F(1/2,1; 3/2; -z^2) = atan(z)/z
3358 ;; atan(z) = z*F(1/2,1; 3/2; -z^2)
3360 (defun atantf (arg)
3361 (list arg
3362 (ref-fpq (list '((rat simp) 1 2) 1)
3363 (list '((rat simp) 3 2))
3364 (mul -1 arg arg))))
3366 ;; Associated Legendre function P in terms of hypergeometric function
3368 ;; A&S 8.1.2
3370 ;; assoc_legendre_p(v,u,z) = ((z+1)/(z-2))^(u/2)/gamma(1-u)*F(-v,v+1;1-u,(1-z)/2)
3372 ;; FIXME: What about the branch cut? 8.1.2 is for z not on the real
3373 ;; line with -1 < z < 1.
3375 (defun ptf (n m z)
3376 (list (mul (inv (take '(%gamma) (sub 1 m)))
3377 (power (div (add z 1)
3378 (sub z 1))
3379 (div m 2)))
3380 (ref-fpq (list (mul -1 n) (add n 1))
3381 (list (sub 1 m))
3382 (sub '((rat simp) 1 2) (div z 2)))))
3384 ;; Associated Legendre function Q in terms of hypergeometric function
3386 ;; A&S 8.1.3:
3388 ;; assoc_legendre_q(v,u,z)
3389 ;; = exp(%i*u*%pi)*2^(-v-1)*sqrt(%pi) *
3390 ;; gamma(v+u+1)/gamma(v+3/2)*z^(-v-u-1)*(z^2-1)^(u/2) *
3391 ;; F(1+v/2+u/2, 1/2+v/2+u/2; v+3/2; 1/z^2)
3393 ;; FIXME: What about the branch cut?
3395 (defun qtf (n m z)
3396 (list (mul (power '$%e (mul m '$%pi '$%i))
3397 (power '$%pi '((rat simp) 1 2))
3398 (take '(%gamma) (add m n 1))
3399 (power 2 (sub -1 n))
3400 (inv (take '(%gamma) (add n '((rat simp) 3 2))))
3401 (power z (mul -1 (add m n 1)))
3402 (power (sub (mul z z) 1) (div m 2)))
3403 (ref-fpq (list (div (add m n 1) 2) (div (add m n 2) 2))
3404 (list (add n '((rat simp) 3 2)))
3405 (power z -2))))
3407 ;; Incomplete lower Gamma in terms of hypergeometric function
3409 ;; A&S 13.6.10:
3411 ;; M(a,a+1,-x) = a*x^(-a)*gamma_incomplete_lower(a,x)
3413 ;; gamma_incomplete_lower(a,x) = x^a/a*M(a,a+1,-x)
3415 (defun gamma-incomplete-lower-tf (a x)
3416 (list (mul (inv a) (power x a))
3417 (ref-fpq (list a)
3418 (list (add a 1))
3419 (mul -1 x))))
3421 ;; Complete elliptic K in terms of hypergeometric function
3423 ;; A&S 17.3.9
3425 ;; K(k) = %pi/2*2F1(1/2,1/2; 1; k^2)
3427 (defun kelliptictf (k)
3428 (let ((inv2 '((rat simp) 1 2)))
3429 (list (mul inv2 '$%pi)
3430 (ref-fpq (list inv2 inv2)
3431 (list 1)
3432 (mul k k)))))
3434 ;; Complete elliptic E in terms of hypergeometric function
3436 ;; A&S 17.3.10
3438 ;; E(k) = %pi/2*2F1(-1/2,1/2;1;k^2)
3440 (defun etf (k)
3441 (let ((inv2 '((rat simp) 1 2)))
3442 (list (mul inv2 '$%pi)
3443 (ref-fpq (list (mul -1 inv2) inv2)
3444 (list 1)
3445 (mul k k)))))
3447 ;; erf in terms of hypgeometric function.
3449 ;; A&S 7.1.21 gives
3451 ;; erf(z) = 2*z/sqrt(%pi)*M(1/2,3/2,-z^2)
3452 ;; = 2*z/sqrt(%pi)*exp(-z^2)*M(1,3/2,z^2)
3454 (defun erftf (arg)
3455 (list (mul 2 arg (power '$%pi '((rat simp) -1 2)))
3456 (ref-fpq (list '((rat simp) 1 2))
3457 (list '((rat simp) 3 2))
3458 (mul -1 arg arg))))
3460 ;; log in terms of hypergeometric function
3462 ;; We know from A&S 15.1.3 that
3464 ;; F(1,1;2;z) = -log(1-z)/z.
3466 ;; So log(z) = (z-1)*F(1,1;2;1-z)
3468 (defun logtf (arg)
3469 (list (sub arg 1)
3470 (ref-fpq (list 1 1)
3471 (list 2)
3472 (sub 1 arg))))
3474 ;; Bessel J function expressed as a hypergeometric function.
3476 ;; A&S 9.1.10:
3477 ;; inf
3478 ;; bessel_j(v,z) = (z/2)^v*sum (-z^2/4)^k/k!/gamma(v+k+1)
3479 ;; k=0
3481 ;; = (z/2)^v/gamma(v+1)*sum 1/poch(v+1,k)*(-z^2/4)^k/k!
3483 ;; = (z/2)^v/gamma(v+1) * 0F1(; v+1; -z^2/4)
3485 (defun j1tf (v z)
3486 (list (mul (inv (power 2 v))
3487 (power z v)
3488 (inv (take '(%gamma) (add v 1))))
3489 (ref-fpq nil
3490 (list (add v 1))
3491 (mul '((rat simp) -1 4) (power z 2)))))
3493 ;; Product of 2 Bessel J functions in terms of hypergeometric function
3495 ;; See Y. L. Luke, formula 39, page 216:
3497 ;; bessel_j(u,z)*bessel_j(v,z)
3498 ;; = (z/2)^(u+v)/gamma(u+1)/gamma(v+1) *
3499 ;; 2F3((u+v+1)/2, (u+v+2)/2; u+1, v+1, u+v+1; -z^2)
3501 (defun j2tf (n m arg)
3502 (list (mul (inv (take '(%gamma) (add n 1)))
3503 (inv (take '(%gamma) (add m 1)))
3504 (inv (power 2 (add n m)))
3505 (power arg (add n m)))
3506 (ref-fpq (list (add '((rat simp) 1 2) (div n 2) (div m 2))
3507 (add 1 (div n 2) (div m 2)))
3508 (list (add 1 n) (add 1 m) (add 1 n m))
3509 (mul -1 (power arg 2)))))
3511 ;; Struve H function in terms of hypergeometric function.
3513 ;; A&S 12.1.2 gives the following series for the Struve H function:
3515 ;; inf
3516 ;; H[v](z) = (z/2)^(v+1)*sum (-1)^k*(z/2)^(2*k)/gamma(k+3/2)/gamma(k+v+3/2)
3517 ;; k=0
3519 ;; We can write this in the form
3521 ;; H[v](z) = 2/sqrt(%pi)*(z/2)^(v+1)/gamma(v+3/2)
3523 ;; inf
3524 ;; * sum n!/poch(3/2,n)/poch(v+3/2,n)*(-z^2/4)^n/n!
3525 ;; n=0
3527 ;; = 2/sqrt(%pi)*(z/2)^(v+1)/gamma(v+3/2) * 1F2(1;3/2,v+3/2;(-z^2/4))
3529 ;; See also A&S 12.1.21.
3531 (defun hstf (v z)
3532 (let ((d32 (div 3 2)))
3533 (list (mul (power (div z 2)(add v 1))
3534 (inv (take '(%gamma) d32))
3535 (inv (take '(%gamma) (add v d32))))
3536 (ref-fpq (list 1)
3537 (list d32 (add v d32))
3538 (mul '((rat simp) -1 4) z z)))))
3540 ;; Struve L function in terms of hypergeometric function
3542 ;; A&S 12.2.1:
3544 ;; L[v](z) = -%i*exp(-v*%i*%pi/2)*H[v](%i*z)
3546 ;; This function computes exactly this way. (But why is %i written as
3547 ;; exp(%i*%pi/2) instead of just %i)
3549 ;; A&S 12.2.1 gives the series expansion as
3551 ;; inf
3552 ;; L[v](z) = (z/2)^(v+1)*sum (z/2)^(2*k)/gamma(k+3/2)/gamma(k+v+3/2)
3553 ;; k=0
3555 ;; It's quite easy to derive
3557 ;; L[v](z) = 2/sqrt(%pi)*(z/2)^(v+1)/gamma(v+3/2) * 1F2(1;3/2,v+3/2;(z^2/4))
3559 (defun lstf (v z)
3560 (let ((d32 (div 3 2)))
3561 (list (mul (power (div z 2) (add v 1))
3562 (inv (take '(%gamma) d32))
3563 (inv (take '(%gamma) (add v d32))))
3564 (ref-fpq (list 1)
3565 (list d32 (add v d32))
3566 (mul '((rat simp) 1 4) z z)))))
3568 ;; Lommel s function in terms of hypergeometric function
3570 ;; See Y. L. Luke, p 217, formula 1
3572 ;; s(u,v,z) = z^(u+1)/(u-v+1)/(u+v+1)*1F2(1; (u-v+3)/2, (u+v+3)/2; -z^2/4)
3574 (defun stf (m n z)
3575 (list (mul (power z (add m 1))
3576 (inv (sub (add m 1) n))
3577 (inv (add m n 1)))
3578 (ref-fpq (list 1)
3579 (list (div (sub (add m 3) n) 2)
3580 (div (add m n 3) 2))
3581 (mul '((rat simp) -1 4) z z))))
3583 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3585 ;;; Algorithm 3: Laplace transform of a hypergeometric function
3587 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3589 (defun %$etest (l l1)
3590 (prog(a q)
3591 (setq q (cdras 'q l))
3592 (cond ((equal q 1)(setq a 0)(go loop)))
3593 (setq a (cdras 'a l))
3594 loop
3595 (return (substl (sub *par* a)
3596 *par*
3597 (execf19 l (cadr l1))))))
3599 (defun execf19 (l1 l2)
3600 (prog(ans)
3601 (setq ans (execargmatch (car (cddddr l2))))
3602 (cond ((eq (car ans) 'dionimo)
3603 (return (dionarghyp l1 l2 (cadr ans)))))
3604 ;; We specialized the pattern for the argument. Now the test fails
3605 ;; correctly and we have to add the return of a noun form.
3606 (return
3607 (setq *hyp-return-noun-flag* 'next-for-other-args))))
3609 ;; Executive for recognizing the sort of argument to the
3610 ;; hypergeometric function. We look to see if the arg is of the form
3611 ;; a*x^m + c. Return a list of 'dionimo (what does that mean?) and
3612 ;; the match.
3614 (defun execargmatch (arg)
3615 (prog(l1)
3616 (cond ((setq l1 (m2-a*x^m+c ($factor arg) *var*))
3617 (return (list 'dionimo l1))))
3618 (cond ((setq l1 (m2-a*x^m+c ($expand arg) *var*))
3619 (return (list 'dionimo l1))))
3620 ;; The return value has to be a list.
3621 (return (list 'other-case-args-to-follow))))
3623 ;; We have hypergeometric function whose arg looks like a*x^m+c. L1
3624 ;; matches the d*x^m... part, L2 is the hypergeometric function and
3625 ;; arg is the match for a*x^m+c.
3627 (defun dionarghyp (l1 l2 arg)
3628 (prog(a m c)
3629 (setq a (cdras 'a arg)
3630 m (cdras 'm arg)
3631 c (cdras 'c arg))
3632 (cond
3633 ((and (integerp m) ; The power of the argument has to be
3634 (plusp m) ; a positive integer.
3635 (equal 0 c)) ; No const term to the argument.
3636 (return (f19cond a m l1 l2)))
3638 (return
3639 (setq *hyp-return-noun-flag* 'prop4-and-other-cases-to-follow))))))
3641 (defun f19cond (a m l1 l2)
3642 (prog(p q s d)
3643 (setq p (caadr l2)
3644 q (cadadr l2)
3645 s (cdras 'm l1)
3646 d (cdras 'd l1)
3647 l1 (caddr l2)
3648 l2 (cadddr l2))
3649 ;; At this point, we have the function d*x^s*%f[p,q](l1, l2, (a*t)^m).
3650 ;; Check to see if Formula 19, p 220 applies.
3651 (cond ((and (not (eq ($asksign (sub (add p m -1) q)) '$pos))
3652 (eq ($asksign (add s 1)) '$pos))
3653 (return (mul d
3654 (f19p220-simp (add s 1)
3658 m)))))
3659 (return (setq *hyp-return-noun-flag*
3660 'failed-on-f19cond-multiply-the-other-cases-with-d))))
3662 ;; Table of Laplace transforms, p 220, formula 19:
3664 ;; If m + k <= n + 1, and Re(s) > 0, the Laplace transform of
3666 ;; t^(s-1)*%f[m,n]([a1,...,am],[p1,...,pn],(c*t)^k)
3667 ;; is
3669 ;; gamma(s)/p^s*%f[m+k,n]([a1,...,am,s/k,(s+1)/k,...,(s+k-1)/k],[p1,...,pm],(k*c/p)^k)
3671 ;; with Re(p) > 0 if m + k <= n, Re(p+k*c*exp(2*%pi*%i*r/k)) > 0 for r
3672 ;; = 0, 1,...,k-1, if m + k = n + 1.
3674 ;; The args below are s, [a's], [p's], c^k, k.
3676 (defun f19p220-simp (s l1 l2 cf k)
3677 (mul (take '(%gamma) s)
3678 (inv (power *par* s))
3679 (hgfsimp-exec (append l1 (addarglist s k))
3681 (mul cf
3682 (power k k)
3683 (power (inv *par*) k)))))
3685 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3687 ;; Return a list of s/k, (s+1)/k, ..., (s+|k|-1)/k
3688 (defun addarglist (s k)
3689 (let ((abs-k (abs k))
3690 (res '()))
3691 (dotimes (n abs-k)
3692 (push (div (add s n) k) res))
3693 (nreverse res)))
3695 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3697 ;;; Pattern for the Laplace transform of the hypergeometric function
3699 ;; Match d*x^m*%e^(a*x). If we match, Q is the e^(a*x) part, A is a,
3700 ;; M is M, and D is d.
3701 (defun m2-d*x^m*%e^a*x (expr var2 par)
3702 (m2 expr
3703 `((mtimes)
3704 ((coefftt) (d free2 ,var2 ,par))
3705 ((mexpt) (x alike1 ,var2) (m free2 ,var2 ,par))
3706 ((mexpt)
3707 (q expor1p)
3708 ((mtimes)
3709 ((coefftt) (a free2 ,var2 ,par))
3710 (x alike1 ,var2))))))
3712 ;; Match f(x)+c
3713 (defun m2-f+c (expr var2)
3714 (m2 expr
3715 `((mplus)
3716 ((coeffpt) (f has ,var2))
3717 ((coeffpp) (c free ,var2)))))
3719 ;; Match a*x^m+c.
3720 ;; The pattern was too general. We match also a*t^2+b*t. But that's not correct.
3721 (defun m2-a*x^m+c (expr var2)
3722 (m2 expr
3723 `((mplus)
3724 ((coefft) ; more special (not coeffpt)
3725 (a free ,var2)
3726 ((mexpt) (x alike1 ,var2) (m free-not-zero-p ,var2)))
3727 ((coeffpp) (c free ,var2)))))
3729 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3731 ;;; Algorithm 4: SPECIAL HANDLING OF Bessel Y for an integer order
3733 ;;; This is called for one Bessel Y function, when the order is an integer.
3734 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3736 (defun lty (rest arg index)
3737 (prog(l)
3738 (cond ((setq l (m2-d*x^m*%e^a*x rest *var* *par*))
3739 (return (execfy l arg index))))
3740 (return (setq *hyp-return-noun-flag* 'fail-in-lty))))
3742 (defun execfy (l arg index)
3743 (prog(ans)
3744 (setq ans (execargmatch arg))
3745 (cond ((eq (car ans) 'dionimo)
3746 (return (dionarghyp-y l index (cadr ans)))))
3747 (return (setq *hyp-return-noun-flag* 'fail-in-execfy))))
3749 (defun dionarghyp-y (l index arg)
3750 (prog (a m c)
3751 (setq a (cdras 'a arg)
3752 m (cdras 'm arg)
3753 c (cdras 'c arg))
3754 (cond ((and (zerp c) (equal m 1))
3755 (let ((ans (f2p105v2cond a l index)))
3756 (unless (symbolp ans)
3757 (return ans)))))
3758 (cond ((and (zerp c) (equal m '((rat simp) 1 2)))
3759 (let ((ans (f50cond a l index)))
3760 (unless (symbolp ans)
3761 (return ans)))))
3762 (return (setq *hyp-return-noun-flag* 'fail-in-dionarghyp-y))))
3764 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3766 ;;; Algorithm 4.1: Laplace transform of t^n*bessel_y(v,a*t)
3767 ;;; v is an integer and n>=v
3769 ;;; Table of Integral Transforms
3771 ;;; Volume 2, p 105, formula 2 is a formula for the Y-transform of
3773 ;;; f(x) = x^(u-3/2)*exp(-a*x)
3775 ;;; where the Y-transform is defined by
3777 ;;; integrate(f(x)*bessel_y(v,x*y)*sqrt(x*y), x, 0, inf)
3779 ;;; which is
3781 ;;; -2/%pi*gamma(u+v)*sqrt(y)*(y^2+a^2)^(-u/2)
3782 ;;; *assoc_legendre_q(u-1,-v,a/sqrt(y^2+a^2))
3784 ;;; with a > 0, Re u > |Re v|.
3786 ;;; In particular, with a slight change of notation, we have
3788 ;;; integrate(x^(u-1)*exp(-p*x)*bessel_y(v,a*x)*sqrt(a), x, 0, inf)
3790 ;;; which is the Laplace transform of x^(u-1/2)*bessel_y(v,x).
3792 ;;; Thus, the Laplace transform is
3794 ;;; -2/%pi*gamma(u+v)*sqrt(a)*(a^2+p^2)^(-u/2)
3795 ;;; *assoc_legendre_q(u-1,-v,p/sqrt(a^2+p^2))
3796 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3798 (defun f2p105v2cond (a l index)
3799 (prog (d m)
3800 (setq d (cdras 'd l) ; contains constant part of integrand
3801 m (cdras 'm l))
3802 (setq m (add m 1.))
3803 (cond ((eq ($asksign ($realpart (sub m index))) '$pos)
3804 (return (mul d (f2p105v2cond-simp m index a)))))
3805 (return (setq *hyp-return-noun-flag* 'fail-in-f2p105v2cond))))
3807 (defun f2p105v2cond-simp (m v a)
3808 (mul -2
3809 (power '$%pi -1)
3810 (take '(%gamma) (add m v))
3811 (power (add (mul a a) (mul *par* *par*))
3812 (mul -1 '((rat simp) 1 2) m))
3813 ;; Call Associated Legendre Q function, which simplifies accordingly.
3814 ;; We have to do a Maxima function call, because $assoc_legendre_q is
3815 ;; not in Maxima core and has to be autoloaded.
3816 (mfuncall '$assoc_legendre_q
3817 (sub m 1)
3818 (mul -1 v)
3819 (mul *par*
3820 (power (add (mul a a) (mul *par* *par*))
3821 '((rat simp) -1 2))))))
3823 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3825 ;;; Algorithm 4.2: Laplace transform of t^n*bessel_y(v, a*sqrt(t))
3827 ;;; Table of Integral Transforms
3829 ;;; p. 188, formula 50:
3831 ;;; t^(u-1/2)*bessel_y(2*v,2*sqrt(a)*sqrt(t))
3832 ;;; -> a^(-1/2)*p^(-u)*exp(-a/2/p)
3833 ;;; * [tan((u-v)*%pi)*gamma(u+v+1/2)/gamma(2*v+1)*M[u,v](a/p)
3834 ;;; -sec((u-v)*%pi)*W[u,v](a/p)]
3835 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3837 (defun f50cond (a l v)
3838 (prog (d m)
3839 (setq d (cdras 'd l)
3840 m (add (cdras 'm l) '((rat simp) 1 2))
3841 v (div v 2))
3842 (cond
3843 ((and (eq ($asksign ($realpart (add m v '((rat simp) 1 2)))) '$pos)
3844 (eq ($asksign ($realpart (sub (add m '((rat simp) 1 2)) v))) '$pos)
3845 (not (maxima-integerp (mul (sub (add m m) (add v v 1))
3846 '((rat simp) 1 2)))))
3847 (setq a (mul a a '((rat simp) 1 4)))
3848 (return (f50p188-simp d m v a))))
3849 (return (setq *hyp-return-noun-flag* 'fail-in-f50cond))))
3851 (defun f50p188-simp (d u v a)
3852 (mul d
3853 (power a '((rat simp) -1 2))
3854 (power *par* (mul -1 u))
3855 (power '$%e (div a (mul -2 *par*)))
3856 (sub (mul (take '(%tan) (mul '$%pi (sub u v)))
3857 (take '(%gamma) (add u v '((rat simp) 1 2)))
3858 (inv (take '(%gamma) (add v v 1)))
3859 (mwhit (div a *par*) u v))
3860 (mul (take '(%sec) (mul '$%pi (sub u v)))
3861 (wwhit (div a *par*) u v)))))
3863 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;