927
931
;; Laplace transform of c*t^v*exp(-p*t+e*f). L contains the pattern
929
933
(defun lt-exp (l e f)
931
(setq c (cdras 'c l) v (cdras 'v l))
933
(setq e (inv (mul -8 e)) v (add v 1))
934
(return (f24p146test c v e))))
936
(setq e (mul* e e (inv 4)) v (add v 1))
937
(return (f35p147test c v e))))
939
(setq e (mul -4 e) v (add v 1))
940
(return (f29p146test v e))))
941
(return 'other-lt-exponential-to-follow)))
934
(let ((c (cdras 'c l))
937
(setq e (inv (mul -8 e)) v (add v 1))
940
(setq e (mul* e e (inv 4)) v (add v 1))
943
(setq e (mul -4 e) v (add v 1))
949
(t 'other-lt-exponential-to-follow))))
943
951
(defun t^2(exp)(m2 exp '((mexpt)(t varp) 2) nil))
1733
1774
(defun sendexec(r a)(distrexecinit ($expand (mul (init r) a))))
1737
(cond ((whittindtest i1 i2) 'formula-for-confl-needed)
1738
(t (distrexecinit ($expand (mul (init r)
1776
;; Test for Whittaker W function. Simplify this if possible, or
1777
;; convert to Whittaker M function.
1779
;; We have r * %w[i1,i2](a)
1780
(defun whittest (r a i1 i2)
1781
(cond ((f16p217test r a i1 i2))
1783
;; Convert to M function and try again.
1784
(distrexecinit ($expand (mul (init r)
1787
;; Formula 16, p. 217
1789
;; t^(v-1)*%w[k,u](a*t)
1790
;; -> gamma(u+v+1/2)*gamma(v-u+1/2)*a^(u+1/2)/
1791
;; (gamma(v-k+1)*(p+a/2)^(u+v+1/2)
1792
;; *2f1(u+v+1/2,u-k+1/2;v-k+1;(p-a/2)/(p+a/2))
1794
;; For Re(v +/- mu) > -1/2
1795
(defun f16p217test (r a i1 i2)
1796
;; We have r*%w[i1,i2](a)
1797
(let ((l (c*t^v r)))
1798
;; Make sure r is of the form c*t^v
1800
(let* ((v (add (cdras 'v l) 1))
1802
;; Check that v + i2 + 1/2 > 0 and v - i2 + 1/2 > 0.
1803
(when (and (eq (asksign (add (add v i2) 1//2)) '$positive)
1804
(eq (asksign (add (sub v i2) 1//2)) '$positive))
1805
;; Ok, we satisfy the conditions. Now extract the arg.
1808
((coeffpt) (f hasvar) (a freevar))
1809
((coeffpp) (c zerp)))
1812
(let ((a (cdras 'a l)))
1813
;; We're ready now to compute the transform.
1815
(power a (add i2 1//2))
1816
(gm (add (add v i2) 1//2))
1817
(gm (add (sub v i2) 1//2))
1818
(inv (mul* (gm (add (sub v i1) 1))
1819
(power (add *par* (div a 2))
1820
(add (add i2 v) 1//2))))
1821
(hgfsimp-exec (list (add (add i2 v 1//2))
1822
(add (sub i2 i1) 1//2))
1823
(list (add (sub v i1) 1))
1824
(div (sub *par* (div a 2))
1825
(add *par* (div a 2)))))))))))))
1741
1827
(defun whittindtest (i1 i2)
1742
1828
(or (maxima-integerp (add i2 i2))
1743
1829
(neginp (sub (sub (1//2) i2) i1))
1839
1925
(parcyl (mul* (power 2 inv2) x) -1)))
1842
(defun eitgammaincomplete(x)(mul* -1 (gminc 0 (mul -1 x))))
1928
;; The exponential integral Ei can be written in terms of the
1929
;; incomplete gamma function.
1931
;; See Table of Integral Transforms, p. 386:
1933
;; -Ei(-x) = E1(x) = integrate(exp(-t)/t,t,x,inf)
1935
;; = gammaincomplete(0,x)
1937
(defun eitgammaincomplete (x)
1938
(mul* -1 (gminc 0 (mul -1 x))))
1940
;; Express Lommel S function in terms of J and Y.
1943
;; S[u,v](z) = s[u,v](z) + {2^(u-1)*gamma((u-v+1)/2)*gamma((u+v+1)/2)}
1944
;; * {sin[(u-v)*%pi/2]*bessel_j(v,z)
1945
;; - cos[(u-v)*%pi/2]*bessel_y(v,z)
1844
1946
(defun slommeltjandy
2169
2278
(div (add* m n 3) 2))
2170
2279
(mul* (inv -4) z z))))
2173
(flg rest arg index)
2174
(prog(index1 index2 argl const l l1)
2175
(cond ((or (zerp index)
2177
(eq flg 'onekelliptic)
2186
(eq flg 'gammagreek)
2190
(cond ((or (eq flg 'hyp-onep)(eq flg 'onelog))
2281
;; FLG = special function we're transforming
2282
;; REST = other stuff
2283
;; ARG = arg of special function
2284
;; INDEX = index of special function.
2286
;; So we're transforming REST*FLG(INDEX, ARG).
2287
(defun lt-ltp (flg rest arg index)
2288
(prog (index1 index2 argl const l l1)
2289
(when (or (zerp index)
2291
(eq flg 'onekelliptic)
2300
(eq flg 'gammagreek)
2304
(cond ((or (eq flg 'hyp-onep)
2306
;; Go to labl1 if we've got %p or log.
2192
(cond ((not (consp index)) (go lab)))
2193
(cond ((not (eq (car index) 'list))(go lab)))
2308
;; Skip this if we have exactly one index or if INDEX doesn't
2309
;; look like '(LIST i1 i2)
2310
(cond ((not (consp index))
2312
(cond ((not (eq (car index) 'list))
2314
;; If the first index is exactly 0, set INDEX1 to it and go to
2194
2316
(cond ((zerp (setq index1 (cadr index)))(go la)))
2317
;; If we're here, the index is of the form '(LIST i1 i2), which
2318
;; means this is the product of two Bessel functions.
2320
;; Ok. I think this is wrong, in general. I think we get here
2321
;; if we're doing the produce to two Bessel functions. This code
2322
;; seems to be applying the property that bessel_j(-n,x) =
2323
;; (-1)^n*bessel_j(n,x). But this only works if n is an integer.
2195
2325
(cond ((eq (checksigntm (simplifya (inv (setq index1
2330
;; FIXME: What is this supposed to do? We take the
2331
;; reciprocal of the first index and see if it's negative.
2332
;; If so, we change the sign of index1 and divide REST by
2333
;; the index. What is this for?
2201
2335
(mul -1 index1)
2203
2337
(mul* (power -1 index1) rest))))
2205
(cond ((zerp (setq index2 (caddr index)))(go la2)))
2339
;; If the second index is zero, skip over this.
2340
(cond ((zerp (setq index2 (caddr index)))
2342
;; Wrong too. See comment above about bessel_j(-n,x).
2206
2344
(cond ((eq (checksigntm (simplifya (inv (setq index2
2349
;; FIXME: This does the same for index2 as for index1
2212
2352
(mul -1 index2)
2214
2354
(mul* (power -1 index2) rest))))
2356
;; Put the 2 indices in a list and go on.
2216
2357
(setq index (list index1 index2))
2360
;; We're here if we have one index, and it's not one of the
2363
;; FIXME: Find out what functions trigger this.
2365
;; I think this is the one bessel function case with a negative
2366
;; index. At least here we check that the index is an integer.
2367
;; We can either leave it here or take it out. It seems
2368
;; bessel_j(-n,x) is converted by the Bessel simplifiers before
2219
2370
(cond ((and (eq (checksigntm (simplifya (inv index)
2222
2373
(maxima-integerp index))
2374
;; FIXME: Same as the 2 index thing above, but we need an
2375
;; (numeric) integer too. Why?
2223
2376
(setq index (mul -1 index))
2224
2377
(setq rest (mul (power -1 index) rest))))
2379
;; Handle index = 0 or one of the special functions erf,
2380
;; kelliptic, E, Jacobi, %d, %s, hstruve, lstruve, %m, Q,
2381
;; incomplete gamma, asin, atan.
2226
2382
(setq argl (f+c arg))
2227
(setq const (cdras 'c argl) arg (cdras 'f argl))
2383
(setq const (cdras 'c argl)
2384
arg (cdras 'f argl))
2385
;; See if the arg is f + c, and replace arg with f.
2228
2386
(cond ((null const)(go labl1)))
2387
;; This handles the case of when the const term is actually there.
2229
2388
(cond ((not (eq (checksigntm (simplifya (power const
2392
;; I guess prop4 handles the case when square of the
2393
;; constant term is not zero. Too bad I (rtoy) don't know
2396
;; FIXME: Implement prop4.
2397
(format t "const = ~A~%" const)
2398
(format t "f = ~A~%" arg)
2233
2399
(return 'prop4-to-be-applied)))
2235
(cond ((eq flg 'oney)(return (lty rest arg index))))
2401
;; No const term, if we're here.
2402
(cond ((eq flg 'oney)
2403
;; Handle bessel_y here. We're done.
2404
(return (lty rest arg index))))
2405
;; Try to express the function in terms of hypergeometric
2406
;; functions that we can handle.
2237
2408
(d*x^m*%e^a*x ($factor (mul* rest