3 * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman
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.
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.
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.
20 /* Author: G. Jungman */
23 #include <gsl/gsl_math.h>
24 #include <gsl/gsl_errno.h>
25 #include <gsl/gsl_sf_gamma.h>
26 #include <gsl/gsl_sf_exp.h>
30 /* Evaluate the continued fraction for exprel.
31 * [Abramowitz+Stegun, 4.2.41]
35 exprel_n_CF(const int N, const double x, gsl_sf_result * result)
37 const double RECUR_BIG = GSL_SQRT_DBL_MAX;
38 const int maxiter = 5000;
52 double An = b1*Anm1 + a1*Anm2; /* A1 */
53 double Bn = b1*Bnm1 + a1*Bnm2; /* B1 */
55 /* One explicit step, before we get to the main pattern. */
61 An = b2*Anm1 + a2*Anm2; /* A2 */
62 Bn = b2*Bnm1 + a2*Bnm2; /* B2 */
74 an = ( GSL_IS_ODD(n) ? ((n-1)/2)*x : -(N+(n/2)-1)*x );
76 An = bn*Anm1 + an*Anm2;
77 Bn = bn*Bnm1 + an*Bnm2;
79 if(fabs(An) > RECUR_BIG || fabs(Bn) > RECUR_BIG) {
92 if(fabs(del - 1.0) < 2.0*GSL_DBL_EPSILON) break;
96 result->err = 2.0*(n+1.0)*GSL_DBL_EPSILON*fabs(fn);
99 GSL_ERROR ("error", GSL_EMAXITER);
105 /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/
107 int gsl_sf_exp_e(const double x, gsl_sf_result * result)
109 if(x > GSL_LOG_DBL_MAX) {
110 OVERFLOW_ERROR(result);
112 else if(x < GSL_LOG_DBL_MIN) {
113 UNDERFLOW_ERROR(result);
116 result->val = exp(x);
117 result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
122 int gsl_sf_exp_e10_e(const double x, gsl_sf_result_e10 * result)
125 OVERFLOW_ERROR_E10(result);
127 else if(x < INT_MIN+1) {
128 UNDERFLOW_ERROR_E10(result);
131 const int N = (x > GSL_LOG_DBL_MAX || x < GSL_LOG_DBL_MIN) ? (int) floor(x/M_LN10) : 0;
132 result->val = exp(x-N*M_LN10);
133 result->err = 2.0 * (fabs(x)+1.0) * GSL_DBL_EPSILON * fabs(result->val);
140 int gsl_sf_exp_mult_e(const double x, const double y, gsl_sf_result * result)
142 const double ay = fabs(y);
149 else if( ( x < 0.5*GSL_LOG_DBL_MAX && x > 0.5*GSL_LOG_DBL_MIN)
150 && (ay < 0.8*GSL_SQRT_DBL_MAX && ay > 1.2*GSL_SQRT_DBL_MIN)
152 const double ex = exp(x);
153 result->val = y * ex;
154 result->err = (2.0 + fabs(x)) * GSL_DBL_EPSILON * fabs(result->val);
158 const double ly = log(ay);
159 const double lnr = x + ly;
161 if(lnr > GSL_LOG_DBL_MAX - 0.01) {
162 OVERFLOW_ERROR(result);
164 else if(lnr < GSL_LOG_DBL_MIN + 0.01) {
165 UNDERFLOW_ERROR(result);
168 const double sy = GSL_SIGN(y);
169 const double M = floor(x);
170 const double N = floor(ly);
171 const double a = x - M;
172 const double b = ly - N;
173 const double berr = 2.0 * GSL_DBL_EPSILON * (fabs(ly) + fabs(N));
174 result->val = sy * exp(M+N) * exp(a+b);
175 result->err = berr * fabs(result->val);
176 result->err += 2.0 * GSL_DBL_EPSILON * (M + N + 1.0) * fabs(result->val);
183 int gsl_sf_exp_mult_e10_e(const double x, const double y, gsl_sf_result_e10 * result)
185 const double ay = fabs(y);
193 else if( ( x < 0.5*GSL_LOG_DBL_MAX && x > 0.5*GSL_LOG_DBL_MIN)
194 && (ay < 0.8*GSL_SQRT_DBL_MAX && ay > 1.2*GSL_SQRT_DBL_MIN)
196 const double ex = exp(x);
197 result->val = y * ex;
198 result->err = (2.0 + fabs(x)) * GSL_DBL_EPSILON * fabs(result->val);
203 const double ly = log(ay);
204 const double l10_val = (x + ly)/M_LN10;
206 if(l10_val > INT_MAX-1) {
207 OVERFLOW_ERROR_E10(result);
209 else if(l10_val < INT_MIN+1) {
210 UNDERFLOW_ERROR_E10(result);
213 const double sy = GSL_SIGN(y);
214 const int N = (int) floor(l10_val);
215 const double arg_val = (l10_val - N) * M_LN10;
216 const double arg_err = 2.0 * GSL_DBL_EPSILON * (fabs(x) + fabs(ly) + M_LN10*fabs(N));
218 result->val = sy * exp(arg_val);
219 result->err = arg_err * fabs(result->val);
220 result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
229 int gsl_sf_exp_mult_err_e(const double x, const double dx,
230 const double y, const double dy,
231 gsl_sf_result * result)
233 const double ay = fabs(y);
237 result->err = fabs(dy * exp(x));
240 else if( ( x < 0.5*GSL_LOG_DBL_MAX && x > 0.5*GSL_LOG_DBL_MIN)
241 && (ay < 0.8*GSL_SQRT_DBL_MAX && ay > 1.2*GSL_SQRT_DBL_MIN)
244 result->val = y * ex;
245 result->err = ex * (fabs(dy) + fabs(y*dx));
246 result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
250 const double ly = log(ay);
251 const double lnr = x + ly;
253 if(lnr > GSL_LOG_DBL_MAX - 0.01) {
254 OVERFLOW_ERROR(result);
256 else if(lnr < GSL_LOG_DBL_MIN + 0.01) {
257 UNDERFLOW_ERROR(result);
260 const double sy = GSL_SIGN(y);
261 const double M = floor(x);
262 const double N = floor(ly);
263 const double a = x - M;
264 const double b = ly - N;
265 const double eMN = exp(M+N);
266 const double eab = exp(a+b);
267 result->val = sy * eMN * eab;
268 result->err = eMN * eab * 2.0*GSL_DBL_EPSILON;
269 result->err += eMN * eab * fabs(dy/y);
270 result->err += eMN * eab * fabs(dx);
277 int gsl_sf_exp_mult_err_e10_e(const double x, const double dx,
278 const double y, const double dy,
279 gsl_sf_result_e10 * result)
281 const double ay = fabs(y);
285 result->err = fabs(dy * exp(x));
289 else if( ( x < 0.5*GSL_LOG_DBL_MAX && x > 0.5*GSL_LOG_DBL_MIN)
290 && (ay < 0.8*GSL_SQRT_DBL_MAX && ay > 1.2*GSL_SQRT_DBL_MIN)
292 const double ex = exp(x);
293 result->val = y * ex;
294 result->err = ex * (fabs(dy) + fabs(y*dx));
295 result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
300 const double ly = log(ay);
301 const double l10_val = (x + ly)/M_LN10;
303 if(l10_val > INT_MAX-1) {
304 OVERFLOW_ERROR_E10(result);
306 else if(l10_val < INT_MIN+1) {
307 UNDERFLOW_ERROR_E10(result);
310 const double sy = GSL_SIGN(y);
311 const int N = (int) floor(l10_val);
312 const double arg_val = (l10_val - N) * M_LN10;
313 const double arg_err = dy/fabs(y) + dx + 2.0*GSL_DBL_EPSILON*fabs(arg_val);
315 result->val = sy * exp(arg_val);
316 result->err = arg_err * fabs(result->val);
317 result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
326 int gsl_sf_expm1_e(const double x, gsl_sf_result * result)
328 const double cut = 0.002;
330 if(x < GSL_LOG_DBL_MIN) {
332 result->err = GSL_DBL_EPSILON;
336 result->val = exp(x) - 1.0;
337 result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
341 result->val = x * (1.0 + 0.5*x*(1.0 + x/3.0*(1.0 + 0.25*x*(1.0 + 0.2*x))));
342 result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
345 else if(x < GSL_LOG_DBL_MAX) {
346 result->val = exp(x) - 1.0;
347 result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
351 OVERFLOW_ERROR(result);
356 int gsl_sf_exprel_e(const double x, gsl_sf_result * result)
358 const double cut = 0.002;
360 if(x < GSL_LOG_DBL_MIN) {
361 result->val = -1.0/x;
362 result->err = GSL_DBL_EPSILON * fabs(result->val);
366 result->val = (exp(x) - 1.0)/x;
367 result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
371 result->val = (1.0 + 0.5*x*(1.0 + x/3.0*(1.0 + 0.25*x*(1.0 + 0.2*x))));
372 result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
375 else if(x < GSL_LOG_DBL_MAX) {
376 result->val = (exp(x) - 1.0)/x;
377 result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
381 OVERFLOW_ERROR(result);
386 int gsl_sf_exprel_2_e(double x, gsl_sf_result * result)
388 const double cut = 0.002;
390 if(x < GSL_LOG_DBL_MIN) {
391 result->val = -2.0/x*(1.0 + 1.0/x);
392 result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
396 result->val = 2.0*(exp(x) - 1.0 - x)/(x*x);
397 result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
401 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))));
402 result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
405 else if(x < GSL_LOG_DBL_MAX) {
406 result->val = 2.0*(exp(x) - 1.0 - x)/(x*x);
407 result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
411 OVERFLOW_ERROR(result);
417 gsl_sf_exprel_n_e(const int N, const double x, gsl_sf_result * result)
420 DOMAIN_ERROR(result);
427 else if(fabs(x) < GSL_ROOT3_DBL_EPSILON * N) {
428 result->val = 1.0 + x/(N+1) * (1.0 + x/(N+2));
429 result->err = 2.0 * GSL_DBL_EPSILON;
433 return gsl_sf_exp_e(x, result);
436 return gsl_sf_exprel_e(x, result);
439 return gsl_sf_exprel_2_e(x, result);
442 if(x > N && (-x + N*(1.0 + log(x/N)) < GSL_LOG_DBL_EPSILON)) {
443 /* x is much larger than n.
444 * Ignore polynomial part, so
445 * exprel_N(x) ~= e^x N!/x^N
451 gsl_sf_lnfact_e(N, &lnf_N);
453 lnr_val = x + lnf_N.val - lnterm;
454 lnr_err = GSL_DBL_EPSILON * (fabs(x) + fabs(lnf_N.val) + fabs(lnterm));
455 lnr_err += lnf_N.err;
456 return gsl_sf_exp_err_e(lnr_val, lnr_err, result);
459 /* Write the identity
460 * exprel_n(x) = e^x n! / x^n (1 - Gamma[n,x]/Gamma[n])
461 * then use the asymptotic expansion
462 * Gamma[n,x] ~ x^(n-1) e^(-x) (1 + (n-1)/x + (n-1)(n-2)/x^2 + ...)
464 double ln_x = log(x);
469 gsl_sf_lnfact_e(N, &lnf_N); /* log(N!) */
470 lg_N = lnf_N.val - log(N); /* log(Gamma(N)) */
471 lnpre_val = x + lnf_N.val - N*ln_x;
472 lnpre_err = GSL_DBL_EPSILON * (fabs(x) + fabs(lnf_N.val) + fabs(N*ln_x));
473 lnpre_err += lnf_N.err;
474 if(lnpre_val < GSL_LOG_DBL_MAX - 5.0) {
476 gsl_sf_result bigG_ratio;
478 int stat_ex = gsl_sf_exp_err_e(lnpre_val, lnpre_err, &pre);
479 double ln_bigG_ratio_pre = -x + (N-1)*ln_x - lg_N;
480 double bigGsum = 1.0;
487 stat_eG = gsl_sf_exp_mult_e(ln_bigG_ratio_pre, bigGsum, &bigG_ratio);
488 if(stat_eG == GSL_SUCCESS) {
489 result->val = pre.val * (1.0 - bigG_ratio.val);
490 result->err = pre.val * (2.0*GSL_DBL_EPSILON + bigG_ratio.err);
491 result->err += pre.err * fabs(1.0 - bigG_ratio.val);
492 result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
502 OVERFLOW_ERROR(result);
505 else if(x > -10.0*N) {
506 return exprel_n_CF(N, x, result);
509 /* x -> -Inf asymptotic:
510 * exprel_n(x) ~ e^x n!/x^n - n/x (1 + (n-1)/x + (n-1)(n-2)/x + ...)
511 * ~ - n/x (1 + (n-1)/x + (n-1)(n-2)/x + ...)
520 result->val = -N/x * sum;
521 result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
529 gsl_sf_exp_err_e(const double x, const double dx, gsl_sf_result * result)
531 const double adx = fabs(dx);
533 /* CHECK_POINTER(result) */
535 if(x + adx > GSL_LOG_DBL_MAX) {
536 OVERFLOW_ERROR(result);
538 else if(x - adx < GSL_LOG_DBL_MIN) {
539 UNDERFLOW_ERROR(result);
542 const double ex = exp(x);
543 const double edx = exp(adx);
545 result->err = ex * GSL_MAX_DBL(GSL_DBL_EPSILON, edx - 1.0/edx);
546 result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
553 gsl_sf_exp_err_e10_e(const double x, const double dx, gsl_sf_result_e10 * result)
555 const double adx = fabs(dx);
557 /* CHECK_POINTER(result) */
559 if(x + adx > INT_MAX - 1) {
560 OVERFLOW_ERROR_E10(result);
562 else if(x - adx < INT_MIN + 1) {
563 UNDERFLOW_ERROR_E10(result);
566 const int N = (int)floor(x/M_LN10);
567 const double ex = exp(x-N*M_LN10);
569 result->err = ex * (2.0 * GSL_DBL_EPSILON * (fabs(x) + 1.0) + adx);
576 /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/
580 double gsl_sf_exp(const double x)
582 EVAL_RESULT(gsl_sf_exp_e(x, &result));
585 double gsl_sf_exp_mult(const double x, const double y)
587 EVAL_RESULT(gsl_sf_exp_mult_e(x, y, &result));
590 double gsl_sf_expm1(const double x)
592 EVAL_RESULT(gsl_sf_expm1_e(x, &result));
595 double gsl_sf_exprel(const double x)
597 EVAL_RESULT(gsl_sf_exprel_e(x, &result));
600 double gsl_sf_exprel_2(const double x)
602 EVAL_RESULT(gsl_sf_exprel_2_e(x, &result));
605 double gsl_sf_exprel_n(const int n, const double x)
607 EVAL_RESULT(gsl_sf_exprel_n_e(n, x, &result));