gsl_specfunc__exp.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. /* specfunc/exp.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. #include "gsl__config.h"
  21. #include "gsl_math.h"
  22. #include "gsl_errno.h"
  23. #include "gsl_sf_gamma.h"
  24. #include "gsl_sf_exp.h"
  25. #include "gsl_specfunc__error.h"
  26. /* Evaluate the continued fraction for exprel.
  27. * [Abramowitz+Stegun, 4.2.41]
  28. */
  29. static
  30. int
  31. exprel_n_CF(const int N, const double x, gsl_sf_result * result)
  32. {
  33. const double RECUR_BIG = GSL_SQRT_DBL_MAX;
  34. const int maxiter = 5000;
  35. int n = 1;
  36. double Anm2 = 1.0;
  37. double Bnm2 = 0.0;
  38. double Anm1 = 0.0;
  39. double Bnm1 = 1.0;
  40. double a1 = 1.0;
  41. double b1 = 1.0;
  42. double a2 = -x;
  43. double b2 = N+1;
  44. double an, bn;
  45. double fn;
  46. double An = b1*Anm1 + a1*Anm2; /* A1 */
  47. double Bn = b1*Bnm1 + a1*Bnm2; /* B1 */
  48. /* One explicit step, before we get to the main pattern. */
  49. n++;
  50. Anm2 = Anm1;
  51. Bnm2 = Bnm1;
  52. Anm1 = An;
  53. Bnm1 = Bn;
  54. An = b2*Anm1 + a2*Anm2; /* A2 */
  55. Bn = b2*Bnm1 + a2*Bnm2; /* B2 */
  56. fn = An/Bn;
  57. while(n < maxiter) {
  58. double old_fn;
  59. double del;
  60. n++;
  61. Anm2 = Anm1;
  62. Bnm2 = Bnm1;
  63. Anm1 = An;
  64. Bnm1 = Bn;
  65. an = ( GSL_IS_ODD(n) ? ((n-1)/2)*x : -(N+(n/2)-1)*x );
  66. bn = N + n - 1;
  67. An = bn*Anm1 + an*Anm2;
  68. Bn = bn*Bnm1 + an*Bnm2;
  69. if(fabs(An) > RECUR_BIG || fabs(Bn) > RECUR_BIG) {
  70. An /= RECUR_BIG;
  71. Bn /= RECUR_BIG;
  72. Anm1 /= RECUR_BIG;
  73. Bnm1 /= RECUR_BIG;
  74. Anm2 /= RECUR_BIG;
  75. Bnm2 /= RECUR_BIG;
  76. }
  77. old_fn = fn;
  78. fn = An/Bn;
  79. del = old_fn/fn;
  80. if(fabs(del - 1.0) < 2.0*GSL_DBL_EPSILON) break;
  81. }
  82. result->val = fn;
  83. result->err = 2.0*(n+1.0)*GSL_DBL_EPSILON*fabs(fn);
  84. if(n == maxiter)
  85. GSL_ERROR ("error", GSL_EMAXITER);
  86. else
  87. return GSL_SUCCESS;
  88. }
  89. /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/
  90. int gsl_sf_exp_e(const double x, gsl_sf_result * result)
  91. {
  92. if(x > GSL_LOG_DBL_MAX) {
  93. OVERFLOW_ERROR(result);
  94. }
  95. else if(x < GSL_LOG_DBL_MIN) {
  96. UNDERFLOW_ERROR(result);
  97. }
  98. else {
  99. result->val = exp(x);
  100. result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  101. return GSL_SUCCESS;
  102. }
  103. }
  104. int gsl_sf_exp_e10_e(const double x, gsl_sf_result_e10 * result)
  105. {
  106. if(x > INT_MAX-1) {
  107. OVERFLOW_ERROR_E10(result);
  108. }
  109. else if(x < INT_MIN+1) {
  110. UNDERFLOW_ERROR_E10(result);
  111. }
  112. else {
  113. const int N = (int) floor(x/M_LN10);
  114. result->val = exp(x-N*M_LN10);
  115. result->err = 2.0 * (fabs(x)+1.0) * GSL_DBL_EPSILON * fabs(result->val);
  116. result->e10 = N;
  117. return GSL_SUCCESS;
  118. }
  119. }
  120. int gsl_sf_exp_mult_e(const double x, const double y, gsl_sf_result * result)
  121. {
  122. const double ay = fabs(y);
  123. if(y == 0.0) {
  124. result->val = 0.0;
  125. result->err = 0.0;
  126. return GSL_SUCCESS;
  127. }
  128. else if( ( x < 0.5*GSL_LOG_DBL_MAX && x > 0.5*GSL_LOG_DBL_MIN)
  129. && (ay < 0.8*GSL_SQRT_DBL_MAX && ay > 1.2*GSL_SQRT_DBL_MIN)
  130. ) {
  131. const double ex = exp(x);
  132. result->val = y * ex;
  133. result->err = (2.0 + fabs(x)) * GSL_DBL_EPSILON * fabs(result->val);
  134. return GSL_SUCCESS;
  135. }
  136. else {
  137. const double ly = log(ay);
  138. const double lnr = x + ly;
  139. if(lnr > GSL_LOG_DBL_MAX - 0.01) {
  140. OVERFLOW_ERROR(result);
  141. }
  142. else if(lnr < GSL_LOG_DBL_MIN + 0.01) {
  143. UNDERFLOW_ERROR(result);
  144. }
  145. else {
  146. const double sy = GSL_SIGN(y);
  147. const double M = floor(x);
  148. const double N = floor(ly);
  149. const double a = x - M;
  150. const double b = ly - N;
  151. const double berr = 2.0 * GSL_DBL_EPSILON * (fabs(ly) + fabs(N));
  152. result->val = sy * exp(M+N) * exp(a+b);
  153. result->err = berr * fabs(result->val);
  154. result->err += 2.0 * GSL_DBL_EPSILON * (M + N + 1.0) * fabs(result->val);
  155. return GSL_SUCCESS;
  156. }
  157. }
  158. }
  159. int gsl_sf_exp_mult_e10_e(const double x, const double y, gsl_sf_result_e10 * result)
  160. {
  161. const double ay = fabs(y);
  162. if(y == 0.0) {
  163. result->val = 0.0;
  164. result->err = 0.0;
  165. result->e10 = 0;
  166. return GSL_SUCCESS;
  167. }
  168. else if( ( x < 0.5*GSL_LOG_DBL_MAX && x > 0.5*GSL_LOG_DBL_MIN)
  169. && (ay < 0.8*GSL_SQRT_DBL_MAX && ay > 1.2*GSL_SQRT_DBL_MIN)
  170. ) {
  171. const double ex = exp(x);
  172. result->val = y * ex;
  173. result->err = (2.0 + fabs(x)) * GSL_DBL_EPSILON * fabs(result->val);
  174. result->e10 = 0;
  175. return GSL_SUCCESS;
  176. }
  177. else {
  178. const double ly = log(ay);
  179. const double l10_val = (x + ly)/M_LN10;
  180. if(l10_val > INT_MAX-1) {
  181. OVERFLOW_ERROR_E10(result);
  182. }
  183. else if(l10_val < INT_MIN+1) {
  184. UNDERFLOW_ERROR_E10(result);
  185. }
  186. else {
  187. const double sy = GSL_SIGN(y);
  188. const int N = (int) floor(l10_val);
  189. const double arg_val = (l10_val - N) * M_LN10;
  190. const double arg_err = 2.0 * GSL_DBL_EPSILON * fabs(ly);
  191. result->val = sy * exp(arg_val);
  192. result->err = arg_err * fabs(result->val);
  193. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  194. result->e10 = N;
  195. return GSL_SUCCESS;
  196. }
  197. }
  198. }
  199. int gsl_sf_exp_mult_err_e(const double x, const double dx,
  200. const double y, const double dy,
  201. gsl_sf_result * result)
  202. {
  203. const double ay = fabs(y);
  204. if(y == 0.0) {
  205. result->val = 0.0;
  206. result->err = fabs(dy * exp(x));
  207. return GSL_SUCCESS;
  208. }
  209. else if( ( x < 0.5*GSL_LOG_DBL_MAX && x > 0.5*GSL_LOG_DBL_MIN)
  210. && (ay < 0.8*GSL_SQRT_DBL_MAX && ay > 1.2*GSL_SQRT_DBL_MIN)
  211. ) {
  212. double ex = exp(x);
  213. result->val = y * ex;
  214. result->err = ex * (fabs(dy) + fabs(y*dx));
  215. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  216. return GSL_SUCCESS;
  217. }
  218. else {
  219. const double ly = log(ay);
  220. const double lnr = x + ly;
  221. if(lnr > GSL_LOG_DBL_MAX - 0.01) {
  222. OVERFLOW_ERROR(result);
  223. }
  224. else if(lnr < GSL_LOG_DBL_MIN + 0.01) {
  225. UNDERFLOW_ERROR(result);
  226. }
  227. else {
  228. const double sy = GSL_SIGN(y);
  229. const double M = floor(x);
  230. const double N = floor(ly);
  231. const double a = x - M;
  232. const double b = ly - N;
  233. const double eMN = exp(M+N);
  234. const double eab = exp(a+b);
  235. result->val = sy * eMN * eab;
  236. result->err = eMN * eab * 2.0*GSL_DBL_EPSILON;
  237. result->err += eMN * eab * fabs(dy/y);
  238. result->err += eMN * eab * fabs(dx);
  239. return GSL_SUCCESS;
  240. }
  241. }
  242. }
  243. int gsl_sf_exp_mult_err_e10_e(const double x, const double dx,
  244. const double y, const double dy,
  245. gsl_sf_result_e10 * result)
  246. {
  247. const double ay = fabs(y);
  248. if(y == 0.0) {
  249. result->val = 0.0;
  250. result->err = fabs(dy * exp(x));
  251. result->e10 = 0;
  252. return GSL_SUCCESS;
  253. }
  254. else if( ( x < 0.5*GSL_LOG_DBL_MAX && x > 0.5*GSL_LOG_DBL_MIN)
  255. && (ay < 0.8*GSL_SQRT_DBL_MAX && ay > 1.2*GSL_SQRT_DBL_MIN)
  256. ) {
  257. const double ex = exp(x);
  258. result->val = y * ex;
  259. result->err = ex * (fabs(dy) + fabs(y*dx));
  260. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  261. result->e10 = 0;
  262. return GSL_SUCCESS;
  263. }
  264. else {
  265. const double ly = log(ay);
  266. const double l10_val = (x + ly)/M_LN10;
  267. if(l10_val > INT_MAX-1) {
  268. OVERFLOW_ERROR_E10(result);
  269. }
  270. else if(l10_val < INT_MIN+1) {
  271. UNDERFLOW_ERROR_E10(result);
  272. }
  273. else {
  274. const double sy = GSL_SIGN(y);
  275. const int N = (int) floor(l10_val);
  276. const double arg_val = (l10_val - N) * M_LN10;
  277. const double arg_err = dy/fabs(y) + dx + 2.0*GSL_DBL_EPSILON*fabs(arg_val);
  278. result->val = sy * exp(arg_val);
  279. result->err = arg_err * fabs(result->val);
  280. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  281. result->e10 = N;
  282. return GSL_SUCCESS;
  283. }
  284. }
  285. }
  286. int gsl_sf_expm1_e(const double x, gsl_sf_result * result)
  287. {
  288. const double cut = 0.002;
  289. if(x < GSL_LOG_DBL_MIN) {
  290. result->val = -1.0;
  291. result->err = GSL_DBL_EPSILON;
  292. return GSL_SUCCESS;
  293. }
  294. else if(x < -cut) {
  295. result->val = exp(x) - 1.0;
  296. result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  297. return GSL_SUCCESS;
  298. }
  299. else if(x < cut) {
  300. result->val = x * (1.0 + 0.5*x*(1.0 + x/3.0*(1.0 + 0.25*x*(1.0 + 0.2*x))));
  301. result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  302. return GSL_SUCCESS;
  303. }
  304. else if(x < GSL_LOG_DBL_MAX) {
  305. result->val = exp(x) - 1.0;
  306. result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  307. return GSL_SUCCESS;
  308. }
  309. else {
  310. OVERFLOW_ERROR(result);
  311. }
  312. }
  313. int gsl_sf_exprel_e(const double x, gsl_sf_result * result)
  314. {
  315. const double cut = 0.002;
  316. if(x < GSL_LOG_DBL_MIN) {
  317. result->val = -1.0/x;
  318. result->err = GSL_DBL_EPSILON * fabs(result->val);
  319. return GSL_SUCCESS;
  320. }
  321. else if(x < -cut) {
  322. result->val = (exp(x) - 1.0)/x;
  323. result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  324. return GSL_SUCCESS;
  325. }
  326. else if(x < cut) {
  327. result->val = (1.0 + 0.5*x*(1.0 + x/3.0*(1.0 + 0.25*x*(1.0 + 0.2*x))));
  328. result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  329. return GSL_SUCCESS;
  330. }
  331. else if(x < GSL_LOG_DBL_MAX) {
  332. result->val = (exp(x) - 1.0)/x;
  333. result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  334. return GSL_SUCCESS;
  335. }
  336. else {
  337. OVERFLOW_ERROR(result);
  338. }
  339. }
  340. int gsl_sf_exprel_2_e(double x, gsl_sf_result * result)
  341. {
  342. const double cut = 0.002;
  343. if(x < GSL_LOG_DBL_MIN) {
  344. result->val = -2.0/x*(1.0 + 1.0/x);
  345. result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  346. return GSL_SUCCESS;
  347. }
  348. else if(x < -cut) {
  349. result->val = 2.0*(exp(x) - 1.0 - x)/(x*x);
  350. result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  351. return GSL_SUCCESS;
  352. }
  353. else if(x < cut) {
  354. result->val = (1.0 + 1.0/3.0*x*(1.0 + 0.25*x*(1.0 + 0.2*x*(1.0 + 1.0/6.0*x))));
  355. result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  356. return GSL_SUCCESS;
  357. }
  358. else if(x < GSL_LOG_DBL_MAX) {
  359. result->val = 2.0*(exp(x) - 1.0 - x)/(x*x);
  360. result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  361. return GSL_SUCCESS;
  362. }
  363. else {
  364. OVERFLOW_ERROR(result);
  365. }
  366. }
  367. int
  368. gsl_sf_exprel_n_e(const int N, const double x, gsl_sf_result * result)
  369. {
  370. if(N < 0) {
  371. DOMAIN_ERROR(result);
  372. }
  373. else if(x == 0.0) {
  374. result->val = 1.0;
  375. result->err = 0.0;
  376. return GSL_SUCCESS;
  377. }
  378. else if(fabs(x) < GSL_ROOT3_DBL_EPSILON * N) {
  379. result->val = 1.0 + x/(N+1) * (1.0 + x/(N+2));
  380. result->err = 2.0 * GSL_DBL_EPSILON;
  381. return GSL_SUCCESS;
  382. }
  383. else if(N == 0) {
  384. return gsl_sf_exp_e(x, result);
  385. }
  386. else if(N == 1) {
  387. return gsl_sf_exprel_e(x, result);
  388. }
  389. else if(N == 2) {
  390. return gsl_sf_exprel_2_e(x, result);
  391. }
  392. else {
  393. if(x > N && (-x + N*(1.0 + log(x/N)) < GSL_LOG_DBL_EPSILON)) {
  394. /* x is much larger than n.
  395. * Ignore polynomial part, so
  396. * exprel_N(x) ~= e^x N!/x^N
  397. */
  398. gsl_sf_result lnf_N;
  399. double lnr_val;
  400. double lnr_err;
  401. double lnterm;
  402. gsl_sf_lnfact_e(N, &lnf_N);
  403. lnterm = N*log(x);
  404. lnr_val = x + lnf_N.val - lnterm;
  405. lnr_err = GSL_DBL_EPSILON * (fabs(x) + fabs(lnf_N.val) + fabs(lnterm));
  406. lnr_err += lnf_N.err;
  407. return gsl_sf_exp_err_e(lnr_val, lnr_err, result);
  408. }
  409. else if(x > N) {
  410. /* Write the identity
  411. * exprel_n(x) = e^x n! / x^n (1 - Gamma[n,x]/Gamma[n])
  412. * then use the asymptotic expansion
  413. * Gamma[n,x] ~ x^(n-1) e^(-x) (1 + (n-1)/x + (n-1)(n-2)/x^2 + ...)
  414. */
  415. double ln_x = log(x);
  416. gsl_sf_result lnf_N;
  417. double lg_N;
  418. double lnpre_val;
  419. double lnpre_err;
  420. gsl_sf_lnfact_e(N, &lnf_N); /* log(N!) */
  421. lg_N = lnf_N.val - log(N); /* log(Gamma(N)) */
  422. lnpre_val = x + lnf_N.val - N*ln_x;
  423. lnpre_err = GSL_DBL_EPSILON * (fabs(x) + fabs(lnf_N.val) + fabs(N*ln_x));
  424. lnpre_err += lnf_N.err;
  425. if(lnpre_val < GSL_LOG_DBL_MAX - 5.0) {
  426. int stat_eG;
  427. gsl_sf_result bigG_ratio;
  428. gsl_sf_result pre;
  429. int stat_ex = gsl_sf_exp_err_e(lnpre_val, lnpre_err, &pre);
  430. double ln_bigG_ratio_pre = -x + (N-1)*ln_x - lg_N;
  431. double bigGsum = 1.0;
  432. double term = 1.0;
  433. int k;
  434. for(k=1; k<N; k++) {
  435. term *= (N-k)/x;
  436. bigGsum += term;
  437. }
  438. stat_eG = gsl_sf_exp_mult_e(ln_bigG_ratio_pre, bigGsum, &bigG_ratio);
  439. if(stat_eG == GSL_SUCCESS) {
  440. result->val = pre.val * (1.0 - bigG_ratio.val);
  441. result->err = pre.val * (2.0*GSL_DBL_EPSILON + bigG_ratio.err);
  442. result->err += pre.err * fabs(1.0 - bigG_ratio.val);
  443. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  444. return stat_ex;
  445. }
  446. else {
  447. result->val = 0.0;
  448. result->err = 0.0;
  449. return stat_eG;
  450. }
  451. }
  452. else {
  453. OVERFLOW_ERROR(result);
  454. }
  455. }
  456. else if(x > -10.0*N) {
  457. return exprel_n_CF(N, x, result);
  458. }
  459. else {
  460. /* x -> -Inf asymptotic:
  461. * exprel_n(x) ~ e^x n!/x^n - n/x (1 + (n-1)/x + (n-1)(n-2)/x + ...)
  462. * ~ - n/x (1 + (n-1)/x + (n-1)(n-2)/x + ...)
  463. */
  464. double sum = 1.0;
  465. double term = 1.0;
  466. int k;
  467. for(k=1; k<N; k++) {
  468. term *= (N-k)/x;
  469. sum += term;
  470. }
  471. result->val = -N/x * sum;
  472. result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  473. return GSL_SUCCESS;
  474. }
  475. }
  476. }
  477. int
  478. gsl_sf_exp_err_e(const double x, const double dx, gsl_sf_result * result)
  479. {
  480. const double adx = fabs(dx);
  481. /* CHECK_POINTER(result) */
  482. if(x + adx > GSL_LOG_DBL_MAX) {
  483. OVERFLOW_ERROR(result);
  484. }
  485. else if(x - adx < GSL_LOG_DBL_MIN) {
  486. UNDERFLOW_ERROR(result);
  487. }
  488. else {
  489. const double ex = exp(x);
  490. const double edx = exp(adx);
  491. result->val = ex;
  492. result->err = ex * GSL_MAX_DBL(GSL_DBL_EPSILON, edx - 1.0/edx);
  493. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  494. return GSL_SUCCESS;
  495. }
  496. }
  497. int
  498. gsl_sf_exp_err_e10_e(const double x, const double dx, gsl_sf_result_e10 * result)
  499. {
  500. const double adx = fabs(dx);
  501. /* CHECK_POINTER(result) */
  502. if(x + adx > INT_MAX - 1) {
  503. OVERFLOW_ERROR_E10(result);
  504. }
  505. else if(x - adx < INT_MIN + 1) {
  506. UNDERFLOW_ERROR_E10(result);
  507. }
  508. else {
  509. const int N = (int)floor(x/M_LN10);
  510. const double ex = exp(x-N*M_LN10);
  511. result->val = ex;
  512. result->err = ex * (2.0 * GSL_DBL_EPSILON * (fabs(x) + 1.0) + adx);
  513. result->e10 = N;
  514. return GSL_SUCCESS;
  515. }
  516. }
  517. /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/
  518. #include "gsl_specfunc__eval.h"
  519. double gsl_sf_exp(const double x)
  520. {
  521. EVAL_RESULT(gsl_sf_exp_e(x, &result));
  522. }
  523. double gsl_sf_exp_mult(const double x, const double y)
  524. {
  525. EVAL_RESULT(gsl_sf_exp_mult_e(x, y, &result));
  526. }
  527. double gsl_sf_expm1(const double x)
  528. {
  529. EVAL_RESULT(gsl_sf_expm1_e(x, &result));
  530. }
  531. double gsl_sf_exprel(const double x)
  532. {
  533. EVAL_RESULT(gsl_sf_exprel_e(x, &result));
  534. }
  535. double gsl_sf_exprel_2(const double x)
  536. {
  537. EVAL_RESULT(gsl_sf_exprel_2_e(x, &result));
  538. }
  539. double gsl_sf_exprel_n(const int n, const double x)
  540. {
  541. EVAL_RESULT(gsl_sf_exprel_n_e(n, x, &result));
  542. }