calc-funcs.el 32 KB

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