calc-funcs.el 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012
  1. ;;; calc-funcs.el --- well-known functions for Calc
  2. ;; Copyright (C) 1990-1993, 2001-2012 Free Software Foundation, Inc.
  3. ;; Author: David Gillespie <daveg@synaptics.com>
  4. ;; Maintainer: Jay Belanger <jay.p.belanger@gmail.com>
  5. ;; This file is part of GNU Emacs.
  6. ;; GNU Emacs is free software: you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation, either version 3 of the License, or
  9. ;; (at your option) any later version.
  10. ;; GNU Emacs is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ;; GNU General Public License for more details.
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  16. ;;; Commentary:
  17. ;;; Code:
  18. ;; This file is autoloaded from calc-ext.el.
  19. (require 'calc-ext)
  20. (require 'calc-macs)
  21. (defun calc-inc-gamma (arg)
  22. (interactive "P")
  23. (calc-slow-wrapper
  24. (if (calc-is-inverse)
  25. (if (calc-is-hyperbolic)
  26. (calc-binary-op "gamG" 'calcFunc-gammaG arg)
  27. (calc-binary-op "gamQ" 'calcFunc-gammaQ arg))
  28. (if (calc-is-hyperbolic)
  29. (calc-binary-op "gamg" 'calcFunc-gammag arg)
  30. (calc-binary-op "gamP" 'calcFunc-gammaP arg)))))
  31. (defun calc-erf (arg)
  32. (interactive "P")
  33. (calc-slow-wrapper
  34. (if (calc-is-inverse)
  35. (calc-unary-op "erfc" 'calcFunc-erfc arg)
  36. (calc-unary-op "erf" 'calcFunc-erf arg))))
  37. (defun calc-erfc (arg)
  38. (interactive "P")
  39. (calc-invert-func)
  40. (calc-erf arg))
  41. (defun calc-beta (arg)
  42. (interactive "P")
  43. (calc-slow-wrapper
  44. (calc-binary-op "beta" 'calcFunc-beta arg)))
  45. (defun calc-inc-beta ()
  46. (interactive)
  47. (calc-slow-wrapper
  48. (if (calc-is-hyperbolic)
  49. (calc-enter-result 3 "betB" (cons 'calcFunc-betaB (calc-top-list-n 3)))
  50. (calc-enter-result 3 "betI" (cons 'calcFunc-betaI (calc-top-list-n 3))))))
  51. (defun calc-bessel-J (arg)
  52. (interactive "P")
  53. (calc-slow-wrapper
  54. (calc-binary-op "besJ" 'calcFunc-besJ arg)))
  55. (defun calc-bessel-Y (arg)
  56. (interactive "P")
  57. (calc-slow-wrapper
  58. (calc-binary-op "besY" 'calcFunc-besY arg)))
  59. (defun calc-bernoulli-number (arg)
  60. (interactive "P")
  61. (calc-slow-wrapper
  62. (if (calc-is-hyperbolic)
  63. (calc-binary-op "bern" 'calcFunc-bern arg)
  64. (calc-unary-op "bern" 'calcFunc-bern arg))))
  65. (defun calc-euler-number (arg)
  66. (interactive "P")
  67. (calc-slow-wrapper
  68. (if (calc-is-hyperbolic)
  69. (calc-binary-op "eulr" 'calcFunc-euler arg)
  70. (calc-unary-op "eulr" 'calcFunc-euler arg))))
  71. (defun calc-stirling-number (arg)
  72. (interactive "P")
  73. (calc-slow-wrapper
  74. (if (calc-is-hyperbolic)
  75. (calc-binary-op "str2" 'calcFunc-stir2 arg)
  76. (calc-binary-op "str1" 'calcFunc-stir1 arg))))
  77. (defun calc-utpb ()
  78. (interactive)
  79. (calc-prob-dist "b" 3))
  80. (defun calc-utpc ()
  81. (interactive)
  82. (calc-prob-dist "c" 2))
  83. (defun calc-utpf ()
  84. (interactive)
  85. (calc-prob-dist "f" 3))
  86. (defun calc-utpn ()
  87. (interactive)
  88. (calc-prob-dist "n" 3))
  89. (defun calc-utpp ()
  90. (interactive)
  91. (calc-prob-dist "p" 2))
  92. (defun calc-utpt ()
  93. (interactive)
  94. (calc-prob-dist "t" 2))
  95. (defun calc-prob-dist (letter nargs)
  96. (calc-slow-wrapper
  97. (if (calc-is-inverse)
  98. (calc-enter-result nargs (concat "ltp" letter)
  99. (append (list (intern (concat "calcFunc-ltp" letter))
  100. (calc-top-n 1))
  101. (calc-top-list-n (1- nargs) 2)))
  102. (calc-enter-result nargs (concat "utp" letter)
  103. (append (list (intern (concat "calcFunc-utp" letter))
  104. (calc-top-n 1))
  105. (calc-top-list-n (1- nargs) 2))))))
  106. ;;; Sources: Numerical Recipes, Press et al;
  107. ;;; Handbook of Mathematical Functions, Abramowitz & Stegun.
  108. ;;; Gamma function.
  109. (defun calcFunc-gamma (x)
  110. (or (math-numberp x) (math-reject-arg x 'numberp))
  111. (calcFunc-fact (math-add x -1)))
  112. (defun math-gammap1-raw (x &optional fprec nfprec)
  113. "Compute gamma(1+X) to the appropriate precision."
  114. (or fprec
  115. (setq fprec (math-float calc-internal-prec)
  116. nfprec (math-float (- calc-internal-prec))))
  117. (cond ((math-lessp-float (calcFunc-re x) fprec)
  118. (if (math-lessp-float (calcFunc-re x) nfprec)
  119. (math-neg (math-div
  120. (math-pi)
  121. (math-mul (math-gammap1-raw
  122. (math-add (math-neg x)
  123. '(float -1 0))
  124. fprec nfprec)
  125. (math-sin-raw
  126. (math-mul (math-pi) x)))))
  127. (let ((xplus1 (math-add x '(float 1 0))))
  128. (math-div (math-gammap1-raw xplus1 fprec nfprec) xplus1))))
  129. ((and (math-realp x)
  130. (math-lessp-float '(float 736276 0) x))
  131. (math-overflow))
  132. (t ; re(x) now >= 10.0
  133. (let ((xinv (math-div 1 x))
  134. (lnx (math-ln-raw x)))
  135. (math-mul (math-sqrt-two-pi)
  136. (math-exp-raw
  137. (math-gamma-series
  138. (math-sub (math-mul (math-add x '(float 5 -1))
  139. lnx)
  140. x)
  141. xinv
  142. (math-sqr xinv)
  143. '(float 0 0)
  144. 2)))))))
  145. (defun math-gamma-series (sum x xinvsqr oterm n)
  146. (math-working "gamma" sum)
  147. (let* ((bn (math-bernoulli-number n))
  148. (term (math-mul (math-div-float (math-float (nth 1 bn))
  149. (math-float (* (nth 2 bn)
  150. (* n (1- n)))))
  151. x))
  152. (next (math-add sum term)))
  153. (if (math-nearly-equal sum next)
  154. next
  155. (if (> n (* 2 calc-internal-prec))
  156. (progn
  157. ;; Need this because series eventually diverges for large enough n.
  158. (calc-record-why
  159. "*Gamma computation stopped early, not all digits may be valid")
  160. next)
  161. (math-gamma-series next (math-mul x xinvsqr) xinvsqr term (+ n 2))))))
  162. ;;; Incomplete gamma function.
  163. (defvar math-current-gamma-value nil)
  164. (defun calcFunc-gammaP (a x)
  165. (if (equal x '(var inf var-inf))
  166. '(float 1 0)
  167. (math-inexact-result)
  168. (or (Math-numberp a) (math-reject-arg a 'numberp))
  169. (or (math-numberp x) (math-reject-arg x 'numberp))
  170. (if (and (math-num-integerp a)
  171. (integerp (setq a (math-trunc a)))
  172. (> a 0) (< a 20))
  173. (math-sub 1 (calcFunc-gammaQ a x))
  174. (let ((math-current-gamma-value (calcFunc-gamma a)))
  175. (math-div (calcFunc-gammag a x) math-current-gamma-value)))))
  176. (defun calcFunc-gammaQ (a x)
  177. (if (equal x '(var inf var-inf))
  178. '(float 0 0)
  179. (math-inexact-result)
  180. (or (Math-numberp a) (math-reject-arg a 'numberp))
  181. (or (math-numberp x) (math-reject-arg x 'numberp))
  182. (if (and (math-num-integerp a)
  183. (integerp (setq a (math-trunc a)))
  184. (> a 0) (< a 20))
  185. (let ((n 0)
  186. (sum '(float 1 0))
  187. (term '(float 1 0)))
  188. (math-with-extra-prec 1
  189. (while (< (setq n (1+ n)) a)
  190. (setq term (math-div (math-mul term x) n)
  191. sum (math-add sum term))
  192. (math-working "gamma" sum))
  193. (math-mul sum (calcFunc-exp (math-neg x)))))
  194. (let ((math-current-gamma-value (calcFunc-gamma a)))
  195. (math-div (calcFunc-gammaG a x) math-current-gamma-value)))))
  196. (defun calcFunc-gammag (a x)
  197. (if (equal x '(var inf var-inf))
  198. (calcFunc-gamma a)
  199. (math-inexact-result)
  200. (or (Math-numberp a) (math-reject-arg a 'numberp))
  201. (or (Math-numberp x) (math-reject-arg x 'numberp))
  202. (math-with-extra-prec 2
  203. (setq a (math-float a))
  204. (setq x (math-float x))
  205. (if (or (math-negp (calcFunc-re a))
  206. (math-lessp-float (calcFunc-re x)
  207. (math-add-float (calcFunc-re a)
  208. '(float 1 0))))
  209. (math-inc-gamma-series a x)
  210. (math-sub (or math-current-gamma-value (calcFunc-gamma a))
  211. (math-inc-gamma-cfrac a x))))))
  212. (defun calcFunc-gammaG (a x)
  213. (if (equal x '(var inf var-inf))
  214. '(float 0 0)
  215. (math-inexact-result)
  216. (or (Math-numberp a) (math-reject-arg a 'numberp))
  217. (or (Math-numberp x) (math-reject-arg x 'numberp))
  218. (math-with-extra-prec 2
  219. (setq a (math-float a))
  220. (setq x (math-float x))
  221. (if (or (math-negp (calcFunc-re a))
  222. (math-lessp-float (calcFunc-re x)
  223. (math-add-float (math-abs-approx a)
  224. '(float 1 0))))
  225. (math-sub (or math-current-gamma-value (calcFunc-gamma a))
  226. (math-inc-gamma-series a x))
  227. (math-inc-gamma-cfrac a x)))))
  228. (defun math-inc-gamma-series (a x)
  229. (if (Math-zerop x)
  230. '(float 0 0)
  231. (math-mul (math-exp-raw (math-sub (math-mul a (math-ln-raw x)) x))
  232. (math-with-extra-prec 2
  233. (let ((start (math-div '(float 1 0) a)))
  234. (math-inc-gamma-series-step start start a x))))))
  235. (defun math-inc-gamma-series-step (sum term a x)
  236. (math-working "gamma" sum)
  237. (setq a (math-add a '(float 1 0))
  238. term (math-div (math-mul term x) a))
  239. (let ((next (math-add sum term)))
  240. (if (math-nearly-equal sum next)
  241. next
  242. (math-inc-gamma-series-step next term a x))))
  243. (defun math-inc-gamma-cfrac (a x)
  244. (if (Math-zerop x)
  245. (or math-current-gamma-value (calcFunc-gamma a))
  246. (math-mul (math-exp-raw (math-sub (math-mul a (math-ln-raw x)) x))
  247. (math-inc-gamma-cfrac-step '(float 1 0) x
  248. '(float 0 0) '(float 1 0)
  249. '(float 1 0) '(float 1 0) '(float 0 0)
  250. a x))))
  251. (defun math-inc-gamma-cfrac-step (a0 a1 b0 b1 n fac g a x)
  252. (let ((ana (math-sub n a))
  253. (anf (math-mul n fac)))
  254. (setq n (math-add n '(float 1 0))
  255. a0 (math-mul (math-add a1 (math-mul a0 ana)) fac)
  256. b0 (math-mul (math-add b1 (math-mul b0 ana)) fac)
  257. a1 (math-add (math-mul x a0) (math-mul anf a1))
  258. b1 (math-add (math-mul x b0) (math-mul anf b1)))
  259. (if (math-zerop a1)
  260. (math-inc-gamma-cfrac-step a0 a1 b0 b1 n fac g a x)
  261. (setq fac (math-div '(float 1 0) a1))
  262. (let ((next (math-mul b1 fac)))
  263. (math-working "gamma" next)
  264. (if (math-nearly-equal next g)
  265. next
  266. (math-inc-gamma-cfrac-step a0 a1 b0 b1 n fac next a x))))))
  267. ;;; Error function.
  268. (defun calcFunc-erf (x)
  269. (if (equal x '(var inf var-inf))
  270. '(float 1 0)
  271. (if (equal x '(neg (var inf var-inf)))
  272. '(float -1 0)
  273. (if (Math-zerop x)
  274. x
  275. (let ((math-current-gamma-value (math-sqrt-pi)))
  276. (math-to-same-complex-quad
  277. (math-div (calcFunc-gammag '(float 5 -1)
  278. (math-sqr (math-to-complex-quad-one x)))
  279. math-current-gamma-value)
  280. x))))))
  281. (defun calcFunc-erfc (x)
  282. (if (equal x '(var inf var-inf))
  283. '(float 0 0)
  284. (if (math-posp x)
  285. (let ((math-current-gamma-value (math-sqrt-pi)))
  286. (math-div (calcFunc-gammaG '(float 5 -1) (math-sqr x))
  287. math-current-gamma-value))
  288. (math-sub 1 (calcFunc-erf x)))))
  289. (defun math-to-complex-quad-one (x)
  290. (if (eq (car-safe x) 'polar) (setq x (math-complex x)))
  291. (if (eq (car-safe x) 'cplx)
  292. (list 'cplx (math-abs (nth 1 x)) (math-abs (nth 2 x)))
  293. x))
  294. (defun math-to-same-complex-quad (x y)
  295. (if (eq (car-safe y) 'cplx)
  296. (if (eq (car-safe x) 'cplx)
  297. (list 'cplx
  298. (if (math-negp (nth 1 y)) (math-neg (nth 1 x)) (nth 1 x))
  299. (if (math-negp (nth 2 y)) (math-neg (nth 2 x)) (nth 2 x)))
  300. (if (math-negp (nth 1 y)) (math-neg x) x))
  301. (if (math-negp y)
  302. (if (eq (car-safe x) 'cplx)
  303. (list 'cplx (math-neg (nth 1 x)) (nth 2 x))
  304. (math-neg x))
  305. x)))
  306. ;;; Beta function.
  307. (defun calcFunc-beta (a b)
  308. (if (math-num-integerp a)
  309. (let ((am (math-add a -1)))
  310. (or (math-numberp b) (math-reject-arg b 'numberp))
  311. (math-div 1 (math-mul b (calcFunc-choose (math-add b am) am))))
  312. (if (math-num-integerp b)
  313. (calcFunc-beta b a)
  314. (math-div (math-mul (calcFunc-gamma a) (calcFunc-gamma b))
  315. (calcFunc-gamma (math-add a b))))))
  316. ;;; Incomplete beta function.
  317. (defvar math-current-beta-value nil)
  318. (defun calcFunc-betaI (x a b)
  319. (cond ((math-zerop x)
  320. '(float 0 0))
  321. ((math-equal-int x 1)
  322. '(float 1 0))
  323. ((or (math-zerop a)
  324. (and (math-num-integerp a)
  325. (math-negp a)))
  326. (if (or (math-zerop b)
  327. (and (math-num-integerp b)
  328. (math-negp b)))
  329. (math-reject-arg b 'range)
  330. '(float 1 0)))
  331. ((or (math-zerop b)
  332. (and (math-num-integerp b)
  333. (math-negp b)))
  334. '(float 0 0))
  335. ((not (math-numberp a)) (math-reject-arg a 'numberp))
  336. ((not (math-numberp b)) (math-reject-arg b 'numberp))
  337. ((math-inexact-result))
  338. (t (let ((math-current-beta-value (calcFunc-beta a b)))
  339. (math-div (calcFunc-betaB x a b) math-current-beta-value)))))
  340. (defun calcFunc-betaB (x a b)
  341. (cond
  342. ((math-zerop x)
  343. '(float 0 0))
  344. ((math-equal-int x 1)
  345. (calcFunc-beta a b))
  346. ((not (math-numberp x)) (math-reject-arg x 'numberp))
  347. ((not (math-numberp a)) (math-reject-arg a 'numberp))
  348. ((not (math-numberp b)) (math-reject-arg b 'numberp))
  349. ((math-zerop a) (math-reject-arg a 'nonzerop))
  350. ((math-zerop b) (math-reject-arg b 'nonzerop))
  351. ((and (math-num-integerp b)
  352. (if (math-negp b)
  353. (math-reject-arg b 'range)
  354. (Math-natnum-lessp (setq b (math-trunc b)) 20)))
  355. (and calc-symbolic-mode (or (math-floatp a) (math-floatp b))
  356. (math-inexact-result))
  357. (math-mul
  358. (math-with-extra-prec 2
  359. (let* ((i 0)
  360. (term 1)
  361. (sum (math-div term a)))
  362. (while (< (setq i (1+ i)) b)
  363. (setq term (math-mul (math-div (math-mul term (- i b)) i) x)
  364. sum (math-add sum (math-div term (math-add a i))))
  365. (math-working "beta" sum))
  366. sum))
  367. (math-pow x a)))
  368. ((and (math-num-integerp a)
  369. (if (math-negp a)
  370. (math-reject-arg a 'range)
  371. (Math-natnum-lessp (setq a (math-trunc a)) 20)))
  372. (math-sub (or math-current-beta-value (calcFunc-beta a b))
  373. (calcFunc-betaB (math-sub 1 x) b a)))
  374. (t
  375. (math-inexact-result)
  376. (math-with-extra-prec 2
  377. (setq x (math-float x))
  378. (setq a (math-float a))
  379. (setq b (math-float b))
  380. (let ((bt (math-exp-raw (math-add (math-mul a (math-ln-raw x))
  381. (math-mul b (math-ln-raw
  382. (math-sub '(float 1 0)
  383. x)))))))
  384. (if (Math-lessp x (math-div (math-add a '(float 1 0))
  385. (math-add (math-add a b) '(float 2 0))))
  386. (math-div (math-mul bt (math-beta-cfrac a b x)) a)
  387. (math-sub (or math-current-beta-value (calcFunc-beta a b))
  388. (math-div (math-mul bt
  389. (math-beta-cfrac b a (math-sub 1 x)))
  390. b))))))))
  391. (defun math-beta-cfrac (a b x)
  392. (let ((qab (math-add a b))
  393. (qap (math-add a '(float 1 0)))
  394. (qam (math-add a '(float -1 0))))
  395. (math-beta-cfrac-step '(float 1 0)
  396. (math-sub '(float 1 0)
  397. (math-div (math-mul qab x) qap))
  398. '(float 1 0) '(float 1 0)
  399. '(float 1 0)
  400. qab qap qam a b x)))
  401. (defun math-beta-cfrac-step (az bz am bm m qab qap qam a b x)
  402. (let* ((two-m (math-mul m '(float 2 0)))
  403. (d (math-div (math-mul (math-mul (math-sub b m) m) x)
  404. (math-mul (math-add qam two-m) (math-add a two-m))))
  405. (ap (math-add az (math-mul d am)))
  406. (bp (math-add bz (math-mul d bm)))
  407. (d2 (math-neg
  408. (math-div (math-mul (math-mul (math-add a m) (math-add qab m)) x)
  409. (math-mul (math-add qap two-m) (math-add a two-m)))))
  410. (app (math-add ap (math-mul d2 az)))
  411. (bpp (math-add bp (math-mul d2 bz)))
  412. (next (math-div app bpp)))
  413. (math-working "beta" next)
  414. (if (math-nearly-equal next az)
  415. next
  416. (math-beta-cfrac-step next '(float 1 0)
  417. (math-div ap bpp) (math-div bp bpp)
  418. (math-add m '(float 1 0))
  419. qab qap qam a b x))))
  420. ;;; Bessel functions.
  421. ;;; Should generalize this to handle arbitrary precision!
  422. (defun calcFunc-besJ (v x)
  423. (or (math-numberp v) (math-reject-arg v 'numberp))
  424. (or (math-numberp x) (math-reject-arg x 'numberp))
  425. (let ((calc-internal-prec (min 8 calc-internal-prec)))
  426. (math-with-extra-prec 3
  427. (setq x (math-float (math-normalize x)))
  428. (setq v (math-float (math-normalize v)))
  429. (cond ((math-zerop x)
  430. (if (math-zerop v)
  431. '(float 1 0)
  432. '(float 0 0)))
  433. ((math-inexact-result))
  434. ((not (math-num-integerp v))
  435. (let ((start (math-div 1 (calcFunc-fact v))))
  436. (math-mul (math-besJ-series start start
  437. 0
  438. (math-mul '(float -25 -2)
  439. (math-sqr x))
  440. v)
  441. (math-pow (math-div x 2) v))))
  442. ((math-negp (setq v (math-trunc v)))
  443. (if (math-oddp v)
  444. (math-neg (calcFunc-besJ (math-neg v) x))
  445. (calcFunc-besJ (math-neg v) x)))
  446. ((eq v 0)
  447. (math-besJ0 x))
  448. ((eq v 1)
  449. (math-besJ1 x))
  450. ((Math-lessp v (math-abs-approx x))
  451. (let ((j 0)
  452. (bjm (math-besJ0 x))
  453. (bj (math-besJ1 x))
  454. (two-over-x (math-div 2 x))
  455. bjp)
  456. (while (< (setq j (1+ j)) v)
  457. (setq bjp (math-sub (math-mul (math-mul j two-over-x) bj)
  458. bjm)
  459. bjm bj
  460. bj bjp))
  461. bj))
  462. (t
  463. (if (Math-lessp 100 v) (math-reject-arg v 'range))
  464. (let* ((j (logior (+ v (math-isqrt-small (* 40 v))) 1))
  465. (two-over-x (math-div 2 x))
  466. (jsum nil)
  467. (bjp '(float 0 0))
  468. (sum '(float 0 0))
  469. (bj '(float 1 0))
  470. bjm ans)
  471. (while (> (setq j (1- j)) 0)
  472. (setq bjm (math-sub (math-mul (math-mul j two-over-x) bj)
  473. bjp)
  474. bjp bj
  475. bj bjm)
  476. (if (> (nth 2 (math-abs-approx bj)) 10)
  477. (setq bj (math-mul bj '(float 1 -10))
  478. bjp (math-mul bjp '(float 1 -10))
  479. ans (and ans (math-mul ans '(float 1 -10)))
  480. sum (math-mul sum '(float 1 -10))))
  481. (or (setq jsum (not jsum))
  482. (setq sum (math-add sum bj)))
  483. (if (= j v)
  484. (setq ans bjp)))
  485. (math-div ans (math-sub (math-mul 2 sum) bj))))))))
  486. (defun math-besJ-series (sum term k zz vk)
  487. (math-working "besJ" sum)
  488. (setq k (1+ k)
  489. vk (math-add 1 vk)
  490. term (math-div (math-mul term zz) (math-mul k vk)))
  491. (let ((next (math-add sum term)))
  492. (if (math-nearly-equal next sum)
  493. next
  494. (math-besJ-series next term k zz vk))))
  495. (defun math-besJ0 (x &optional yflag)
  496. (cond ((and (not yflag) (math-negp (calcFunc-re x)))
  497. (math-besJ0 (math-neg x)))
  498. ((Math-lessp '(float 8 0) (math-abs-approx x))
  499. (let* ((z (math-div '(float 8 0) x))
  500. (y (math-sqr z))
  501. (xx (math-add x
  502. (math-read-number-simple "-0.785398164")))
  503. (a1 (math-poly-eval y
  504. (list
  505. (math-read-number-simple "0.0000002093887211")
  506. (math-read-number-simple "-0.000002073370639")
  507. (math-read-number-simple "0.00002734510407")
  508. (math-read-number-simple "-0.001098628627")
  509. '(float 1 0))))
  510. (a2 (math-poly-eval y
  511. (list
  512. (math-read-number-simple "-0.0000000934935152")
  513. (math-read-number-simple "0.0000007621095161")
  514. (math-read-number-simple "-0.000006911147651")
  515. (math-read-number-simple "0.0001430488765")
  516. (math-read-number-simple "-0.01562499995"))))
  517. (sc (math-sin-cos-raw xx)))
  518. (if yflag
  519. (setq sc (cons (math-neg (cdr sc)) (car sc))))
  520. (math-mul (math-sqrt
  521. (math-div (math-read-number-simple "0.636619722")
  522. x))
  523. (math-sub (math-mul (cdr sc) a1)
  524. (math-mul (car sc) (math-mul z a2))))))
  525. (t
  526. (let ((y (math-sqr x)))
  527. (math-div (math-poly-eval y
  528. (list
  529. (math-read-number-simple "-184.9052456")
  530. (math-read-number-simple "77392.33017")
  531. (math-read-number-simple "-11214424.18")
  532. (math-read-number-simple "651619640.7")
  533. (math-read-number-simple "-13362590354.0")
  534. (math-read-number-simple "57568490574.0")))
  535. (math-poly-eval y
  536. (list
  537. '(float 1 0)
  538. (math-read-number-simple "267.8532712")
  539. (math-read-number-simple "59272.64853")
  540. (math-read-number-simple "9494680.718")
  541. (math-read-number-simple "1029532985.0")
  542. (math-read-number-simple "57568490411.0"))))))))
  543. (defun math-besJ1 (x &optional yflag)
  544. (cond ((and (math-negp (calcFunc-re x)) (not yflag))
  545. (math-neg (math-besJ1 (math-neg x))))
  546. ((Math-lessp '(float 8 0) (math-abs-approx x))
  547. (let* ((z (math-div '(float 8 0) x))
  548. (y (math-sqr z))
  549. (xx (math-add x (math-read-number-simple "-2.356194491")))
  550. (a1 (math-poly-eval y
  551. (list
  552. (math-read-number-simple "-0.000000240337019")
  553. (math-read-number-simple "0.000002457520174")
  554. (math-read-number-simple "-0.00003516396496")
  555. '(float 183105 -8)
  556. '(float 1 0))))
  557. (a2 (math-poly-eval y
  558. (list
  559. (math-read-number-simple "0.000000105787412")
  560. (math-read-number-simple "-0.00000088228987")
  561. (math-read-number-simple "0.000008449199096")
  562. (math-read-number-simple "-0.0002002690873")
  563. (math-read-number-simple "0.04687499995"))))
  564. (sc (math-sin-cos-raw xx)))
  565. (if yflag
  566. (setq sc (cons (math-neg (cdr sc)) (car sc)))
  567. (if (math-negp x)
  568. (setq sc (cons (math-neg (car sc)) (math-neg (cdr sc))))))
  569. (math-mul (math-sqrt (math-div
  570. (math-read-number-simple "0.636619722")
  571. x))
  572. (math-sub (math-mul (cdr sc) a1)
  573. (math-mul (car sc) (math-mul z a2))))))
  574. (t
  575. (let ((y (math-sqr x)))
  576. (math-mul
  577. x
  578. (math-div (math-poly-eval y
  579. (list
  580. (math-read-number-simple "-30.16036606")
  581. (math-read-number-simple "15704.4826")
  582. (math-read-number-simple "-2972611.439")
  583. (math-read-number-simple "242396853.1")
  584. (math-read-number-simple "-7895059235.0")
  585. (math-read-number-simple "72362614232.0")))
  586. (math-poly-eval y
  587. (list
  588. '(float 1 0)
  589. (math-read-number-simple "376.9991397")
  590. (math-read-number-simple "99447.43394")
  591. (math-read-number-simple "18583304.74")
  592. (math-read-number-simple "2300535178.0")
  593. (math-read-number-simple "144725228442.0")))))))))
  594. (defun calcFunc-besY (v x)
  595. (math-inexact-result)
  596. (or (math-numberp v) (math-reject-arg v 'numberp))
  597. (or (math-numberp x) (math-reject-arg x 'numberp))
  598. (let ((calc-internal-prec (min 8 calc-internal-prec)))
  599. (math-with-extra-prec 3
  600. (setq x (math-float (math-normalize x)))
  601. (setq v (math-float (math-normalize v)))
  602. (cond ((not (math-num-integerp v))
  603. (let ((sc (math-sin-cos-raw (math-mul v (math-pi)))))
  604. (math-div (math-sub (math-mul (calcFunc-besJ v x) (cdr sc))
  605. (calcFunc-besJ (math-neg v) x))
  606. (car sc))))
  607. ((math-negp (setq v (math-trunc v)))
  608. (if (math-oddp v)
  609. (math-neg (calcFunc-besY (math-neg v) x))
  610. (calcFunc-besY (math-neg v) x)))
  611. ((eq v 0)
  612. (math-besY0 x))
  613. ((eq v 1)
  614. (math-besY1 x))
  615. (t
  616. (let ((j 0)
  617. (bym (math-besY0 x))
  618. (by (math-besY1 x))
  619. (two-over-x (math-div 2 x))
  620. byp)
  621. (while (< (setq j (1+ j)) v)
  622. (setq byp (math-sub (math-mul (math-mul j two-over-x) by)
  623. bym)
  624. bym by
  625. by byp))
  626. by))))))
  627. (defun math-besY0 (x)
  628. (cond ((Math-lessp (math-abs-approx x) '(float 8 0))
  629. (let ((y (math-sqr x)))
  630. (math-add
  631. (math-div (math-poly-eval y
  632. (list
  633. (math-read-number-simple "228.4622733")
  634. (math-read-number-simple "-86327.92757")
  635. (math-read-number-simple "10879881.29")
  636. (math-read-number-simple "-512359803.6")
  637. (math-read-number-simple "7062834065.0")
  638. (math-read-number-simple "-2957821389.0")))
  639. (math-poly-eval y
  640. (list
  641. '(float 1 0)
  642. (math-read-number-simple "226.1030244")
  643. (math-read-number-simple "47447.2647")
  644. (math-read-number-simple "7189466.438")
  645. (math-read-number-simple "745249964.8")
  646. (math-read-number-simple "40076544269.0"))))
  647. (math-mul (math-read-number-simple "0.636619772")
  648. (math-mul (math-besJ0 x) (math-ln-raw x))))))
  649. ((math-negp (calcFunc-re x))
  650. (math-add (math-besJ0 (math-neg x) t)
  651. (math-mul '(cplx 0 2)
  652. (math-besJ0 (math-neg x)))))
  653. (t
  654. (math-besJ0 x t))))
  655. (defun math-besY1 (x)
  656. (cond ((Math-lessp (math-abs-approx x) '(float 8 0))
  657. (let ((y (math-sqr x)))
  658. (math-add
  659. (math-mul
  660. x
  661. (math-div (math-poly-eval y
  662. (list
  663. (math-read-number-simple "8511.937935")
  664. (math-read-number-simple "-4237922.726")
  665. (math-read-number-simple "734926455.1")
  666. (math-read-number-simple "-51534381390.0")
  667. (math-read-number-simple "1275274390000.0")
  668. (math-read-number-simple "-4900604943000.0")))
  669. (math-poly-eval y
  670. (list
  671. '(float 1 0)
  672. (math-read-number-simple "354.9632885")
  673. (math-read-number-simple "102042.605")
  674. (math-read-number-simple "22459040.02")
  675. (math-read-number-simple "3733650367.0")
  676. (math-read-number-simple "424441966400.0")
  677. (math-read-number-simple "24995805700000.0")))))
  678. (math-mul (math-read-number-simple "0.636619772")
  679. (math-sub (math-mul (math-besJ1 x) (math-ln-raw x))
  680. (math-div 1 x))))))
  681. ((math-negp (calcFunc-re x))
  682. (math-neg
  683. (math-add (math-besJ1 (math-neg x) t)
  684. (math-mul '(cplx 0 2)
  685. (math-besJ1 (math-neg x))))))
  686. (t
  687. (math-besJ1 x t))))
  688. (defun math-poly-eval (x coefs)
  689. (let ((accum (car coefs)))
  690. (while (setq coefs (cdr coefs))
  691. (setq accum (math-add (car coefs) (math-mul accum x))))
  692. accum))
  693. ;;;; Bernoulli and Euler polynomials and numbers.
  694. (defun calcFunc-bern (n &optional x)
  695. (if (and x (not (math-zerop x)))
  696. (if (and calc-symbolic-mode (math-floatp x))
  697. (math-inexact-result)
  698. (math-build-polynomial-expr (math-bernoulli-coefs n) x))
  699. (or (math-num-natnump n) (math-reject-arg n 'natnump))
  700. (if (consp n)
  701. (progn
  702. (math-inexact-result)
  703. (math-float (math-bernoulli-number (math-trunc n))))
  704. (math-bernoulli-number n))))
  705. (defun calcFunc-euler (n &optional x)
  706. (or (math-num-natnump n) (math-reject-arg n 'natnump))
  707. (if x
  708. (let* ((n1 (math-add n 1))
  709. (coefs (math-bernoulli-coefs n1))
  710. (fac (math-div (math-pow 2 n1) n1))
  711. (k -1)
  712. (x1 (math-div (math-add x 1) 2))
  713. (x2 (math-div x 2)))
  714. (if (math-numberp x)
  715. (if (and calc-symbolic-mode (math-floatp x))
  716. (math-inexact-result)
  717. (math-mul fac
  718. (math-sub (math-build-polynomial-expr coefs x1)
  719. (math-build-polynomial-expr coefs x2))))
  720. (calcFunc-collect
  721. (math-reduce-vec
  722. 'math-add
  723. (cons 'vec
  724. (mapcar (function
  725. (lambda (c)
  726. (setq k (1+ k))
  727. (math-mul (math-mul fac c)
  728. (math-sub (math-pow x1 k)
  729. (math-pow x2 k)))))
  730. coefs)))
  731. x)))
  732. (math-mul (math-pow 2 n)
  733. (if (consp n)
  734. (progn
  735. (math-inexact-result)
  736. (calcFunc-euler n '(float 5 -1)))
  737. (calcFunc-euler n '(frac 1 2))))))
  738. (defvar math-bernoulli-b-cache
  739. (list
  740. (list 'frac
  741. -174611
  742. (math-read-number-simple "802857662698291200000"))
  743. (list 'frac
  744. 43867
  745. (math-read-number-simple "5109094217170944000"))
  746. (list 'frac
  747. -3617
  748. (math-read-number-simple "10670622842880000"))
  749. (list 'frac
  750. 1
  751. (math-read-number-simple "74724249600"))
  752. (list 'frac
  753. -691
  754. (math-read-number-simple "1307674368000"))
  755. (list 'frac
  756. 1
  757. (math-read-number-simple "47900160"))
  758. (list 'frac
  759. -1
  760. (math-read-number-simple "1209600"))
  761. (list 'frac
  762. 1
  763. 30240)
  764. (list 'frac
  765. -1
  766. 720)
  767. (list 'frac
  768. 1
  769. 12)
  770. 1 ))
  771. (defvar math-bernoulli-B-cache
  772. '((frac -174611 330) (frac 43867 798)
  773. (frac -3617 510) (frac 7 6) (frac -691 2730)
  774. (frac 5 66) (frac -1 30) (frac 1 42)
  775. (frac -1 30) (frac 1 6) 1 ))
  776. (defvar math-bernoulli-cache-size 11)
  777. (defun math-bernoulli-coefs (n)
  778. (let* ((coefs (list (calcFunc-bern n)))
  779. (nn (math-trunc n))
  780. (k nn)
  781. (term nn)
  782. coef
  783. (calc-prefer-frac (or (integerp n) calc-prefer-frac)))
  784. (while (>= (setq k (1- k)) 0)
  785. (setq term (math-div term (- nn k))
  786. coef (math-mul term (math-bernoulli-number k))
  787. coefs (cons (if (consp n) (math-float coef) coef) coefs)
  788. term (math-mul term k)))
  789. (nreverse coefs)))
  790. (defun math-bernoulli-number (n)
  791. (if (= (% n 2) 1)
  792. (if (= n 1)
  793. '(frac -1 2)
  794. 0)
  795. (setq n (/ n 2))
  796. (while (>= n math-bernoulli-cache-size)
  797. (let* ((sum 0)
  798. (nk 1) ; nk = n-k+1
  799. (fact 1) ; fact = (n-k+1)!
  800. ofact
  801. (p math-bernoulli-b-cache)
  802. (calc-prefer-frac t))
  803. (math-working "bernoulli B" (* 2 math-bernoulli-cache-size))
  804. (while p
  805. (setq nk (+ nk 2)
  806. ofact fact
  807. fact (math-mul fact (* nk (1- nk)))
  808. sum (math-add sum (math-div (car p) fact))
  809. p (cdr p)))
  810. (setq ofact (math-mul ofact (1- nk))
  811. sum (math-sub (math-div '(frac 1 2) ofact) sum)
  812. math-bernoulli-b-cache (cons sum math-bernoulli-b-cache)
  813. math-bernoulli-B-cache (cons (math-mul sum ofact)
  814. math-bernoulli-B-cache)
  815. math-bernoulli-cache-size (1+ math-bernoulli-cache-size))))
  816. (nth (- math-bernoulli-cache-size n 1) math-bernoulli-B-cache)))
  817. ;;; Bn = n! bn
  818. ;;; bn = - sum_k=0^n-1 bk / (n-k+1)!
  819. ;;; A faster method would be to use "tangent numbers", c.f., Concrete
  820. ;;; Mathematics pg. 273.
  821. ;;; Probability distributions.
  822. ;;; Binomial.
  823. (defun calcFunc-utpb (x n p)
  824. (if math-expand-formulas
  825. (math-normalize (list 'calcFunc-betaI p x (list '+ (list '- n x) 1)))
  826. (calcFunc-betaI p x (math-add (math-sub n x) 1))))
  827. (put 'calcFunc-utpb 'math-expandable t)
  828. (defun calcFunc-ltpb (x n p)
  829. (math-sub 1 (calcFunc-utpb x n p)))
  830. (put 'calcFunc-ltpb 'math-expandable t)
  831. ;;; Chi-square.
  832. (defun calcFunc-utpc (chisq v)
  833. (if math-expand-formulas
  834. (math-normalize (list 'calcFunc-gammaQ (list '/ v 2) (list '/ chisq 2)))
  835. (calcFunc-gammaQ (math-div v 2) (math-div chisq 2))))
  836. (put 'calcFunc-utpc 'math-expandable t)
  837. (defun calcFunc-ltpc (chisq v)
  838. (if math-expand-formulas
  839. (math-normalize (list 'calcFunc-gammaP (list '/ v 2) (list '/ chisq 2)))
  840. (calcFunc-gammaP (math-div v 2) (math-div chisq 2))))
  841. (put 'calcFunc-ltpc 'math-expandable t)
  842. ;;; F-distribution.
  843. (defun calcFunc-utpf (f v1 v2)
  844. (if math-expand-formulas
  845. (math-normalize (list 'calcFunc-betaI
  846. (list '/ v2 (list '+ v2 (list '* v1 f)))
  847. (list '/ v2 2)
  848. (list '/ v1 2)))
  849. (calcFunc-betaI (math-div v2 (math-add v2 (math-mul v1 f)))
  850. (math-div v2 2)
  851. (math-div v1 2))))
  852. (put 'calcFunc-utpf 'math-expandable t)
  853. (defun calcFunc-ltpf (f v1 v2)
  854. (math-sub 1 (calcFunc-utpf f v1 v2)))
  855. (put 'calcFunc-ltpf 'math-expandable t)
  856. ;;; Normal.
  857. (defun calcFunc-utpn (x mean sdev)
  858. (if math-expand-formulas
  859. (math-normalize
  860. (list '/
  861. (list '+ 1
  862. (list 'calcFunc-erf
  863. (list '/ (list '- mean x)
  864. (list '* sdev (list 'calcFunc-sqrt 2)))))
  865. 2))
  866. (math-mul (math-add '(float 1 0)
  867. (calcFunc-erf
  868. (math-div (math-sub mean x)
  869. (math-mul sdev (math-sqrt-2)))))
  870. '(float 5 -1))))
  871. (put 'calcFunc-utpn 'math-expandable t)
  872. (defun calcFunc-ltpn (x mean sdev)
  873. (if math-expand-formulas
  874. (math-normalize
  875. (list '/
  876. (list '+ 1
  877. (list 'calcFunc-erf
  878. (list '/ (list '- x mean)
  879. (list '* sdev (list 'calcFunc-sqrt 2)))))
  880. 2))
  881. (math-mul (math-add '(float 1 0)
  882. (calcFunc-erf
  883. (math-div (math-sub x mean)
  884. (math-mul sdev (math-sqrt-2)))))
  885. '(float 5 -1))))
  886. (put 'calcFunc-ltpn 'math-expandable t)
  887. ;;; Poisson.
  888. (defun calcFunc-utpp (n x)
  889. (if math-expand-formulas
  890. (math-normalize (list 'calcFunc-gammaP x n))
  891. (calcFunc-gammaP x n)))
  892. (put 'calcFunc-utpp 'math-expandable t)
  893. (defun calcFunc-ltpp (n x)
  894. (if math-expand-formulas
  895. (math-normalize (list 'calcFunc-gammaQ x n))
  896. (calcFunc-gammaQ x n)))
  897. (put 'calcFunc-ltpp 'math-expandable t)
  898. ;;; Student's t. (As defined in Abramowitz & Stegun and Numerical Recipes.)
  899. (defun calcFunc-utpt (tt v)
  900. (if math-expand-formulas
  901. (math-normalize (list 'calcFunc-betaI
  902. (list '/ v (list '+ v (list '^ tt 2)))
  903. (list '/ v 2)
  904. '(float 5 -1)))
  905. (calcFunc-betaI (math-div v (math-add v (math-sqr tt)))
  906. (math-div v 2)
  907. '(float 5 -1))))
  908. (put 'calcFunc-utpt 'math-expandable t)
  909. (defun calcFunc-ltpt (tt v)
  910. (math-sub 1 (calcFunc-utpt tt v)))
  911. (put 'calcFunc-ltpt 'math-expandable t)
  912. (provide 'calc-funcs)
  913. ;;; calc-funcs.el ends here