spe.pas 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792
  1. {
  2. This file is part of the Numlib package.
  3. Copyright (c) 1986-2000 by
  4. Kees van Ginneken, Wil Kortsmit and Loek van Reij of the
  5. Computational centre of the Eindhoven University of Technology
  6. FPC port Code by Marco van de Voort ([email protected])
  7. documentation by Michael van Canneyt ([email protected])
  8. Special functions. (Currently, most of these functions only work for
  9. ArbFloat=REAL/DOUBLE, not for Extended(at least not at full
  10. precision, implement the tables in the diverse functions
  11. for extended)
  12. See the file COPYING.FPC, included in this distribution,
  13. for details about the copyright.
  14. This program is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. **********************************************************************}
  18. {$mode objfpc}{$H+}
  19. {$modeswitch nestedprocvars}
  20. unit spe;
  21. {$I DIRECT.INC}
  22. interface
  23. uses typ;
  24. { Calculate modified Besselfunction "of the first kind" I0(x) }
  25. function spebi0(x: ArbFloat): ArbFloat;
  26. { Calculate modified Besselfunction "of the first kind" I1(x) }
  27. function spebi1(x: ArbFloat): ArbFloat;
  28. { Calculate Besselfunction "of the first kind" J0(x) }
  29. function spebj0(x: ArbFloat): ArbFloat;
  30. { Calculate Besselfunction "of the first kind" J1(x) }
  31. function spebj1(x: ArbFloat): ArbFloat;
  32. { Calculate modified Besselfunction "of the second kind" K0(x) }
  33. function spebk0(x: ArbFloat): ArbFloat;
  34. { Calculate modified Besselfunction "of the second kind" K1(x) }
  35. function spebk1(x: ArbFloat): ArbFloat;
  36. { Calculate Besselfunction "of the second kind" Y0(x) }
  37. function speby0(x: ArbFloat): ArbFloat;
  38. { Calculate Besselfunction "of the second kind" Y1(x) }
  39. function speby1(x: ArbFloat): ArbFloat;
  40. { Entier function, calculates first integer greater or equal than X}
  41. function speent(x: ArbFloat): longint;
  42. { Errorfunction ( 2/sqrt(pi)* Int(t,0,pi,exp(sqr(t)) )}
  43. function speerf(x: ArbFloat): ArbFloat;
  44. { Errorfunction's complement ( 2/sqrt(pi)* Int(t,pi,inf,exp(sqr(t))) )}
  45. function speefc(x: ArbFloat): ArbFloat;
  46. { Calculates the cumulative normal distribution
  47. N(x) = 1/sqrt(2*pi) * Int(t, -INF, x, exp(t^2/2) ) }
  48. function normaldist(x: ArbFloat): ArbFloat;
  49. { Inverse of cumulative normal distribution:
  50. Returns x such that y = normaldist(x) }
  51. function invnormaldist(y: ArbFloat): ArbFloat;
  52. { Function to calculate the Gamma function ( int(t,0,inf,t^(x-1)*exp(-t)) }
  53. function spegam(x: ArbFloat): ArbFloat;
  54. { Function to calculate the natural logaritm of the Gamma function}
  55. function spelga(x: ArbFloat): ArbFloat;
  56. { Function to calculate the lower incomplete Gamma function
  57. int(t,0,x,exp(-t)t^(s-1)) / spegam(s) (s > 0) }
  58. function gammap(s, x: ArbFloat): ArbFloat;
  59. { Function to calculate the upper incomplete Gamma function
  60. int(t,x,inf,exp(-t)t^(s-1)) / spegam(s) (s > 0)
  61. gammaq(s,x) = 1 - gammap(s,x) }
  62. function gammaq(s, x: ArbFloat): ArbFloat;
  63. function invgammaq(s, y: ArbFloat): ArbFloat;
  64. { Function to calculate the (complete) beta function
  65. beta(a, b) = int(t, 0, 1, t^(a-1) * (1-t)^(b-1) with a > 0, b > 0
  66. beta(a, b) = spegam(a) * spegam(b) / spegam(a + b) }
  67. function beta(a, b: ArbFloat): ArbFloat;
  68. { Function to calculate the (regularized) incomplete beta function
  69. betai(a, b, x) = int(t, 0, x, t^(x-1) * (1-t)^(y-1) ) / beta(a,b) }
  70. function betai(a, b, x: ArbFloat): ArbFloat;
  71. function invbetai(a, b, y: ArbFloat; eps: ArbFloat = 0.0): ArbFloat;
  72. { Function to calculate the cumulative chi2 distribution with n degrees of
  73. freedom (upper tail) }
  74. function chi2dist(x: ArbFloat; n: ArbInt): ArbFloat;
  75. function invchi2dist(y: Arbfloat; n: ArbInt): ArbFloat;
  76. { Function to calculate Student's t distribution with n degrees of freedom
  77. (cumulative, upper tail if Tails = 1, else both tails }
  78. type
  79. TNumTails = 1..2;
  80. function tdist(t: ArbFloat; n: ArbInt; Tails: TNumTails): ArbFloat;
  81. function invtdist(y: ArbFloat; n: ArbInt; Tails: TNumTails; eps: ArbFloat = 0.0): ArbFloat;
  82. { Function to calculate the cumulative F distribution function of value F
  83. with n1 and n2 degrees of freedom }
  84. function Fdist(F: ArbFloat; n1, n2: ArbInt): ArbFloat;
  85. function invFdist(p: ArbFloat; n1, n2: ArbInt; eps: ArbFloat = 0.0): ArbFloat;
  86. { "Calculates" the maximum of two ArbFloat values }
  87. function spemax(a, b: ArbFloat): ArbFloat; deprecated 'Use max(a,b) in unit math.';
  88. { Calculates the function value of a polynomial of degree n for variable x.
  89. The polynomial coefficients a are ordered from lowest to highest degree term.
  90. y = a0 + a1 x + a2 x^2 + ... + an x^n }
  91. function spepol(x: ArbFloat; var a: ArbFloat; n: ArbInt): ArbFloat;
  92. { Calc a^b with a and b real numbers}
  93. function spepow(a, b: ArbFloat): ArbFloat; deprecated 'Use power(a,b) in unit math.';
  94. { Returns sign of x (-1 for x<0, 0 for x=0 and 1 for x>0) }
  95. function spesgn(x: ArbFloat): ArbInt; deprecated 'Use sign(x) in unit math.';
  96. { ArcSin(x) }
  97. function spears(x: ArbFloat): ArbFloat; deprecated 'Use arcsin(x) in unit math.';
  98. { ArcCos(x) }
  99. function spearc(x: ArbFloat): ArbFloat; deprecated 'Use arccos(x) in unit math.';
  100. { Sinh(x) }
  101. function spesih(x: ArbFloat): ArbFloat; deprecated 'Use sinh(x) in unit math.';
  102. { Cosh(x) }
  103. function specoh(x: ArbFloat): ArbFloat; deprecated 'Use cosh(x) in unit math.';
  104. { Tanh(x) }
  105. function spetah(x: ArbFloat): ArbFloat; deprecated 'Use tanh(x) in unit math.';
  106. { ArcSinH(x) }
  107. function speash(x: ArbFloat): ArbFloat; deprecated 'Use arcsinh(x) in unit math.';
  108. { ArcCosh(x) }
  109. function speach(x: ArbFloat): ArbFloat; deprecated 'Use arccosh(x) in unit math';
  110. { ArcTanH(x) }
  111. function speath(x: ArbFloat): ArbFloat; deprecated 'Use arctanh(x) in unit math';
  112. { Error numbers used within this unit:
  113. 401 - function spebk0(x) is not defined for x <= 0.
  114. 402 - function spebk1(x) is not defined for x <= 0.
  115. 403 - function speby0(x) is not defined for x <= 0.
  116. 404 - function speby1(x) is not defined for x <= 0.
  117. 405 - function speach(x) is not defined for x < 1
  118. 406 - function speath(x) is not defined for x <= -1 or x >= 1
  119. 407 - function spgam(x): x is too small or too large.
  120. 408 - function splga(x) cannot be calculated for x <= 0, or x is too large.
  121. 409 - function spears(s, x) is not defined for x < -1 or x > 1
  122. 410 - function gammap(s, x) is not defined for s <= 0 or x < 0
  123. 411 - function gammaq(s, x) is not defined for s <= 0 or x < 0
  124. 412 - function beta(a, b) is not defined for a <= 0 or b <= 0
  125. 413 - function betai(a, b, x) is not defined for a <= 0 or b <= 0
  126. 414 - function betai(a, b, x) is not defined for x < 0 or x > 0
  127. 415 - function invtdist(t, n) is not defined for t <= 0 or t >= 1 or n <= 0.
  128. }
  129. implementation
  130. uses
  131. math, roo;
  132. const
  133. SQRT2 = 1.4142135623730950488016887242097; // sqrt(2)
  134. SQRT2PI = 2.506628274631000502415765284811; // sqrt(2*pi)
  135. EXP_2 = 0.13533528323661269189399949497248; // exp(-2)
  136. function spebi0(x: ArbFloat): ArbFloat;
  137. const
  138. xvsmall = 3.2e-9;
  139. a1 : array[0..23] of ArbFloat =
  140. ( 3.08508322553671039e-1, -1.86478066609466760e-1,
  141. 1.57686843969995904e-1, -1.28895621330524993e-1,
  142. 9.41616340200868389e-2, -6.04316795007737183e-2,
  143. 3.41505388391452157e-2, -1.71317947935716536e-2,
  144. 7.70061052263382555e-3, -3.12923286656374358e-3,
  145. 1.15888319775791686e-3, -3.93934532072526720e-4,
  146. 1.23682594989692688e-4, -3.60645571444886286e-5,
  147. 9.81395862769787105e-6, -2.50298975966588680e-6,
  148. 6.00566861079330132e-7, -1.36042013507151017e-7,
  149. 2.92096163521178835e-8, -5.94856273204259507e-9,
  150. 1.13415934215369209e-9, -2.10071360134551962e-10,
  151. 4.44484446637868974e-11,-7.48150165756234957e-12);
  152. a2 : array[0..26] of ArbFloat =
  153. ( 1.43431781856850311e-1, -3.71571542566085323e-2,
  154. 1.44861237337359455e-2, -6.30121694459896307e-3,
  155. 2.89362046530968701e-3, -1.37638906941232170e-3,
  156. 6.72508592273773611e-4, -3.35833513200679384e-4,
  157. 1.70524543267970595e-4, -8.74354291104467762e-5,
  158. 4.48739019580173804e-5, -2.28278155280668483e-5,
  159. 1.14032404021741277e-5, -5.54917762110482949e-6,
  160. 2.61457634142262604e-6, -1.18752840689765504e-6,
  161. 5.18632519069546106e-7, -2.17653548816447667e-7,
  162. 8.75291839187305722e-8, -3.34900221934314738e-8,
  163. 1.24131668344616429e-8, -4.66215489983794905e-9,
  164. 1.58599776268172290e-9, -3.80370174256271589e-10,
  165. 1.23188158175419302e-10,-8.46900307934754898e-11,
  166. 2.45185252963941089e-11);
  167. a3: array[0..19] of ArbFloat =
  168. ( 4.01071065066847416e-1, 2.18216817211694382e-3,
  169. 5.59848253337377763e-5, 2.79770701849785597e-6,
  170. 2.17160501061222148e-7, 2.36884434055843528e-8,
  171. 3.44345025431425567e-9, 6.47994117793472057e-10,
  172. 1.56147127476528831e-10, 4.82726630988879388e-11,
  173. 1.89599322920800794e-11, 1.05863621425699789e-11,
  174. 8.27719401266046976e-12, 2.82807056475555021e-12,
  175. -4.34624739357691085e-12,-4.29417106720584499e-12,
  176. 4.30812577328136192e-13, 1.44572313799118029e-12,
  177. 4.73229306831831040e-14,-1.95679809047625728e-13);
  178. var t : ArbFloat;
  179. begin
  180. t:=abs(x);
  181. if t <=xvsmall
  182. then
  183. spebi0:=1
  184. else
  185. if t <= 4
  186. then
  187. spebi0 := exp(t)*spepol(t/2-1, a1[0], SizeOf(a1) div SizeOf(ArbFloat) -1)
  188. else
  189. if t <= 12
  190. then
  191. spebi0:=exp(t)*spepol(t/4-2, a2[0], SizeOf(a2) div SizeOf(ArbFloat) -1)
  192. else { t > 12}
  193. spebi0:=(exp(t)/sqrt(t))*
  194. spepol(24/t-1, a3[0], SizeOf(a3) div SizeOf(ArbFloat) -1)
  195. end; {spebi0}
  196. function spebi1(x: ArbFloat): ArbFloat;
  197. const xvsmall = 3.2e-9;
  198. a1: array[0..11] of ArbFloat =
  199. ( 1.19741654963670236e+0, 9.28758890114609554e-1,
  200. 2.68657659522092832e-1, 4.09286371827770484e-2,
  201. 3.84763940423809498e-3, 2.45224314039278904e-4,
  202. 1.12849795779951847e-5, 3.92368710996392755e-7,
  203. 1.06662712314503955e-8, 2.32856921884663846e-10,
  204. 4.17372709788222413e-12,6.24387910353848320e-14);
  205. a2: array[0..26] of ArbFloat =
  206. ( 1.34142493292698178e-1, -2.99140923897405570e-2,
  207. 9.76021102528646704e-3, -3.40759647928956354e-3,
  208. 1.17313412855965374e-3, -3.67626180992174570e-4,
  209. 8.47999438119288094e-5, 5.21557319070236939e-6,
  210. -2.62051678511418163e-5, 2.47493270133518925e-5,
  211. -1.79026222757948636e-5, 1.13818992442463952e-5,
  212. -6.63144162982509821e-6, 3.60186151617732531e-6,
  213. -1.83910206626348772e-6, 8.86951515545183908e-7,
  214. -4.05456611578551130e-7, 1.76305222240064495e-7,
  215. -7.28978293484163628e-8, 2.84961041291017650e-8,
  216. -1.07563514207617768e-8, 4.11321223904934809e-9,
  217. -1.41575617446629553e-9, 3.38883570696523350e-10,
  218. -1.10970391104678003e-10, 7.79929176497056645e-11,
  219. -2.27061376122617856e-11);
  220. a3: array[0..19] of ArbFloat =
  221. ( 3.92624494204116555e-1, -6.40545360348237412e-3,
  222. -9.12475535508497109e-5, -3.82795135453556215e-6,
  223. -2.72684545741400871e-7, -2.82537120880041703e-8,
  224. -3.96757162863209348e-9, -7.28107961041827952e-10,
  225. -1.72060490748583241e-10,-5.23524129533553498e-11,
  226. -2.02947854602758139e-11,-1.11795516742222899e-11,
  227. -8.69631766630563635e-12,-3.05957293450420224e-12,
  228. 4.42966462319664333e-12, 4.47735589657057690e-12,
  229. -3.95353303949377536e-13,-1.48765082315961139e-12,
  230. -5.77176811730370560e-14, 1.99448557598015488e-13);
  231. var t : ArbFloat;
  232. begin
  233. t:=abs(x);
  234. if t <= xvsmall
  235. then
  236. spebi1:=x/2
  237. else
  238. if t <= 4
  239. then
  240. spebi1:=x*spepol(sqr(t)/8-1, a1[0], sizeof(a1) div sizeof(ArbFloat)-1)
  241. else
  242. if t <= 12
  243. then
  244. spebi1:=
  245. exp(t)*spepol(t/4-2, a2[0], sizeof(a2) div sizeof(ArbFloat)-1)*spesgn(x)
  246. else { t > 12}
  247. spebi1:=
  248. (exp(t)/sqrt(t))*
  249. spepol(24/t-1, a3[0], sizeof(a3) div sizeof(ArbFloat)-1)*spesgn(x)
  250. end; {spebi1}
  251. function spebj0(x: ArbFloat): ArbFloat;
  252. const
  253. xvsmall = 3.2e-9;
  254. tbpi = 6.36619772367581343e-1;
  255. a1 : array[0..5] of ArbFloat =
  256. ( 1.22200000000000000e-17, -1.94383469000000000e-12,
  257. 7.60816359241900000e-8, -4.60626166206275050e-4,
  258. 1.58067102332097261e-1, -8.72344235285222129e-3);
  259. b1 : array[0..5] of ArbFloat =
  260. ( - 7.58850000000000000e-16, 7.84869631400000000e-11,
  261. - 1.76194690776215000e-6, 4.81918006946760450e-3,
  262. - 3.70094993872649779e-1, 1.57727971474890120e-1);
  263. c1 : array[0..4] of ArbFloat =
  264. ( 4.12532100000000000e-14, - 2.67925353056000000e-9,
  265. 3.24603288210050800e-5, - 3.48937694114088852e-2,
  266. 2.65178613203336810e-1);
  267. d1 : array[0..13] of ArbFloat =
  268. ( 9.99457275788251954e-1, -5.36367319213004570e-4,
  269. 6.13741608010926000e-6, -2.05274481565160000e-7,
  270. 1.28037614434400000e-8, -1.21211819632000000e-9,
  271. 1.55005642880000000e-10,-2.48827276800000000e-11,
  272. 4.78702080000000000e-12,-1.06365696000000000e-12,
  273. 2.45294080000000000e-13,-6.41843200000000000e-14,
  274. 3.34028800000000000e-14,-1.17964800000000000e-14);
  275. d2 : array[0..16] of ArbFloat =
  276. ( -1.55551138795135187e-2, 6.83314909934390000e-5,
  277. -1.47713883264594000e-6, 7.10621485930000000e-8,
  278. -5.66871613024000000e-9, 6.43278173280000000e-10,
  279. -9.47034774400000000e-11, 1.70330918400000000e-11,
  280. -3.59094272000000000e-12, 8.59855360000000000e-13,
  281. -2.28807680000000000e-13, 6.95193600000000000e-14,
  282. -2.27942400000000000e-14, 4.75136000000000000e-15,
  283. -1.14688000000000000e-15, 2.12992000000000000e-15,
  284. -9.83040000000000000e-16);
  285. var t, g, y, t2, a, b, c, cx, sx : ArbFloat;
  286. i, bov : ArbInt;
  287. begin
  288. t:=abs(x);
  289. if t<=xvsmall
  290. then
  291. spebj0:=1
  292. else
  293. if t<=8
  294. then
  295. begin
  296. t:=0.03125*sqr(t)-1; t2:=2*t;
  297. b:=0; c:=0;
  298. bov:=sizeof(a1) div sizeof(ArbFloat) - 1;
  299. for i:=0 to bov do
  300. begin
  301. a:=t2*c-b+a1[i];
  302. if i<5
  303. then
  304. b:=t2*a-c+b1[i]
  305. else
  306. spebj0:=t*a-c+b1[i];
  307. if i<bov
  308. then
  309. c:=t2*b-a+c1[i]
  310. else
  311. if i<5
  312. then
  313. spebj0:=t*b-a+c1[i]
  314. end {i}
  315. end {abs(x)<=8}
  316. else
  317. begin
  318. g:=t-1/(2*tbpi); y:=sqrt(tbpi/t);
  319. cx:=cos(g)*y; sx:=-sin(g)*y*8/t;
  320. t:=128/sqr(t)-1;
  321. spebj0:=cx*spepol(t, d1[0], sizeof(d1) div sizeof(ArbFloat) - 1)
  322. + sx*spepol(t, d2[0], sizeof(d2) div sizeof(ArbFloat) - 1)
  323. end {abs(x)>8}
  324. end {spebj0};
  325. function spebj1(x: ArbFloat): ArbFloat;
  326. const
  327. xvsmall = 3.2e-9;
  328. tbpi = 6.36619772367581343e-1;
  329. a1 : array[0..5] of ArbFloat =
  330. ( 2.95000000000000000e-18, -5.77740420000000000e-13,
  331. 2.94970700727800000e-8, -2.60444389348580680e-4,
  332. 1.77709117239728283e-1, -1.19180116054121687e+0);
  333. b1 : array[0..5] of ArbFloat =
  334. ( -1.95540000000000000e-16, 2.52812366400000000e-11,
  335. -7.61758780540030000e-7, 3.24027018268385747e-3,
  336. -6.61443934134543253e-1, 6.48358770605264921e-1);
  337. c1 : array[0..4] of ArbFloat =
  338. ( 1.13857200000000000e-14, -9.42421298160000000e-10,
  339. 1.58870192399321300e-5, -2.91755248061542077e-2,
  340. 1.28799409885767762e+0);
  341. d1 : array[0..13] of ArbFloat =
  342. ( 1.00090702627808217e+0, 8.98804941670557880e-4,
  343. -7.95969469843846000e-6, 2.45367662227560000e-7,
  344. -1.47085129889600000e-8, 1.36030580128000000e-9,
  345. -1.71310758400000000e-10, 2.72040729600000000e-11,
  346. -5.19113984000000000e-12, 1.14622464000000000e-12,
  347. -2.63372800000000000e-13, 6.86387200000000000e-14,
  348. -3.54508800000000000e-14, 1.24928000000000000e-14);
  349. d2 : array[0..15] of ArbFloat =
  350. ( 4.67768740274489776e-2, -9.62145882205441600e-5,
  351. 1.82120185123076000e-6, -8.29196070929200000e-8,
  352. 6.42013250344000000e-9, -7.15110504800000000e-10,
  353. 1.03950931840000000e-10, -1.85248000000000000e-11,
  354. 3.87554432000000000e-12, -9.23228160000000000e-13,
  355. 2.50224640000000000e-13, -7.43936000000000000e-14,
  356. 1.75718400000000000e-14, -4.83328000000000000e-15,
  357. 5.32480000000000000e-15, -2.29376000000000000e-15);
  358. var t, g, y, t2, a, b, c, cx, sx : ArbFloat;
  359. i, bov : ArbInt;
  360. begin
  361. t:=abs(x);
  362. if t<xvsmall
  363. then
  364. spebj1:=x/2
  365. else
  366. if t<=8
  367. then
  368. begin
  369. t:=0.03125*sqr(t)-1; t2:=2*t;
  370. b:=0; c:=0;
  371. bov:=sizeof(a1) div sizeof(ArbFloat) - 1;
  372. for i:=0 to bov do
  373. begin
  374. a:=t2*c-b+a1[i];
  375. if i<bov
  376. then
  377. begin
  378. b:=t2*a-c+b1[i];
  379. c:=t2*b-a+c1[i]
  380. end
  381. else
  382. spebj1:=(x/8)*(t*a-c+b1[i])
  383. end {i}
  384. end {abs(x)<=8}
  385. else
  386. begin
  387. g:=t-1.5/tbpi; y:=sqrt(tbpi/t)*spesgn(x);
  388. cx:=cos(g)*y; sx:=-sin(g)*y*8/t;
  389. t:=128/sqr(t)-1;
  390. spebj1:=cx*spepol(t, d1[0], sizeof(d1) div sizeof(ArbFloat) - 1)
  391. + sx*spepol(t, d2[0], sizeof(d2) div sizeof(ArbFloat) - 1)
  392. end {abs(x)>8}
  393. end {spebj1};
  394. function spebk0(x: ArbFloat): ArbFloat;
  395. const
  396. egam = 0.57721566490153286;
  397. xvsmall = 3.2e-9;
  398. highexp = 745;
  399. a0: array[0..7] of ArbFloat =
  400. ( 1.12896092945412762e+0, 1.32976966478338191e-1,
  401. 4.07157485171389048e-3, 5.59702338227915383e-5,
  402. 4.34562671546158210e-7, 2.16382411824721532e-9,
  403. 7.49110736894134794e-12, 1.90674197514561280e-14);
  404. a1: array[0..8] of ArbFloat =
  405. ( 2.61841879258687055e-1, 1.52436921799395196e-1,
  406. 6.63513979313943827e-3, 1.09534292632401542e-4,
  407. 9.57878493265929443e-7, 5.19906865800665633e-9,
  408. 1.92405264219706684e-11, 5.16867886946332160e-14,
  409. 1.05407718191360000e-16);
  410. a2: array[0..22] of ArbFloat =
  411. ( 9.58210053294896496e-1, -1.42477910128828254e-1,
  412. 3.23582010649653009e-2, -8.27780350351692662e-3,
  413. 2.24709729617770471e-3, -6.32678357460594866e-4,
  414. 1.82652460089342789e-4, -5.37101208898441760e-5,
  415. 1.60185974149720562e-5, -4.83134250336922161e-6,
  416. 1.47055796078231691e-6, -4.51017292375200017e-7,
  417. 1.39217270224614153e-7, -4.32185089841834127e-8,
  418. 1.34790467361340101e-8, -4.20597329258249948e-9,
  419. 1.32069362385968867e-9, -4.33326665618780914e-10,
  420. 1.37999268074442719e-10, -3.19241059198852137e-11,
  421. 9.74410152270679245e-12, -7.83738609108569293e-12,
  422. 2.57466288575820595e-12);
  423. a3: array[0..22] of ArbFloat =
  424. ( 6.97761598043851776e-1, -1.08801882084935132e-1,
  425. 2.56253646031960321e-2, -6.74459607940169198e-3,
  426. 1.87292939725962385e-3, -5.37145622971910027e-4,
  427. 1.57451516235860573e-4, -4.68936653814896712e-5,
  428. 1.41376509343622727e-5, -4.30373871727268511e-6,
  429. 1.32052261058932425e-6, -4.07851207862189007e-7,
  430. 1.26672629417567360e-7, -3.95403255713518420e-8,
  431. 1.23923137898346852e-8, -3.88349705250555658e-9,
  432. 1.22424982779432970e-9, -4.03424607871960089e-10,
  433. 1.28905587479980147e-10,-2.97787564633235128e-11,
  434. 9.11109430833001267e-12,-7.39672783987933184e-12,
  435. 2.43538242247537459e-12);
  436. a4: array[0..16] of ArbFloat =
  437. ( 1.23688664769425422e+0, -1.72683652385321641e-2,
  438. -9.25551464765637133e-4, -9.02553345187404564e-5,
  439. -6.31692398333746470e-6, -7.69177622529272933e-7,
  440. -4.16044811174114579e-8, -9.41555321137176073e-9,
  441. 1.75359321273580603e-10, -2.22829582288833265e-10,
  442. 3.49564293256545992e-11, -1.11391758572647639e-11,
  443. 2.85481235167705907e-12, -7.31344482663931904e-13,
  444. 2.06328892562554880e-13, -1.28108310826991616e-13,
  445. 4.43741979886551040e-14);
  446. var t: ArbFloat;
  447. begin
  448. if x<=0
  449. then
  450. RunError(401);
  451. if x<=xvsmall
  452. then
  453. spebk0:=-(ln(x/2)+egam)
  454. else
  455. if x<=1
  456. then
  457. begin
  458. t:=2*sqr(x)-1;
  459. spebk0:=-ln(x)*spepol(t, a0[0], sizeof(a0) div sizeof(ArbFloat) - 1)
  460. + spepol(t, a1[0], sizeof(a1) div sizeof(ArbFloat) - 1)
  461. end
  462. else
  463. if x<=2
  464. then
  465. spebk0:=exp(-x)*spepol(2*x-3, a2[0], sizeof(a2) div sizeof(ArbFloat) - 1)
  466. else
  467. if x<=4
  468. then
  469. spebk0:=exp(-x)*spepol(x-3, a3[0], sizeof(a3) div sizeof(ArbFloat) - 1)
  470. else
  471. if x <= highexp
  472. then
  473. spebk0:=exp(-x)*
  474. spepol(10/(1+x)-1, a4[0], sizeof(a4) div sizeof(ArbFloat) - 1)/sqrt(x)
  475. else
  476. spebk0:=0
  477. end; {spebk0}
  478. function spebk1(x: ArbFloat): ArbFloat;
  479. const
  480. xsmall = 7.9e-10;
  481. highexp = 745;
  482. a0: array[0..7] of ArbFloat =
  483. ( 5.31907865913352762e-1, 3.25725988137110495e-2,
  484. 6.71642805873498653e-4, 6.95300274548206237e-6,
  485. 4.32764823642997753e-8, 1.79784792380155752e-10,
  486. 5.33888268665658944e-13, 1.18964962439910400e-15);
  487. a1: array[0..7] of ArbFloat =
  488. ( 3.51825828289325536e-1, 4.50490442966943726e-2,
  489. 1.20333585658219028e-3, 1.44612432533006139e-5,
  490. 9.96686689273781531e-8, 4.46828628435618679e-10,
  491. 1.40917103024514301e-12, 3.29881058019865600e-15);
  492. a2: array[0..23] of ArbFloat =
  493. ( 1.24316587355255299e+0, -2.71910714388689413e-1,
  494. 8.20250220860693888e-2, -2.62545818729427417e-2,
  495. 8.57388087067410089e-3, -2.82450787841655951e-3,
  496. 9.34594154387642940e-4, -3.10007681013626626e-4,
  497. 1.02982746700060730e-4, -3.42424912211942134e-5,
  498. 1.13930169202553526e-5, -3.79227698821142908e-6,
  499. 1.26265578331941923e-6, -4.20507152338934956e-7,
  500. 1.40138351985185509e-7, -4.66928912168020101e-8,
  501. 1.54456653909012693e-8, -5.13783508140332214e-9,
  502. 1.82808381381205361e-9, -6.15211416898895086e-10,
  503. 1.28044023949946257e-10, -4.02591066627023831e-11,
  504. 4.27404330568767242e-11, -1.46639291782948454e-11);
  505. a3: array[0..23] of ArbFloat =
  506. ( 8.06563480128786903e-1, -1.60052611291327173e-1,
  507. 4.58591528414023064e-2, -1.42363136684423646e-2,
  508. 4.55865751206724687e-3, -1.48185472032688523e-3,
  509. 4.85707174778663652e-4, -1.59994873621599146e-4,
  510. 5.28712919123131781e-5, -1.75089594354079944e-5,
  511. 5.80692311842296724e-6, -1.92794586996432593e-6,
  512. 6.40581814037398274e-7, -2.12969229346310343e-7,
  513. 7.08723366696569880e-8, -2.35855618461025265e-8,
  514. 7.79421651144832709e-9, -2.59039399308009059e-9,
  515. 9.20781685906110546e-10, -3.09667392343245062e-10,
  516. 6.44913423545894175e-11, -2.02680401514735862e-11,
  517. 2.14736751065133220e-11, -7.36478297050421658e-12);
  518. a4: array[0..16] of ArbFloat =
  519. ( 1.30387573604230402e+0, 5.44845254318931612e-2,
  520. 4.31639434283445364e-3, 4.29973970898766831e-4,
  521. 4.04720631528495020e-5, 4.32776409784235211e-6,
  522. 4.07563856931843484e-7, 4.86651420008153956e-8,
  523. 3.82717692121438315e-9, 6.77688943857588882e-10,
  524. 6.97075379117731379e-12, 1.72026097285930936e-11,
  525. -2.60774502020271104e-12, 8.58211523713560576e-13,
  526. -2.19287104441802752e-13, 1.39321122940600320e-13,
  527. -4.77850238111580160e-14);
  528. var t: ArbFloat;
  529. begin
  530. if x<=0
  531. then
  532. RunError(402);
  533. if x<=xsmall
  534. then
  535. spebk1:=1/x
  536. else
  537. if x<=1
  538. then
  539. begin
  540. t:=2*sqr(x)-1;
  541. spebk1:=( ln(x)*spepol(t, a0[0], sizeof(a0) div sizeof(ArbFloat) - 1)
  542. -spepol(t, a1[0], sizeof(a1) div sizeof(ArbFloat) -1) )*x + 1/x
  543. end
  544. else
  545. if x<=2
  546. then
  547. spebk1:=exp(-x)*spepol(2*x-3, a2[0], sizeof(a2) div sizeof(ArbFloat) - 1)
  548. else
  549. if x<=4
  550. then
  551. spebk1:=exp(-x)*spepol(x-3, a3[0], sizeof(a3) div sizeof(ArbFloat) - 1)
  552. else
  553. if x <= highexp
  554. then
  555. spebk1:=exp(-x)*spepol(10/(1+x)-1, a4[0],
  556. sizeof(a4) div sizeof(ArbFloat) - 1)/sqrt(x)
  557. else
  558. spebk1:=0
  559. end; {spebk1}
  560. function speby0(x: ArbFloat): ArbFloat;
  561. const
  562. tbpi = 6.36619772367581343e-1;
  563. egam = 5.77215664901532861e-1;
  564. xvsmall = 3.2e-9;
  565. a1 : array[0..5] of ArbFloat =
  566. ( 3.90000000000000000e-19, -8.74734100000000000e-14,
  567. 5.24879478733000000e-9, -5.63207914105698700e-5,
  568. 4.71966895957633869e-2, 1.79034314077182663e-1);
  569. b1 : array[0..5] of ArbFloat =
  570. ( -2.69800000000000000e-17, 4.02633082000000000e-12,
  571. -1.44072332740190000e-7, 7.53113593257774230e-4,
  572. -1.77302012781143582e-1, -2.74474305529745265e-1);
  573. c1 : array[0..5] of ArbFloat =
  574. ( 1.64349000000000000e-15, -1.58375525420000000e-10,
  575. 3.20653253765480000e-6, -7.28796247955207918e-3,
  576. 2.61567346255046637e-1, -3.31461132032849417e-2);
  577. d1 : array[0..13] of ArbFloat =
  578. ( 9.99457275788251954e-1, -5.36367319213004570e-4,
  579. 6.13741608010926000e-6, -2.05274481565160000e-7,
  580. 1.28037614434400000e-8, -1.21211819632000000e-9,
  581. 1.55005642880000000e-10,-2.48827276800000000e-11,
  582. 4.78702080000000000e-12,-1.06365696000000000e-12,
  583. 2.45294080000000000e-13,-6.41843200000000000e-14,
  584. 3.34028800000000000e-14,-1.17964800000000000e-14);
  585. d2 : array[0..16] of ArbFloat =
  586. (-1.55551138795135187e-2, 6.83314909934390000e-5,
  587. -1.47713883264594000e-6, 7.10621485930000000e-8,
  588. -5.66871613024000000e-9, 6.43278173280000000e-10,
  589. -9.47034774400000000e-11, 1.70330918400000000e-11,
  590. -3.59094272000000000e-12, 8.59855360000000000e-13,
  591. -2.28807680000000000e-13, 6.95193600000000000e-14,
  592. -2.27942400000000000e-14, 4.75136000000000000e-15,
  593. -1.14688000000000000e-15, 2.12992000000000000e-15,
  594. -9.83040000000000000e-16);
  595. var t, g, y, t2, a, b, c, cx, sx : ArbFloat;
  596. i, bov : ArbInt;
  597. begin
  598. if x<=0
  599. then
  600. RunError(403);
  601. if x<=xvsmall
  602. then
  603. speby0:=(ln(x/2)+egam)*tbpi
  604. else
  605. if x<=8
  606. then
  607. begin
  608. t:=0.03125*sqr(x)-1; t2:=2*t;
  609. b:=0; c:=0;
  610. bov:=sizeof(a1) div sizeof(ArbFloat) - 1;
  611. for i:=0 to bov do
  612. begin
  613. a:=t2*c-b+a1[i];
  614. b:=t2*a-c+b1[i];
  615. if i<bov
  616. then
  617. c:=t2*b-a+c1[i]
  618. else
  619. speby0:=t*b-a+c1[i]+tbpi*spebj0(x)*ln(x)
  620. end {i}
  621. end {x<=8}
  622. else
  623. begin
  624. g:=x-1/(2*tbpi); y:=sqrt(tbpi/x);
  625. cx:=cos(g)*y*8/x; sx:=sin(g)*y;
  626. t:=128/sqr(x)-1;
  627. speby0:=sx*spepol(t, d1[0], sizeof(d1) div sizeof(ArbFloat) - 1)
  628. + cx*spepol(t, d2[0], sizeof(d2) div sizeof(ArbFloat) - 1)
  629. end {x>8}
  630. end {speby0};
  631. function speby1(x: ArbFloat): ArbFloat;
  632. const
  633. tbpi = 6.36619772367581343e-1;
  634. xsmall = 7.9e-10;
  635. a1 : array[0..5] of ArbFloat =
  636. (-6.58000000000000000e-18, 1.21143321000000000e-12,
  637. -5.68844003991900000e-8, 4.40478629867099510e-4,
  638. -2.26624991556754924e-1, -1.28697384381350001e-1);
  639. b1 : array[0..5] of ArbFloat =
  640. ( 4.27730000000000000e-16,-5.17212147300000000e-11,
  641. 1.41662436449235000e-6, -5.13164116106108479e-3,
  642. 6.75615780772187667e-1, 2.03041058859342538e-2);
  643. c1 : array[0..4] of ArbFloat =
  644. (-2.44094900000000000e-14, 1.87547032473000000e-9,
  645. -2.83046401495148000e-5, 4.23191803533369041e-2,
  646. -7.67296362886645940e-1);
  647. d1 : array[0..13] of ArbFloat =
  648. ( 1.00090702627808217e+0, 8.98804941670557880e-4,
  649. -7.95969469843846000e-6, 2.45367662227560000e-7,
  650. -1.47085129889600000e-8, 1.36030580128000000e-9,
  651. -1.71310758400000000e-10, 2.72040729600000000e-11,
  652. -5.19113984000000000e-12, 1.14622464000000000e-12,
  653. -2.63372800000000000e-13, 6.86387200000000000e-14,
  654. -3.54508800000000000e-14, 1.24928000000000000e-14);
  655. d2 : array[0..15] of ArbFloat =
  656. ( 4.67768740274489776e-2, -9.62145882205441600e-5,
  657. 1.82120185123076000e-6, -8.29196070929200000e-8,
  658. 6.42013250344000000e-9, -7.15110504800000000e-10,
  659. 1.03950931840000000e-10,-1.85248000000000000e-11,
  660. 3.87554432000000000e-12,-9.23228160000000000e-13,
  661. 2.50224640000000000e-13,-7.43936000000000000e-14,
  662. 1.75718400000000000e-14,-4.83328000000000000e-15,
  663. 5.32480000000000000e-15,-2.29376000000000000e-15);
  664. var t, g, y, t2, a, b, c, cx, sx : ArbFloat;
  665. i, bov : ArbInt;
  666. begin
  667. if x<=0
  668. then
  669. RunError(404);
  670. if x<=xsmall
  671. then
  672. speby1:=-tbpi/x
  673. else
  674. if x<=8
  675. then
  676. begin
  677. t:=0.03125*sqr(x)-1; t2:=2*t;
  678. b:=0; c:=0;
  679. bov:=sizeof(a1) div sizeof(ArbFloat) - 1;
  680. for i:=0 to bov do
  681. begin
  682. a:=t2*c-b+a1[i];
  683. if i<bov
  684. then
  685. begin
  686. b:=t2*a-c+b1[i];
  687. c:=t2*b-a+c1[i]
  688. end
  689. else
  690. if bov=3 {single}
  691. then
  692. begin
  693. b:=t2*a-c+b1[i];
  694. speby1:=(t*b-a+c1[i])*x/8 + spebj1(x)*ln(x)*tbpi - tbpi/x
  695. end
  696. else
  697. speby1:=(t*a-c+b1[i])*x/8 + spebj1(x)*ln(x)*tbpi - tbpi/x
  698. end {i}
  699. end {x<=8}
  700. else
  701. begin
  702. g:=x-3/(2*tbpi); y:=sqrt(tbpi/x);
  703. cx:=cos(g)*y*8/x; sx:=sin(g)*y;
  704. t:=128/sqr(x)-1;
  705. speby1:=sx*spepol(t, d1[0], sizeof(d1) div sizeof(ArbFloat) - 1)
  706. + cx*spepol(t, d2[0], sizeof(d2) div sizeof(ArbFloat) - 1)
  707. end {x>8}
  708. end {speby1};
  709. function speent(x : ArbFloat): longint;
  710. var tx : longint;
  711. begin
  712. tx:=trunc(x);
  713. if x>=0
  714. then
  715. speent:=tx
  716. else
  717. if x=tx
  718. then
  719. speent:=tx
  720. else
  721. speent:=tx-1
  722. end; {speent}
  723. function speerf(x : ArbFloat) : ArbFloat;
  724. const
  725. xup = 6.25;
  726. sqrtpi = 1.7724538509055160;
  727. c : array[1..18] of ArbFloat =
  728. ( 1.9449071068178803e0, 4.20186582324414e-2, -1.86866103976769e-2,
  729. 5.1281061839107e-3, -1.0683107461726e-3, 1.744737872522e-4,
  730. -2.15642065714e-5, 1.7282657974e-6, -2.00479241e-8,
  731. -1.64782105e-8, 2.0008475e-9, 2.57716e-11,
  732. -3.06343e-11, 1.9158e-12, 3.703e-13,
  733. -5.43e-14, -4.0e-15, 1.2e-15);
  734. d : array[1..17] of ArbFloat =
  735. ( 1.4831105640848036e0, -3.010710733865950e-1, 6.89948306898316e-2,
  736. -1.39162712647222e-2, 2.4207995224335e-3, -3.658639685849e-4,
  737. 4.86209844323e-5, -5.7492565580e-6, 6.113243578e-7,
  738. -5.89910153e-8, 5.2070091e-9, -4.232976e-10,
  739. 3.18811e-11, -2.2361e-12, 1.467e-13,
  740. -9.0e-15, 5.0e-16);
  741. var t, s, s1, s2, x2: ArbFloat;
  742. bovc, bovd, j: ArbInt;
  743. begin
  744. bovc:=sizeof(c) div sizeof(ArbFloat);
  745. bovd:=sizeof(d) div sizeof(ArbFloat);
  746. t:=abs(x);
  747. if t <= 2
  748. then
  749. begin
  750. x2:=sqr(x)-2;
  751. s1:=d[bovd]; s2:=0; j:=bovd-1;
  752. s:=x2*s1-s2+d[j];
  753. while j > 1 do
  754. begin
  755. s2:=s1; s1:=s; j:=j-1;
  756. s:=x2*s1-s2+d[j]
  757. end;
  758. speerf:=(s-s2)*x/2
  759. end
  760. else
  761. if t < xup
  762. then
  763. begin
  764. x2:=2-20/(t+3);
  765. s1:=c[bovc]; s2:=0; j:=bovc-1;
  766. s:=x2*s1-s2+c[j];
  767. while j > 1 do
  768. begin
  769. s2:=s1; s1:=s; j:=j-1;
  770. s:=x2*s1-s2+c[j]
  771. end;
  772. x2:=((s-s2)/(2*t))*exp(-sqr(x))/sqrtpi;
  773. speerf:=(1-x2)*spesgn(x)
  774. end
  775. else
  776. speerf:=spesgn(x)
  777. end; {speerf}
  778. function spemax(a, b: ArbFloat): ArbFloat;
  779. begin
  780. if a>b
  781. then
  782. spemax:=a
  783. else
  784. spemax:=b
  785. end; {spemax}
  786. function speefc(x : ArbFloat) : ArbFloat;
  787. const
  788. xlow = -6.25;
  789. xhigh = 27.28;
  790. c : array[0..22] of ArbFloat =
  791. ( 1.455897212750385e-1, -2.734219314954260e-1,
  792. 2.260080669166197e-1, -1.635718955239687e-1,
  793. 1.026043120322792e-1, -5.480232669380236e-2,
  794. 2.414322397093253e-2, -8.220621168415435e-3,
  795. 1.802962431316418e-3, -2.553523453642242e-5,
  796. -1.524627476123466e-4, 4.789838226695987e-5,
  797. 3.584014089915968e-6, -6.182369348098529e-6,
  798. 7.478317101785790e-7, 6.575825478226343e-7,
  799. -1.822565715362025e-7, -7.043998994397452e-8,
  800. 3.026547320064576e-8, 7.532536116142436e-9,
  801. -4.066088879757269e-9, -5.718639670776992e-10,
  802. 3.328130055126039e-10);
  803. var t, s : ArbFloat;
  804. begin
  805. if x <= xlow
  806. then
  807. speefc:=2
  808. else
  809. if x >= xhigh
  810. then
  811. speefc:=0
  812. else
  813. begin
  814. t:=1-7.5/(abs(x)+3.75);
  815. s:=exp(-x*x)*spepol(t, c[0], sizeof(c) div sizeof(ArbFloat) - 1);
  816. if x < 0
  817. then
  818. speefc:=2-s
  819. else
  820. speefc:=s
  821. end
  822. end {speefc};
  823. { N(x) = 1/sqrt(2 pi) int(-INF, x, exp(t^2/2) = (1 + erf(x/sqrt(2))) / 2 }
  824. function normaldist(x: ArbFloat): ArbFloat;
  825. begin
  826. Result := 0.5 * (1.0 + speerf(x / SQRT2));
  827. end;
  828. function invnormaldist(y: ArbFloat): ArbFloat;
  829. { Ref.: Moshier, "Methods and programs for mathematical function" }
  830. const
  831. P0: array[0..4] of ArbFloat = (
  832. -1.23916583867381258016,
  833. 13.9312609387279679503,
  834. -56.6762857469070293439,
  835. 98.0010754185999661536,
  836. -59.9633501014107895267);
  837. Q0: array[0..8] of ArbFloat = (
  838. -1.18331621121330003142,
  839. 15.9056225126211695515,
  840. -82.0372256168333339912,
  841. 200.260212380060660359,
  842. -225.462687854119370527,
  843. 86.3602421390890590575,
  844. 4.67627912898881538453,
  845. 1.95448858338141759834,
  846. 1.0);
  847. P1: array[0..8] of ArbFloat = (
  848. -8.57456785154685413611E-4,
  849. -3.50424626827848203418E-2,
  850. -1.40256079171354495875E-1,
  851. 2.18663306850790267539,
  852. 14.6849561928858024014,
  853. 44.0805073893200834700,
  854. 57.1628192246421288162,
  855. 31.5251094599893866154,
  856. 4.05544892305962419923);
  857. Q1: array[0..8] of Arbfloat = (
  858. -9.33259480895457427372E-4,
  859. -3.80806407691578277194E-2,
  860. -1.42182922854787788574E-1,
  861. 2.50464946208309415979,
  862. 15.0425385692907503408,
  863. 41.3172038254672030440,
  864. 45.3907635128879210584,
  865. 15.7799883256466749731,
  866. 1.0);
  867. P2: array[0..8] of ArbFloat = (
  868. 6.23974539184983293730E-9,
  869. 2.65806974686737550832E-6,
  870. 3.01581553508235416007E-4,
  871. 1.23716634817820021358E-2,
  872. 2.01485389549179081538E-1,
  873. 1.33303460815807542389,
  874. 3.93881025292474443415,
  875. 6.91522889068984211695,
  876. 3.23774891776946035970);
  877. Q2: array[0..8] of ArbFloat = (
  878. 6.79019408009981274425E-9,
  879. 2.89247864745380683936E-6,
  880. 3.28014464682127739104E-4,
  881. 1.34204006088543189037E-2,
  882. 2.16236993594496635890E-1,
  883. 1.37702099489081330271,
  884. 3.67983563856160859403,
  885. 6.02427039364742014255,
  886. 1.0);
  887. var
  888. x, x0, x1: ArbFloat;
  889. yy, y2: ArbFloat;
  890. z: ArbFloat;
  891. code: Integer;
  892. begin
  893. if y <= 0.0 then
  894. begin
  895. Result := -giant;
  896. exit;
  897. end;
  898. if y >= 1.0 then
  899. begin
  900. Result := +giant;
  901. exit;
  902. end;
  903. code := 1;
  904. yy := y;
  905. if yy > 1.0 - EXP_2 then begin // EXP_2 = exp(-2)
  906. yy := 1.0 - yy;
  907. code := 0;
  908. end;
  909. if yy > EXP_2 then begin
  910. yy := yy - 0.5;
  911. y2 := yy * yy;
  912. x := y2 * spepol(y2, P0[0], 4) / spepol(y2, Q0[0], 8);
  913. x := (yy + yy * x) * SQRT2PI; // SQRT2PI = sqrt(2*pi);
  914. Result := x;
  915. exit;
  916. end;
  917. x := sqrt(-2.0 * ln(yy));
  918. x0 := x - ln(x) / x;
  919. z := 1.0 / x;
  920. if x < 8.0 then
  921. x1 := z * spepol(z, P1[0], 8) / spepol(z, Q1[0], 8)
  922. else
  923. x1 := z * spepol(z, P2[0], 8) / spepol(z, Q2[0], 8);
  924. x := x0 - x1;
  925. if code <> 0 then
  926. x := -x;
  927. Result := x;
  928. end;
  929. function spegam(x: ArbFloat): ArbFloat;
  930. const
  931. tmax = 170;
  932. a: array[0..23] of ArbFloat =
  933. ( 8.86226925452758013e-1, 1.61691987244425092e-2,
  934. 1.03703363422075456e-1, -1.34118505705967765e-2,
  935. 9.04033494028101968e-3, -2.42259538436268176e-3,
  936. 9.15785997288933120e-4, -2.96890121633200000e-4,
  937. 1.00928148823365120e-4, -3.36375833240268800e-5,
  938. 1.12524642975590400e-5, -3.75499034136576000e-6,
  939. 1.25281466396672000e-6, -4.17808776355840000e-7,
  940. 1.39383522590720000e-7, -4.64774927155200000e-8,
  941. 1.53835215257600000e-8, -5.11961333760000000e-9,
  942. 1.82243164160000000e-9, -6.13513953280000000e-10,
  943. 1.27679856640000000e-10,-4.01499750400000000e-11,
  944. 4.26560716800000000e-11,-1.46381209600000000e-11);
  945. var tvsmall, t, g: ArbFloat;
  946. m, i: ArbInt;
  947. begin
  948. if sizeof(ArbFloat) = 6
  949. then
  950. tvsmall:=2*midget
  951. else
  952. tvsmall:=midget;
  953. t:=abs(x);
  954. if t > tmax
  955. then
  956. RunError(407);
  957. if t < macheps
  958. then
  959. begin
  960. if t < tvsmall
  961. then
  962. RunError(407);
  963. spegam:=1/x
  964. end
  965. else { abs(x) >= macheps }
  966. begin
  967. m:=trunc(x);
  968. if x > 0
  969. then
  970. begin
  971. t:=x-m; m:=m-1; g:=1;
  972. if m<0
  973. then
  974. g:=g/x
  975. else
  976. if m>0
  977. then
  978. for i:=1 to m do
  979. g:=(x-i)*g
  980. end
  981. else { x < 0 }
  982. begin
  983. t:=x-m+1;
  984. if t=1
  985. then
  986. RunError(407);
  987. m:=1-m;
  988. g:=x;
  989. for i:=1 to m do
  990. g:=(i+x)*g;
  991. g:=1/g
  992. end;
  993. spegam:=spepol(2*t-1, a[0], sizeof(a) div sizeof(ArbFloat) - 1)*g
  994. end { abs(x) >= macheps }
  995. end; {spegam}
  996. function spelga(x: ArbFloat): ArbFloat;
  997. const
  998. xbig = 7.7e7;
  999. xmax = 2.559e305;
  1000. lnr2pi = 9.18938533204672742e-1;
  1001. a: array[0..23] of ArbFloat =
  1002. ( 8.86226925452758013e-1, 1.61691987244425092e-2,
  1003. 1.03703363422075456e-1, -1.34118505705967765e-2,
  1004. 9.04033494028101968e-3, -2.42259538436268176e-3,
  1005. 9.15785997288933120e-4, -2.96890121633200000e-4,
  1006. 1.00928148823365120e-4, -3.36375833240268800e-5,
  1007. 1.12524642975590400e-5, -3.75499034136576000e-6,
  1008. 1.25281466396672000e-6, -4.17808776355840000e-7,
  1009. 1.39383522590720000e-7, -4.64774927155200000e-8,
  1010. 1.53835215257600000e-8, -5.11961333760000000e-9,
  1011. 1.82243164160000000e-9, -6.13513953280000000e-10,
  1012. 1.27679856640000000e-10,-4.01499750400000000e-11,
  1013. 4.26560716800000000e-11,-1.46381209600000000e-11);
  1014. b: array[0..5] of ArbFloat =
  1015. ( 8.33271644065786580e-2, -6.16502049453716986e-6,
  1016. 3.89978899876484712e-9, -6.45101975779653651e-12,
  1017. 2.00201927337982364e-14, -9.94561064728159347e-17);
  1018. var t, g : ArbFloat;
  1019. m, i : ArbInt;
  1020. begin
  1021. if x <= 0
  1022. then
  1023. RunError(408);
  1024. if x <= macheps
  1025. then
  1026. spelga:=-ln(x)
  1027. else
  1028. if x <= 15
  1029. then
  1030. begin
  1031. m:=trunc(x); t:=x-m; m:=m-1; g:=1;
  1032. if m < 0
  1033. then
  1034. g:=g/x
  1035. else
  1036. if m > 0
  1037. then
  1038. for i:=1 to m do
  1039. g:=(x-i)*g;
  1040. spelga:=ln(g*spepol(2*t-1, a[0], sizeof(a) div sizeof(ArbFloat) - 1))
  1041. end
  1042. else { x > 15 }
  1043. if x <= xbig
  1044. then
  1045. spelga:=(x-0.5)*ln(x) - x + lnr2pi
  1046. + spepol(450/sqr(x)-1, b[0], sizeof(b) div sizeof(ArbFloat) - 1)/x
  1047. else { x > xbig }
  1048. if x <= xmax
  1049. then
  1050. spelga:=(x-0.5)*ln(x) - x + lnr2pi
  1051. else { x > xmax => x*ln(x) > giant }
  1052. RunError(408)
  1053. end; {spelga}
  1054. { Implements power series expansion for lower incomplete gamma function
  1055. according to
  1056. https://en.wikipedia.org/wiki/Incomplete_gamma_function#Evaluation_formulae
  1057. gamma(s, x) = sum {k = 0 to inf, x^s exp(-x) x^k / (s (s+1) ... (s+k) ) }
  1058. Converges rapidly for x < s + 1 }
  1059. function gammaser(s, x: ArbFloat): ArbFloat;
  1060. const
  1061. MAX_IT = 100;
  1062. EPS = 1E-7;
  1063. var
  1064. delta: Arbfloat;
  1065. sum: ArbFloat;
  1066. k: Integer;
  1067. lngamma: ArbFloat;
  1068. begin
  1069. delta := 1 / s;
  1070. sum := delta;
  1071. for k := 1 to MAX_IT do begin
  1072. delta := delta * x / (s + k);
  1073. sum := sum + delta;
  1074. if delta < EPS then break;
  1075. end;
  1076. lngamma := spelga(s); // log of complete gamma(s)
  1077. Result := exp(s * ln(x) - x + ln(sum) - lngamma);
  1078. end;
  1079. type
  1080. TCFFunc = function(n: Integer): ArbFloat is nested;
  1081. { Calculates the continued fraction a0 + (b1 / (a1 + b2 / (a2 + b3 / (a3 + b4 /...))))
  1082. using convergents.
  1083. Ref.: http://lib.dr.iastate.edu/cgi/viewcontent.cgi?article=8639&context=rtd
  1084. nth convergent: wn = P(n)/Q(n).
  1085. P(n) = a(n) P(n-1) + b(n) P(n-2)
  1086. Q(n) = a(n) Q(n-1) + b(n) Q(n-2)
  1087. P(-1) = 1, P(0) = a(0), Q(-1) = 0, Q(0) = 1 }
  1088. function CalcCF(funca, funcb: TCfFunc; MaxIt: Integer; Eps: ArbFloat): ArbFloat;
  1089. var
  1090. Pn, Pn1, Pn2: ArbFloat;
  1091. Qn, Qn1, Qn2: ArbFloat;
  1092. it: Integer;
  1093. prev: ArbFloat;
  1094. a, b: ArbFloat;
  1095. begin
  1096. Pn2 := 1.0;
  1097. Pn1 := funca(0);
  1098. Qn2 := 0.0;
  1099. Qn1 := 1.0;
  1100. prev := Giant;
  1101. for it := 1 to MaxIt do begin
  1102. a := funca(it);
  1103. b := funcb(it);
  1104. Pn := a * Pn1 + b * Pn2;
  1105. Qn := a * Qn1 + b * Qn2;
  1106. Result := Pn/Qn;
  1107. if abs(Result - prev) < EPS * abs(Result) then
  1108. exit;
  1109. prev := Result;
  1110. Pn2 := Pn1;
  1111. Pn1 := Pn;
  1112. Qn2 := Qn1;
  1113. Qn1 := Qn;
  1114. end;
  1115. end;
  1116. { calculates the upper incomplete gamma function using its continued
  1117. fraction expansion
  1118. https://en.wikipedia.org/wiki/Incomplete_gamma_function#Connection_with_Kummer.27s_confluent_hypergeometric_function }
  1119. function gammacf(s, x: ArbFloat): ArbFloat;
  1120. function funca(i: Integer): ArbFloat;
  1121. begin
  1122. if i = 0 then
  1123. Result := 0
  1124. else
  1125. if odd(i) then
  1126. Result := x
  1127. else
  1128. Result := 1;
  1129. end;
  1130. function funcb(i: Integer): ArbFloat;
  1131. begin
  1132. if i = 1 then
  1133. Result := 1
  1134. else
  1135. if odd(i) then
  1136. Result := (i-1) div 2
  1137. else
  1138. Result := i div 2 - s;
  1139. end;
  1140. const
  1141. MAX_IT = 100;
  1142. EPS = 1E-7;
  1143. begin
  1144. Result := exp(-x + s*ln(x) - spelga(s)) * CalcCF(@funca, @funcb, MAX_IT, EPS);
  1145. end;
  1146. function gammap(s, x: ArbFloat): ArbFloat;
  1147. begin
  1148. if (x < 0.0) or (s <= 0.0) then
  1149. RunError(410); // Invalid argument of gammap
  1150. if x = 0.0 then
  1151. Result := 0.0
  1152. else if x < s + 1 then
  1153. Result := gammaser(s, x) // Use series expansion
  1154. else
  1155. Result := 1.0 - gammacf(s, x); // Use continued fraction
  1156. end;
  1157. function gammaq(s, x: ArbFloat): ArbFloat;
  1158. begin
  1159. if (x < 0.0) or (s <= 0.0) then
  1160. RunError(411); // Invalid argument of gammaq
  1161. if x = 0.0 then
  1162. Result := 1.0
  1163. else if x < s + 1 then
  1164. Result := 1.0 - gammaser(s, x) // Use series expansion
  1165. else
  1166. Result := gammacf(s, x); // Use continued fraction
  1167. end;
  1168. { Ref.: Moshier, "Methods and programs for mathematical functions" }
  1169. function invgammaq(s, y: ArbFloat): ArbFloat;
  1170. const
  1171. NUM_IT = 30;
  1172. var
  1173. d, y0, x0, xinit, lgm: ArbFloat;
  1174. it: Integer;
  1175. eps: ArbFloat;
  1176. begin
  1177. d := 1.0 / (9 * s);
  1178. y0 := invnormaldist(y);
  1179. if y0 = giant then
  1180. exit(0.0);
  1181. y0 := 1.0 - d - y0 * sqrt(d);
  1182. x0 := s * y0 * y0 * y0;
  1183. xinit := x0;
  1184. lgm := spelga(s);
  1185. eps := 2.0 * MachEps;
  1186. for it := 1 to NUM_IT do
  1187. begin
  1188. if (x0 <= 0.0) then // underflow
  1189. exit(0.0);
  1190. y0 := gammaq(s, x0);
  1191. d := (s - 1.0) * ln(x0) - x0 - lgm;
  1192. if d < -lnGiant then // underflow
  1193. break;
  1194. d := -exp(d);
  1195. if d = 0.0 then
  1196. break;
  1197. d := (y0 - y) / d;
  1198. x0 := x0 - d;
  1199. if it <= 3 then
  1200. continue;
  1201. if abs(d / x0) < eps then
  1202. break;
  1203. end;
  1204. Result := x0;
  1205. end;
  1206. { Calculates the complete beta function based on its property that
  1207. beta(a, b) = gamma(a) * gamma(b) / gamma(a+b)
  1208. https://en.wikipedia.org/wiki/Beta_function }
  1209. function beta(a, b: ArbFloat): ArbFloat;
  1210. begin
  1211. if (a <= 0) or (b <= 0) then
  1212. RunError(412);
  1213. Result := exp(spelga(a) + spelga(b) - spelga(a + b));
  1214. end;
  1215. { Calculates the continued fraction of the incomplete beta function.
  1216. Ref: https://www.encyclopediaofmath.org/index.php/Incomplete_beta-function }
  1217. function betaicf(a, b, x: ArbFloat): Arbfloat;
  1218. function funca(i: Integer): ArbFloat;
  1219. begin
  1220. if i = 0 then Result := 0.0 else Result := 1.0;
  1221. end;
  1222. function funcb(i: Integer): ArbFloat;
  1223. var
  1224. am: ArbFloat;
  1225. amm: ArbFloat;
  1226. m: Integer;
  1227. begin
  1228. if i = 1 then
  1229. Result := 1.0
  1230. else begin
  1231. m := (i-1) div 2;
  1232. am := a + m;
  1233. amm := am + m;
  1234. if odd(i) then
  1235. Result := m * (b - m) * x / ((amm - 1) * amm)
  1236. else
  1237. Result := -am * (am + b) * x / (amm * (amm + 1));
  1238. end;
  1239. end;
  1240. const
  1241. MAX_IT = 100;
  1242. EPS = 1E-7;
  1243. begin
  1244. Result := CalcCF(@funca, @funcb, MAX_IT, EPS);
  1245. end;
  1246. function betai(a, b, x: ArbFloat): ArbFloat;
  1247. var
  1248. factor: ArbFloat;
  1249. begin
  1250. // Check for invalid arguments
  1251. if (a <= 0) or (b <= 0) then
  1252. RunError(413);
  1253. if (x < 0) or (x > 1) then
  1254. RunError(414);
  1255. if (x = 0) or (x = 1) then
  1256. factor := 0
  1257. else
  1258. factor := exp(a * ln(x) + b * ln(1.0 - x) + spelga(a + b) - spelga(a) - spelga(b));
  1259. // The continued fraction expansion converges quickly only for
  1260. // x < (a + 1) / (a + b + 2)
  1261. // For the other case, we apply the relation
  1262. // beta(a, b, x) = 1 - beta(b, a, 1-x)
  1263. if x < (a + 1) / (a + b + 2) then
  1264. Result := factor * betaicf(a, b, x) / a
  1265. else
  1266. Result := 1.0 - factor * betaicf(b, a, 1.0 - x) / b;
  1267. end;
  1268. { Inverse of the incomplete beta function }
  1269. function invbetai(a, b, y: ArbFloat; eps: ArbFloat = 0.0): ArbFloat;
  1270. function _betai(x: ArbFloat): ArbFloat;
  1271. begin
  1272. Result := betai(a, b, x) - y;
  1273. end;
  1274. var
  1275. term: ArbInt = 0;
  1276. begin
  1277. if eps = 0.0 then
  1278. eps := MachEps;
  1279. roof1rn(@_betai, 0, 1, eps, eps, Result, term);
  1280. if term = 3 then
  1281. Result := NaN;
  1282. end;
  1283. function chi2dist(x: ArbFloat; n: ArbInt): ArbFloat;
  1284. begin
  1285. Result := gammaQ(0.5*n, 0.5*x);
  1286. end;
  1287. function invchi2dist(y: Arbfloat; n: ArbInt): ArbFloat;
  1288. begin
  1289. Result := 2.0 * invgammaQ(n/2, y);
  1290. // Result := 2.0 * invgammaQ_alglib(n/2, y);
  1291. end;
  1292. function tdist(t: ArbFloat; n: ArbInt; Tails: TNumTails): ArbFloat;
  1293. begin
  1294. Result := betai(0.5*n, 0.5, n/(n+t*t));
  1295. if Tails = 1 then Result := Result * 0.5;
  1296. end;
  1297. function invtdist(y: ArbFloat; n: ArbInt; Tails: TNumTails;
  1298. eps: ArbFloat = 0.0): ArbFloat;
  1299. var
  1300. w: ArbFloat;
  1301. begin
  1302. if (n <= 0) or (y <= 0) or (y >= 1) then
  1303. RunError(415);
  1304. if Tails = 2 then y := y * 0.5;
  1305. w := invbetai(0.5*n, 0.5, 2*y, eps);
  1306. Result := sqrt(n/w - n);
  1307. end;
  1308. // Calculates the F distribution with n1 and n2 degrees of freedom in the
  1309. // numerator and denominator, respectively
  1310. function Fdist(F: ArbFloat; n1, n2: ArbInt): ArbFloat;
  1311. begin
  1312. Result := betai(n2*0.5, n1*0.5, n2 / (n2 + n1*F));
  1313. end;
  1314. // Calculates the inverse of the F distribution
  1315. // Ref. Moshier, "Methods and programs for mathematical functions"
  1316. function invFdist(p: ArbFloat; n1, n2: ArbInt; eps: ArbFloat = 0.0): ArbFloat;
  1317. var
  1318. s: ArbFloat;
  1319. begin
  1320. if eps = 0.0 then eps := machEps;
  1321. s := invbetai(n2*0.5, n1*0.5, p, eps);
  1322. Result := n2 * (1-s) / (n1 * s);
  1323. end;
  1324. function spepol(x: ArbFloat; var a: ArbFloat; n: ArbInt): ArbFloat;
  1325. var pa : ^arfloat0;
  1326. i : ArbInt;
  1327. polx : ArbFloat;
  1328. begin
  1329. pa:=@a;
  1330. polx:=0;
  1331. for i:=n downto 0 do
  1332. polx:=polx*x+pa^[i];
  1333. spepol:=polx
  1334. end {spepol};
  1335. function spepow(a, b: ArbFloat): ArbFloat;
  1336. function PowInt(a: double; n: longint): double;
  1337. var a1 : double;
  1338. begin
  1339. if n=0 then PowInt := 1 else
  1340. begin
  1341. a1 := 1;
  1342. if n<0 then begin a := 1/a; n := -n end;
  1343. while n>0
  1344. do if Odd(n)
  1345. then begin Dec(n); a1 := a1*a end
  1346. else begin n := n div 2; a := sqr(a) end;
  1347. PowInt := a1
  1348. end
  1349. end;
  1350. var tb : longint;
  1351. fb : double;
  1352. begin
  1353. { (a < 0, b niet geheel) of (a = 0, b <= 0), dan afbreken}
  1354. if (a=0) then if (b<=0) then RunError(400) else begin SpePow :=0; exit end;
  1355. tb := Trunc(b); fb := b-tb;
  1356. if (a<0) and (fb<>0) then RunError(400);
  1357. if a>0
  1358. then if fb=0 then SpePow := PowInt(a, tb)
  1359. else SpePow := PowInt(a, tb)*exp(fb*ln(a))
  1360. else if odd(tb) then Spepow := -PowInt(-a, tb)
  1361. else SpePow := PowInt(-a, tb)
  1362. end; {spepow}
  1363. function spesgn(x: ArbFloat): ArbInt;
  1364. begin
  1365. if x<0
  1366. then
  1367. spesgn:=-1
  1368. else
  1369. if x=0
  1370. then
  1371. spesgn:=0
  1372. else
  1373. spesgn:=1
  1374. end; {spesgn}
  1375. function spears(x: ArbFloat): ArbFloat;
  1376. const
  1377. pi2 = 1.570796326794897;
  1378. a : array[0..17] of ArbFloat =
  1379. ( 1.047197551196598e+0, 5.375149359132719e-2, 7.798902238957732e-3,
  1380. 1.519668539582420e-3, 3.408637238430600e-4, 8.302317819598986e-5,
  1381. 2.134554822576075e-5, 5.701781046148566e-6, 1.566985123962741e-6,
  1382. 4.402076871418002e-7, 1.257811162594110e-7, 3.646577948300129e-8,
  1383. 1.081021746966715e-8, 3.212744286269388e-9, 8.515014302985799e-10,
  1384. 2.513296398553196e-10, 1.342121568282535e-10, 4.210346761190271e-11);
  1385. var y, u, t, s : ArbFloat;
  1386. uprang : boolean;
  1387. begin
  1388. if abs(x) > 1
  1389. then
  1390. RunError(411);
  1391. u:=sqr(x); uprang:= u > 0.5;
  1392. if uprang
  1393. then
  1394. u:=1-u;
  1395. t:=4*u-1; y:=spepol(t, a[0], sizeof(a) div sizeof(ArbFloat) - 1);
  1396. if uprang
  1397. then
  1398. begin
  1399. s:=pi2-sqrt(u)*y;
  1400. if x < 0
  1401. then
  1402. s:=-s;
  1403. spears:=s
  1404. end
  1405. else
  1406. spears:=x*y
  1407. end; {spears}
  1408. function spearc(x: ArbFloat): ArbFloat;
  1409. const
  1410. pi2 = 1.570796326794897;
  1411. a : array[0..17] of ArbFloat =
  1412. ( 1.047197551196598e+0, 5.375149359132719e-2, 7.798902238957732e-3,
  1413. 1.519668539582420e-3, 3.408637238430600e-4, 8.302317819598986e-5,
  1414. 2.134554822576075e-5, 5.701781046148566e-6, 1.566985123962741e-6,
  1415. 4.402076871418002e-7, 1.257811162594110e-7, 3.646577948300129e-8,
  1416. 1.081021746966715e-8, 3.212744286269388e-9, 8.515014302985799e-10,
  1417. 2.513296398553196e-10, 1.342121568282535e-10, 4.210346761190271e-11);
  1418. var u, t, y, s : ArbFloat;
  1419. uprang : boolean;
  1420. begin
  1421. if abs(x)>1.0
  1422. then
  1423. RunError(402);
  1424. u:=sqr(x); uprang:=u>0.5;
  1425. if uprang
  1426. then
  1427. u:=1-u;
  1428. t:=4*u-1; y:=spepol(t, a[0], sizeof(a) div sizeof(ArbFloat) - 1);
  1429. if uprang
  1430. then
  1431. begin
  1432. s:=sqrt(u)*y;
  1433. if x<0
  1434. then
  1435. s:=2*pi2-s;
  1436. spearc:=s
  1437. end
  1438. else
  1439. spearc:=pi2-x*y
  1440. end; {spearc}
  1441. function spesih(x: ArbFloat): ArbFloat;
  1442. const
  1443. a : array[0..6] of ArbFloat =
  1444. ( 1.085441641272607e+0, 8.757509762437522e-2, 2.158779361257021e-3,
  1445. 2.549839945498292e-5, 1.761854853281383e-7, 7.980704288665359e-10,
  1446. 2.551377137317034e-12);
  1447. var u : ArbFloat;
  1448. begin
  1449. if abs(x)<=1.0
  1450. then
  1451. begin
  1452. u:=2*sqr(x)-1;
  1453. spesih:=x*spepol(u, a[0], sizeof(a) div sizeof(ArbFloat) - 1)
  1454. end
  1455. else
  1456. begin
  1457. u:=exp(x); spesih:=(u-1/u)/2
  1458. end
  1459. end; {spesih}
  1460. function specoh(x: ArbFloat): ArbFloat;
  1461. var u: ArbFloat;
  1462. begin
  1463. u:=exp(x); specoh:=(u+1/u)/2
  1464. end; {specoh}
  1465. function spetah(x: ArbFloat): ArbFloat;
  1466. const
  1467. xhi = 18.50;
  1468. a : array[0..15] of ArbFloat =
  1469. ( 8.610571715805476e-1, -1.158834489728470e-1, 1.918072383973950e-2,
  1470. -3.225255180728459e-3, 5.433071386922689e-4, -9.154289983175165e-5,
  1471. 1.542469328074432e-5, -2.599022539340038e-6, 4.379282308765732e-7,
  1472. -7.378980192173815e-8, 1.243517352745986e-8, -2.095373768837420e-9,
  1473. 3.509758916273561e-10,-5.908745181531817e-11, 1.124199312776748e-11,
  1474. -1.907888434471600e-12);
  1475. var t, y: ArbFloat;
  1476. begin
  1477. t:=abs(x);
  1478. if t <= 1
  1479. then
  1480. begin
  1481. y:=2*sqr(x)-1;
  1482. spetah:=x*spepol(y, a[0], sizeof(a) div sizeof(ArbFloat) - 1)
  1483. end
  1484. else
  1485. if t < xhi
  1486. then
  1487. begin
  1488. y:=exp(2*x); spetah:=(y-1)/(y+1)
  1489. end
  1490. else
  1491. spetah:=spesgn(x)
  1492. end; {spetah}
  1493. function speash(x: ArbFloat): ArbFloat;
  1494. const
  1495. xhi = 1e9;
  1496. c : array[0..18] of ArbFloat =
  1497. ( 9.312298594527122e-1, -5.736663926249348e-2,
  1498. 9.004288574881897e-3, -1.833458667045431e-3,
  1499. 4.230023450529706e-4, -1.050715136470630e-4,
  1500. 2.740790473603819e-5, -7.402952157663977e-6,
  1501. 2.052474396638805e-6, -5.807433412373489e-7,
  1502. 1.670117348345774e-7, -4.863477336087045e-8,
  1503. 1.432753532351304e-8, -4.319978113584910e-9,
  1504. 1.299779213740398e-9, -3.394726871170490e-10,
  1505. 1.008344962167889e-10, -5.731943029121004e-11,
  1506. 1.810792296549804e-11);
  1507. var t : ArbFloat;
  1508. begin
  1509. t:=abs(x);
  1510. if t <= 1 then
  1511. speash:=x*spepol(2*sqr(x)-1, c[0], sizeof(c) div sizeof(ArbFloat) - 1)
  1512. else
  1513. if t < xhi then
  1514. speash:=ln(sqrt(sqr(x)+1)+t)*spesgn(x)
  1515. else
  1516. speash:=ln(2*t)*spesgn(x)
  1517. end; {speash}
  1518. function speach(x: ArbFloat): ArbFloat;
  1519. const
  1520. xhi = 1e9;
  1521. begin
  1522. if x<1 then
  1523. RunError(405);
  1524. if x=1 then
  1525. speach:=0
  1526. else
  1527. if x<=xhi then
  1528. speach:=ln(x+sqrt(sqr(x)-1))
  1529. else
  1530. speach:=ln(2*x)
  1531. end; {speach}
  1532. function speath(x: ArbFloat): ArbFloat;
  1533. const
  1534. c : array[0..19] of ArbFloat =
  1535. ( 1.098612288668110e+0, 1.173605223326117e-1, 2.309071936165689e-2,
  1536. 5.449091889986991e-3, 1.404884102286929e-3, 3.816948426588058e-4,
  1537. 1.073604335435426e-4, 3.095027782918129e-5, 9.088050814470148e-6,
  1538. 2.706881064641104e-6, 8.155200644023077e-7, 2.479830612463254e-7,
  1539. 7.588067811453948e-8, 2.339295963220429e-8, 7.408486568719348e-9,
  1540. 2.319454882064018e-9, 5.960921368486746e-10, 1.820410351379402e-10,
  1541. 1.184977617320312e-10, 3.856235316559190e-11);
  1542. var t, u: ArbFloat;
  1543. begin
  1544. t:=abs(x);
  1545. if t >= 1 then
  1546. RunError(406);
  1547. u:=sqr(x);
  1548. if u < 0.5 then
  1549. speath:=x*spepol(4*u-1, c[0], sizeof(c) div sizeof(ArbFloat) - 1)
  1550. else { 0.5 < x*x < 1 }
  1551. speath:=ln((1+t)/(1-t))/2*spesgn(x)
  1552. end; {speath}
  1553. var exitsave : pointer;
  1554. procedure MyExit;
  1555. {
  1556. const ErrorS : array[400..408,1..6] of char =
  1557. ('spepow',
  1558. 'spebk0',
  1559. 'spebk1',
  1560. 'speby0',
  1561. 'speby1',
  1562. 'speach',
  1563. 'speath',
  1564. 'spegam',
  1565. 'spelga'); }
  1566. //var ErrFil : text;
  1567. begin
  1568. ExitProc := ExitSave;
  1569. // Assign(ErrFil, 'CON');
  1570. // ReWrite(ErrFil);
  1571. if (ExitCode>=400) AND (ExitCode<=415) then
  1572. begin
  1573. // write(ErrFil, 'critical error in ', ErrorS[ExitCode]);
  1574. ExitCode := 201
  1575. end;
  1576. // Close(ErrFil)
  1577. end;
  1578. begin
  1579. ExitSave := ExitProc;
  1580. ExitProc := @MyExit;
  1581. end.