spe.pas 52 KB

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