gsl_specfunc__debye.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. /* specfunc/debye.c
  2. *
  3. * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. */
  19. /* Author: G. Jungman */
  20. /* augmented to n=5 and 6 2005-11-08 by R. J. Mathar, http://www.strw.leidenuniv.nl/~mathar */
  21. #include "gsl__config.h"
  22. #include "gsl_math.h"
  23. #include "gsl_errno.h"
  24. #include "gsl_sf_debye.h"
  25. #include "gsl_specfunc__error.h"
  26. #include "gsl_specfunc__check.h"
  27. #include "gsl_specfunc__chebyshev.h"
  28. #include "gsl_specfunc__cheb_eval.c"
  29. static double adeb1_data[17] = {
  30. 2.4006597190381410194,
  31. 0.1937213042189360089,
  32. -0.62329124554895770e-02,
  33. 0.3511174770206480e-03,
  34. -0.228222466701231e-04,
  35. 0.15805467875030e-05,
  36. -0.1135378197072e-06,
  37. 0.83583361188e-08,
  38. -0.6264424787e-09,
  39. 0.476033489e-10,
  40. -0.36574154e-11,
  41. 0.2835431e-12,
  42. -0.221473e-13,
  43. 0.17409e-14,
  44. -0.1376e-15,
  45. 0.109e-16,
  46. -0.9e-18
  47. };
  48. static cheb_series adeb1_cs = {
  49. adeb1_data,
  50. 16,
  51. -1.0, 1.0,
  52. 9
  53. };
  54. static double adeb2_data[18] = {
  55. 2.5943810232570770282,
  56. 0.2863357204530719834,
  57. -0.102062656158046713e-01,
  58. 0.6049109775346844e-03,
  59. -0.405257658950210e-04,
  60. 0.28633826328811e-05,
  61. -0.2086394303065e-06,
  62. 0.155237875826e-07,
  63. -0.11731280087e-08,
  64. 0.897358589e-10,
  65. -0.69317614e-11,
  66. 0.5398057e-12,
  67. -0.423241e-13,
  68. 0.33378e-14,
  69. -0.2645e-15,
  70. 0.211e-16,
  71. -0.17e-17,
  72. 0.1e-18
  73. };
  74. static cheb_series adeb2_cs = {
  75. adeb2_data,
  76. 17,
  77. -1.0, 1.0,
  78. 10
  79. };
  80. static double adeb3_data[17] = {
  81. 2.707737068327440945,
  82. 0.340068135211091751,
  83. -0.12945150184440869e-01,
  84. 0.7963755380173816e-03,
  85. -0.546360009590824e-04,
  86. 0.39243019598805e-05,
  87. -0.2894032823539e-06,
  88. 0.217317613962e-07,
  89. -0.16542099950e-08,
  90. 0.1272796189e-09,
  91. -0.987963460e-11,
  92. 0.7725074e-12,
  93. -0.607797e-13,
  94. 0.48076e-14,
  95. -0.3820e-15,
  96. 0.305e-16,
  97. -0.24e-17
  98. };
  99. static cheb_series adeb3_cs = {
  100. adeb3_data,
  101. 16,
  102. -1.0, 1.0,
  103. 10
  104. };
  105. static double adeb4_data[17] = {
  106. 2.781869415020523460,
  107. 0.374976783526892863,
  108. -0.14940907399031583e-01,
  109. 0.945679811437042e-03,
  110. -0.66132916138933e-04,
  111. 0.4815632982144e-05,
  112. -0.3588083958759e-06,
  113. 0.271601187416e-07,
  114. -0.20807099122e-08,
  115. 0.1609383869e-09,
  116. -0.125470979e-10,
  117. 0.9847265e-12,
  118. -0.777237e-13,
  119. 0.61648e-14,
  120. -0.4911e-15,
  121. 0.393e-16,
  122. -0.32e-17
  123. };
  124. static cheb_series adeb4_cs = {
  125. adeb4_data,
  126. 16,
  127. -1.0, 1.0,
  128. 10
  129. };
  130. static double adeb5_data[17] = {
  131. 2.8340269546834530149,
  132. 0.3994098857106266445,
  133. -0.164566764773099646e-1,
  134. 0.10652138340664541e-2,
  135. -0.756730374875418e-4,
  136. 0.55745985240273e-5,
  137. -0.4190692330918e-6,
  138. 0.319456143678e-7,
  139. -0.24613318171e-8,
  140. 0.1912801633e-9,
  141. -0.149720049e-10,
  142. 0.11790312e-11,
  143. -0.933329e-13,
  144. 0.74218e-14,
  145. -0.5925e-15,
  146. 0.475e-16,
  147. -0.39e-17
  148. };
  149. static cheb_series adeb5_cs = {
  150. adeb5_data,
  151. 16,
  152. -1.0, 1.0,
  153. 10
  154. };
  155. static double adeb6_data[17] = {
  156. 2.8726727134130122113,
  157. 0.4174375352339027746,
  158. -0.176453849354067873e-1,
  159. 0.11629852733494556e-2,
  160. -0.837118027357117e-4,
  161. 0.62283611596189e-5,
  162. -0.4718644465636e-6,
  163. 0.361950397806e-7,
  164. -0.28030368010e-8,
  165. 0.2187681983e-9,
  166. -0.171857387e-10,
  167. 0.13575809e-11,
  168. -0.1077580e-12,
  169. 0.85893e-14,
  170. -0.6872e-15,
  171. 0.552e-16,
  172. -0.44e-17
  173. };
  174. static cheb_series adeb6_cs = {
  175. adeb6_data,
  176. 16,
  177. -1.0, 1.0,
  178. 10
  179. };
  180. /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/
  181. int gsl_sf_debye_1_e(const double x, gsl_sf_result * result)
  182. {
  183. const double val_infinity = 1.64493406684822644;
  184. const double xcut = -GSL_LOG_DBL_MIN;
  185. /* CHECK_POINTER(result) */
  186. if(x < 0.0) {
  187. DOMAIN_ERROR(result);
  188. }
  189. else if(x < 2.0*GSL_SQRT_DBL_EPSILON) {
  190. result->val = 1.0 - 0.25*x + x*x/36.0;
  191. result->err = GSL_DBL_EPSILON * fabs(result->val);
  192. return GSL_SUCCESS;
  193. }
  194. else if(x <= 4.0) {
  195. const double t = x*x/8.0 - 1.0;
  196. gsl_sf_result c;
  197. cheb_eval_e(&adeb1_cs, t, &c);
  198. result->val = c.val - 0.25 * x;
  199. result->err = c.err + 0.25 * x * GSL_DBL_EPSILON;
  200. return GSL_SUCCESS;
  201. }
  202. else if(x < -(M_LN2 + GSL_LOG_DBL_EPSILON)) {
  203. const int nexp = floor(xcut/x);
  204. const double ex = exp(-x);
  205. double sum = 0.0;
  206. double xk = nexp * x;
  207. double rk = nexp;
  208. int i;
  209. for(i=nexp; i>=1; i--) {
  210. sum *= ex;
  211. sum += (1.0 + 1.0/xk)/rk;
  212. rk -= 1.0;
  213. xk -= x;
  214. }
  215. result->val = val_infinity/x - sum*ex;
  216. result->err = GSL_DBL_EPSILON * fabs(result->val);
  217. return GSL_SUCCESS;
  218. }
  219. else if(x < xcut) {
  220. result->val = (val_infinity - exp(-x)*(x+1.0)) / x;
  221. result->err = GSL_DBL_EPSILON * fabs(result->val);
  222. return GSL_SUCCESS;
  223. }
  224. else {
  225. result->val = val_infinity/x;
  226. result->err = GSL_DBL_EPSILON * fabs(result->val);
  227. return GSL_SUCCESS;
  228. }
  229. }
  230. int gsl_sf_debye_2_e(const double x, gsl_sf_result * result)
  231. {
  232. const double val_infinity = 4.80822761263837714;
  233. const double xcut = -GSL_LOG_DBL_MIN;
  234. /* CHECK_POINTER(result) */
  235. if(x < 0.0) {
  236. DOMAIN_ERROR(result);
  237. }
  238. else if(x < 2.0*M_SQRT2*GSL_SQRT_DBL_EPSILON) {
  239. result->val = 1.0 - x/3.0 + x*x/24.0;
  240. result->err = GSL_DBL_EPSILON * result->val;
  241. return GSL_SUCCESS;
  242. }
  243. else if(x <= 4.0) {
  244. const double t = x*x/8.0 - 1.0;
  245. gsl_sf_result c;
  246. cheb_eval_e(&adeb2_cs, t, &c);
  247. result->val = c.val - x/3.0;
  248. result->err = c.err + GSL_DBL_EPSILON * x/3.0;
  249. return GSL_SUCCESS;
  250. }
  251. else if(x < -(M_LN2 + GSL_LOG_DBL_EPSILON)) {
  252. const int nexp = floor(xcut/x);
  253. const double ex = exp(-x);
  254. double xk = nexp * x;
  255. double rk = nexp;
  256. double sum = 0.0;
  257. int i;
  258. for(i=nexp; i>=1; i--) {
  259. sum *= ex;
  260. sum += (1.0 + 2.0/xk + 2.0/(xk*xk)) / rk;
  261. rk -= 1.0;
  262. xk -= x;
  263. }
  264. result->val = val_infinity/(x*x) - 2.0 * sum * ex;
  265. result->err = GSL_DBL_EPSILON * fabs(result->val);
  266. return GSL_SUCCESS;
  267. }
  268. else if(x < xcut) {
  269. const double x2 = x*x;
  270. const double sum = 2.0 + 2.0*x + x2;
  271. result->val = (val_infinity - 2.0 * sum * exp(-x)) / x2;
  272. result->err = GSL_DBL_EPSILON * fabs(result->val);
  273. return GSL_SUCCESS;
  274. }
  275. else {
  276. result->val = (val_infinity/x)/x;
  277. result->err = GSL_DBL_EPSILON * result->val;
  278. CHECK_UNDERFLOW(result);
  279. return GSL_SUCCESS;
  280. }
  281. }
  282. int gsl_sf_debye_3_e(const double x, gsl_sf_result * result)
  283. {
  284. const double val_infinity = 19.4818182068004875;
  285. const double xcut = -GSL_LOG_DBL_MIN;
  286. /* CHECK_POINTER(result) */
  287. if(x < 0.0) {
  288. DOMAIN_ERROR(result);
  289. }
  290. else if(x < 2.0*M_SQRT2*GSL_SQRT_DBL_EPSILON) {
  291. result->val = 1.0 - 3.0*x/8.0 + x*x/20.0;
  292. result->err = GSL_DBL_EPSILON * result->val;
  293. return GSL_SUCCESS;
  294. }
  295. else if(x <= 4.0) {
  296. const double t = x*x/8.0 - 1.0;
  297. gsl_sf_result c;
  298. cheb_eval_e(&adeb3_cs, t, &c);
  299. result->val = c.val - 0.375*x;
  300. result->err = c.err + GSL_DBL_EPSILON * 0.375*x;
  301. return GSL_SUCCESS;
  302. }
  303. else if(x < -(M_LN2 + GSL_LOG_DBL_EPSILON)) {
  304. const int nexp = floor(xcut/x);
  305. const double ex = exp(-x);
  306. double xk = nexp * x;
  307. double rk = nexp;
  308. double sum = 0.0;
  309. int i;
  310. for(i=nexp; i>=1; i--) {
  311. double xk_inv = 1.0/xk;
  312. sum *= ex;
  313. sum += (((6.0*xk_inv + 6.0)*xk_inv + 3.0)*xk_inv + 1.0) / rk;
  314. rk -= 1.0;
  315. xk -= x;
  316. }
  317. result->val = val_infinity/(x*x*x) - 3.0 * sum * ex;
  318. result->err = GSL_DBL_EPSILON * result->val;
  319. return GSL_SUCCESS;
  320. }
  321. else if(x < xcut) {
  322. const double x3 = x*x*x;
  323. const double sum = 6.0 + 6.0*x + 3.0*x*x + x3;
  324. result->val = (val_infinity - 3.0 * sum * exp(-x)) / x3;
  325. result->err = GSL_DBL_EPSILON * result->val;
  326. return GSL_SUCCESS;
  327. }
  328. else {
  329. result->val = ((val_infinity/x)/x)/x;
  330. result->err = GSL_DBL_EPSILON * result->val;
  331. CHECK_UNDERFLOW(result);
  332. return GSL_SUCCESS;
  333. }
  334. }
  335. int gsl_sf_debye_4_e(const double x, gsl_sf_result * result)
  336. {
  337. const double val_infinity = 99.5450644937635129;
  338. const double xcut = -GSL_LOG_DBL_MIN;
  339. /* CHECK_POINTER(result) */
  340. if(x < 0.0) {
  341. DOMAIN_ERROR(result);
  342. }
  343. else if(x < 2.0*M_SQRT2*GSL_SQRT_DBL_EPSILON) {
  344. result->val = 1.0 - 2.0*x/5.0 + x*x/18.0;
  345. result->err = GSL_DBL_EPSILON * result->val;
  346. return GSL_SUCCESS;
  347. }
  348. else if(x <= 4.0) {
  349. const double t = x*x/8.0 - 1.0;
  350. gsl_sf_result c;
  351. cheb_eval_e(&adeb4_cs, t, &c);
  352. result->val = c.val - 2.0*x/5.0;
  353. result->err = c.err + GSL_DBL_EPSILON * 2.0*x/5.0;
  354. return GSL_SUCCESS;
  355. }
  356. else if(x < -(M_LN2 + GSL_LOG_DBL_EPSILON)) {
  357. const int nexp = floor(xcut/x);
  358. const double ex = exp(-x);
  359. double xk = nexp * x;
  360. double rk = nexp;
  361. double sum = 0.0;
  362. int i;
  363. for(i=nexp; i>=1; i--) {
  364. double xk_inv = 1.0/xk;
  365. sum *= ex;
  366. sum += ((((24.0*xk_inv + 24.0)*xk_inv + 12.0)*xk_inv + 4.0)*xk_inv + 1.0) / rk;
  367. rk -= 1.0;
  368. xk -= x;
  369. }
  370. result->val = val_infinity/(x*x*x*x) - 4.0 * sum * ex;
  371. result->err = GSL_DBL_EPSILON * result->val;
  372. return GSL_SUCCESS;
  373. }
  374. else if(x < xcut) {
  375. const double x2 = x*x;
  376. const double x4 = x2*x2;
  377. const double sum = 24.0 + 24.0*x + 12.0*x2 + 4.0*x2*x + x4;
  378. result->val = (val_infinity - 4.0 * sum * exp(-x)) / x4;
  379. result->err = GSL_DBL_EPSILON * result->val;
  380. return GSL_SUCCESS;
  381. }
  382. else {
  383. result->val = (((val_infinity/x)/x)/x)/x;
  384. result->err = GSL_DBL_EPSILON * result->val;
  385. CHECK_UNDERFLOW(result);
  386. return GSL_SUCCESS;
  387. }
  388. }
  389. int gsl_sf_debye_5_e(const double x, gsl_sf_result * result)
  390. {
  391. const double val_infinity = 610.405837190669483828710757875 ;
  392. const double xcut = -GSL_LOG_DBL_MIN;
  393. /* CHECK_POINTER(result) */
  394. if(x < 0.0) {
  395. DOMAIN_ERROR(result);
  396. }
  397. else if(x < 2.0*M_SQRT2*GSL_SQRT_DBL_EPSILON) {
  398. result->val = 1.0 - 5.0*x/12.0 + 5.0*x*x/84.0;
  399. result->err = GSL_DBL_EPSILON * result->val;
  400. return GSL_SUCCESS;
  401. }
  402. else if(x <= 4.0) {
  403. const double t = x*x/8.0 - 1.0;
  404. gsl_sf_result c;
  405. cheb_eval_e(&adeb5_cs, t, &c);
  406. result->val = c.val - 5.0*x/12.0;
  407. result->err = c.err + GSL_DBL_EPSILON * 5.0*x/12.0;
  408. return GSL_SUCCESS;
  409. }
  410. else if(x < -(M_LN2 + GSL_LOG_DBL_EPSILON)) {
  411. const int nexp = floor(xcut/x);
  412. const double ex = exp(-x);
  413. double xk = nexp * x;
  414. double rk = nexp;
  415. double sum = 0.0;
  416. int i;
  417. for(i=nexp; i>=1; i--) {
  418. double xk_inv = 1.0/xk;
  419. sum *= ex;
  420. sum += (((((120.0*xk_inv + 120.0)*xk_inv + 60.0)*xk_inv + 20.0)*xk_inv + 5.0)*xk_inv+ 1.0) / rk;
  421. rk -= 1.0;
  422. xk -= x;
  423. }
  424. result->val = val_infinity/(x*x*x*x*x) - 5.0 * sum * ex;
  425. result->err = GSL_DBL_EPSILON * result->val;
  426. return GSL_SUCCESS;
  427. }
  428. else if(x < xcut) {
  429. const double x2 = x*x;
  430. const double x4 = x2*x2;
  431. const double x5 = x4*x;
  432. const double sum = 120.0 + 120.0*x + 60.0*x2 + 20.0*x2*x + 5.0*x4 + x5;
  433. result->val = (val_infinity - 5.0 * sum * exp(-x)) / x5;
  434. result->err = GSL_DBL_EPSILON * result->val;
  435. return GSL_SUCCESS;
  436. }
  437. else {
  438. result->val = ((((val_infinity/x)/x)/x)/x)/x;
  439. result->err = GSL_DBL_EPSILON * result->val;
  440. CHECK_UNDERFLOW(result);
  441. return GSL_SUCCESS;
  442. }
  443. }
  444. int gsl_sf_debye_6_e(const double x, gsl_sf_result * result)
  445. {
  446. const double val_infinity = 4356.06887828990661194792541535 ;
  447. const double xcut = -GSL_LOG_DBL_MIN;
  448. /* CHECK_POINTER(result) */
  449. if(x < 0.0) {
  450. DOMAIN_ERROR(result);
  451. }
  452. else if(x < 2.0*M_SQRT2*GSL_SQRT_DBL_EPSILON) {
  453. result->val = 1.0 - 3.0*x/7.0 + x*x/16.0;
  454. result->err = GSL_DBL_EPSILON * result->val;
  455. return GSL_SUCCESS;
  456. }
  457. else if(x <= 4.0) {
  458. const double t = x*x/8.0 - 1.0;
  459. gsl_sf_result c;
  460. cheb_eval_e(&adeb6_cs, t, &c);
  461. result->val = c.val - 3.0*x/7.0;
  462. result->err = c.err + GSL_DBL_EPSILON * 3.0*x/7.0;
  463. return GSL_SUCCESS;
  464. }
  465. else if(x < -(M_LN2 + GSL_LOG_DBL_EPSILON)) {
  466. const int nexp = floor(xcut/x);
  467. const double ex = exp(-x);
  468. double xk = nexp * x;
  469. double rk = nexp;
  470. double sum = 0.0;
  471. int i;
  472. for(i=nexp; i>=1; i--) {
  473. double xk_inv = 1.0/xk;
  474. sum *= ex;
  475. sum += ((((((720.0*xk_inv + 720.0)*xk_inv + 360.0)*xk_inv + 120.0)*xk_inv + 30.0)*xk_inv+ 6.0)*xk_inv+ 1.0) / rk;
  476. rk -= 1.0;
  477. xk -= x;
  478. }
  479. result->val = val_infinity/(x*x*x*x*x*x) - 6.0 * sum * ex;
  480. result->err = GSL_DBL_EPSILON * result->val;
  481. return GSL_SUCCESS;
  482. }
  483. else if(x < xcut) {
  484. const double x2 = x*x;
  485. const double x4 = x2*x2;
  486. const double x6 = x4*x2;
  487. const double sum = 720.0 + 720.0*x + 360.0*x2 + 120.0*x2*x + 30.0*x4 + 6.0*x4*x +x6 ;
  488. result->val = (val_infinity - 6.0 * sum * exp(-x)) / x6;
  489. result->err = GSL_DBL_EPSILON * result->val;
  490. return GSL_SUCCESS;
  491. }
  492. else {
  493. result->val = (((((val_infinity/x)/x)/x)/x)/x)/x ;
  494. result->err = GSL_DBL_EPSILON * result->val;
  495. CHECK_UNDERFLOW(result);
  496. return GSL_SUCCESS;
  497. }
  498. }
  499. /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/
  500. #include "gsl_specfunc__eval.h"
  501. double gsl_sf_debye_1(const double x)
  502. {
  503. EVAL_RESULT(gsl_sf_debye_1_e(x, &result));
  504. }
  505. double gsl_sf_debye_2(const double x)
  506. {
  507. EVAL_RESULT(gsl_sf_debye_2_e(x, &result));
  508. }
  509. double gsl_sf_debye_3(const double x)
  510. {
  511. EVAL_RESULT(gsl_sf_debye_3_e(x, &result));
  512. }
  513. double gsl_sf_debye_4(const double x)
  514. {
  515. EVAL_RESULT(gsl_sf_debye_4_e(x, &result));
  516. }
  517. double gsl_sf_debye_5(const double x)
  518. {
  519. EVAL_RESULT(gsl_sf_debye_5_e(x, &result));
  520. }
  521. double gsl_sf_debye_6(const double x)
  522. {
  523. EVAL_RESULT(gsl_sf_debye_6_e(x, &result));
  524. }