|
Packit |
67cb25 |
/* specfunc/expint.c
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* Copyright (C) 2007 Brian Gough
|
|
Packit |
67cb25 |
* Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Gerard Jungman
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
67cb25 |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
67cb25 |
* the Free Software Foundation; either version 3 of the License, or (at
|
|
Packit |
67cb25 |
* your option) any later version.
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* This program is distributed in the hope that it will be useful, but
|
|
Packit |
67cb25 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
67cb25 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
67cb25 |
* General Public License for more details.
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
67cb25 |
* along with this program; if not, write to the Free Software
|
|
Packit |
67cb25 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
Packit |
67cb25 |
*/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* Author: G. Jungman */
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
#include <config.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_math.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_errno.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_sf_expint.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_sf_gamma.h>
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
#include "error.h"
|
|
Packit |
67cb25 |
#include "check.h"
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
#include "chebyshev.h"
|
|
Packit |
67cb25 |
#include "cheb_eval.c"
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/*
|
|
Packit |
67cb25 |
Chebyshev expansions: based on SLATEC e1.f, W. Fullerton
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Series for AE11 on the interval -1.00000D-01 to 0.
|
|
Packit |
67cb25 |
with weighted error 1.76E-17
|
|
Packit |
67cb25 |
log weighted error 16.75
|
|
Packit |
67cb25 |
significant figures required 15.70
|
|
Packit |
67cb25 |
decimal places required 17.55
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Series for AE12 on the interval -2.50000D-01 to -1.00000D-01
|
|
Packit |
67cb25 |
with weighted error 5.83E-17
|
|
Packit |
67cb25 |
log weighted error 16.23
|
|
Packit |
67cb25 |
significant figures required 15.76
|
|
Packit |
67cb25 |
decimal places required 16.93
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Series for E11 on the interval -4.00000D+00 to -1.00000D+00
|
|
Packit |
67cb25 |
with weighted error 1.08E-18
|
|
Packit |
67cb25 |
log weighted error 17.97
|
|
Packit |
67cb25 |
significant figures required 19.02
|
|
Packit |
67cb25 |
decimal places required 18.61
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Series for E12 on the interval -1.00000D+00 to 1.00000D+00
|
|
Packit |
67cb25 |
with weighted error 3.15E-18
|
|
Packit |
67cb25 |
log weighted error 17.50
|
|
Packit |
67cb25 |
approx significant figures required 15.8
|
|
Packit |
67cb25 |
decimal places required 18.10
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Series for AE13 on the interval 2.50000D-01 to 1.00000D+00
|
|
Packit |
67cb25 |
with weighted error 2.34E-17
|
|
Packit |
67cb25 |
log weighted error 16.63
|
|
Packit |
67cb25 |
significant figures required 16.14
|
|
Packit |
67cb25 |
decimal places required 17.33
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Series for AE14 on the interval 0. to 2.50000D-01
|
|
Packit |
67cb25 |
with weighted error 5.41E-17
|
|
Packit |
67cb25 |
log weighted error 16.27
|
|
Packit |
67cb25 |
significant figures required 15.38
|
|
Packit |
67cb25 |
decimal places required 16.97
|
|
Packit |
67cb25 |
*/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static double AE11_data[39] = {
|
|
Packit |
67cb25 |
0.121503239716065790,
|
|
Packit |
67cb25 |
-0.065088778513550150,
|
|
Packit |
67cb25 |
0.004897651357459670,
|
|
Packit |
67cb25 |
-0.000649237843027216,
|
|
Packit |
67cb25 |
0.000093840434587471,
|
|
Packit |
67cb25 |
0.000000420236380882,
|
|
Packit |
67cb25 |
-0.000008113374735904,
|
|
Packit |
67cb25 |
0.000002804247688663,
|
|
Packit |
67cb25 |
0.000000056487164441,
|
|
Packit |
67cb25 |
-0.000000344809174450,
|
|
Packit |
67cb25 |
0.000000058209273578,
|
|
Packit |
67cb25 |
0.000000038711426349,
|
|
Packit |
67cb25 |
-0.000000012453235014,
|
|
Packit |
67cb25 |
-0.000000005118504888,
|
|
Packit |
67cb25 |
0.000000002148771527,
|
|
Packit |
67cb25 |
0.000000000868459898,
|
|
Packit |
67cb25 |
-0.000000000343650105,
|
|
Packit |
67cb25 |
-0.000000000179796603,
|
|
Packit |
67cb25 |
0.000000000047442060,
|
|
Packit |
67cb25 |
0.000000000040423282,
|
|
Packit |
67cb25 |
-0.000000000003543928,
|
|
Packit |
67cb25 |
-0.000000000008853444,
|
|
Packit |
67cb25 |
-0.000000000000960151,
|
|
Packit |
67cb25 |
0.000000000001692921,
|
|
Packit |
67cb25 |
0.000000000000607990,
|
|
Packit |
67cb25 |
-0.000000000000224338,
|
|
Packit |
67cb25 |
-0.000000000000200327,
|
|
Packit |
67cb25 |
-0.000000000000006246,
|
|
Packit |
67cb25 |
0.000000000000045571,
|
|
Packit |
67cb25 |
0.000000000000016383,
|
|
Packit |
67cb25 |
-0.000000000000005561,
|
|
Packit |
67cb25 |
-0.000000000000006074,
|
|
Packit |
67cb25 |
-0.000000000000000862,
|
|
Packit |
67cb25 |
0.000000000000001223,
|
|
Packit |
67cb25 |
0.000000000000000716,
|
|
Packit |
67cb25 |
-0.000000000000000024,
|
|
Packit |
67cb25 |
-0.000000000000000201,
|
|
Packit |
67cb25 |
-0.000000000000000082,
|
|
Packit |
67cb25 |
0.000000000000000017
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
static cheb_series AE11_cs = {
|
|
Packit |
67cb25 |
AE11_data,
|
|
Packit |
67cb25 |
38,
|
|
Packit |
67cb25 |
-1, 1,
|
|
Packit |
67cb25 |
20
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static double AE12_data[25] = {
|
|
Packit |
67cb25 |
0.582417495134726740,
|
|
Packit |
67cb25 |
-0.158348850905782750,
|
|
Packit |
67cb25 |
-0.006764275590323141,
|
|
Packit |
67cb25 |
0.005125843950185725,
|
|
Packit |
67cb25 |
0.000435232492169391,
|
|
Packit |
67cb25 |
-0.000143613366305483,
|
|
Packit |
67cb25 |
-0.000041801320556301,
|
|
Packit |
67cb25 |
-0.000002713395758640,
|
|
Packit |
67cb25 |
0.000001151381913647,
|
|
Packit |
67cb25 |
0.000000420650022012,
|
|
Packit |
67cb25 |
0.000000066581901391,
|
|
Packit |
67cb25 |
0.000000000662143777,
|
|
Packit |
67cb25 |
-0.000000002844104870,
|
|
Packit |
67cb25 |
-0.000000000940724197,
|
|
Packit |
67cb25 |
-0.000000000177476602,
|
|
Packit |
67cb25 |
-0.000000000015830222,
|
|
Packit |
67cb25 |
0.000000000002905732,
|
|
Packit |
67cb25 |
0.000000000001769356,
|
|
Packit |
67cb25 |
0.000000000000492735,
|
|
Packit |
67cb25 |
0.000000000000093709,
|
|
Packit |
67cb25 |
0.000000000000010707,
|
|
Packit |
67cb25 |
-0.000000000000000537,
|
|
Packit |
67cb25 |
-0.000000000000000716,
|
|
Packit |
67cb25 |
-0.000000000000000244,
|
|
Packit |
67cb25 |
-0.000000000000000058
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
static cheb_series AE12_cs = {
|
|
Packit |
67cb25 |
AE12_data,
|
|
Packit |
67cb25 |
24,
|
|
Packit |
67cb25 |
-1, 1,
|
|
Packit |
67cb25 |
15
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static double E11_data[19] = {
|
|
Packit |
67cb25 |
-16.11346165557149402600,
|
|
Packit |
67cb25 |
7.79407277874268027690,
|
|
Packit |
67cb25 |
-1.95540581886314195070,
|
|
Packit |
67cb25 |
0.37337293866277945612,
|
|
Packit |
67cb25 |
-0.05692503191092901938,
|
|
Packit |
67cb25 |
0.00721107776966009185,
|
|
Packit |
67cb25 |
-0.00078104901449841593,
|
|
Packit |
67cb25 |
0.00007388093356262168,
|
|
Packit |
67cb25 |
-0.00000620286187580820,
|
|
Packit |
67cb25 |
0.00000046816002303176,
|
|
Packit |
67cb25 |
-0.00000003209288853329,
|
|
Packit |
67cb25 |
0.00000000201519974874,
|
|
Packit |
67cb25 |
-0.00000000011673686816,
|
|
Packit |
67cb25 |
0.00000000000627627066,
|
|
Packit |
67cb25 |
-0.00000000000031481541,
|
|
Packit |
67cb25 |
0.00000000000001479904,
|
|
Packit |
67cb25 |
-0.00000000000000065457,
|
|
Packit |
67cb25 |
0.00000000000000002733,
|
|
Packit |
67cb25 |
-0.00000000000000000108
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
static cheb_series E11_cs = {
|
|
Packit |
67cb25 |
E11_data,
|
|
Packit |
67cb25 |
18,
|
|
Packit |
67cb25 |
-1, 1,
|
|
Packit |
67cb25 |
13
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static double E12_data[16] = {
|
|
Packit |
67cb25 |
-0.03739021479220279500,
|
|
Packit |
67cb25 |
0.04272398606220957700,
|
|
Packit |
67cb25 |
-0.13031820798497005440,
|
|
Packit |
67cb25 |
0.01441912402469889073,
|
|
Packit |
67cb25 |
-0.00134617078051068022,
|
|
Packit |
67cb25 |
0.00010731029253063780,
|
|
Packit |
67cb25 |
-0.00000742999951611943,
|
|
Packit |
67cb25 |
0.00000045377325690753,
|
|
Packit |
67cb25 |
-0.00000002476417211390,
|
|
Packit |
67cb25 |
0.00000000122076581374,
|
|
Packit |
67cb25 |
-0.00000000005485141480,
|
|
Packit |
67cb25 |
0.00000000000226362142,
|
|
Packit |
67cb25 |
-0.00000000000008635897,
|
|
Packit |
67cb25 |
0.00000000000000306291,
|
|
Packit |
67cb25 |
-0.00000000000000010148,
|
|
Packit |
67cb25 |
0.00000000000000000315
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
static cheb_series E12_cs = {
|
|
Packit |
67cb25 |
E12_data,
|
|
Packit |
67cb25 |
15,
|
|
Packit |
67cb25 |
-1, 1,
|
|
Packit |
67cb25 |
10
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static double AE13_data[25] = {
|
|
Packit |
67cb25 |
-0.605773246640603460,
|
|
Packit |
67cb25 |
-0.112535243483660900,
|
|
Packit |
67cb25 |
0.013432266247902779,
|
|
Packit |
67cb25 |
-0.001926845187381145,
|
|
Packit |
67cb25 |
0.000309118337720603,
|
|
Packit |
67cb25 |
-0.000053564132129618,
|
|
Packit |
67cb25 |
0.000009827812880247,
|
|
Packit |
67cb25 |
-0.000001885368984916,
|
|
Packit |
67cb25 |
0.000000374943193568,
|
|
Packit |
67cb25 |
-0.000000076823455870,
|
|
Packit |
67cb25 |
0.000000016143270567,
|
|
Packit |
67cb25 |
-0.000000003466802211,
|
|
Packit |
67cb25 |
0.000000000758754209,
|
|
Packit |
67cb25 |
-0.000000000168864333,
|
|
Packit |
67cb25 |
0.000000000038145706,
|
|
Packit |
67cb25 |
-0.000000000008733026,
|
|
Packit |
67cb25 |
0.000000000002023672,
|
|
Packit |
67cb25 |
-0.000000000000474132,
|
|
Packit |
67cb25 |
0.000000000000112211,
|
|
Packit |
67cb25 |
-0.000000000000026804,
|
|
Packit |
67cb25 |
0.000000000000006457,
|
|
Packit |
67cb25 |
-0.000000000000001568,
|
|
Packit |
67cb25 |
0.000000000000000383,
|
|
Packit |
67cb25 |
-0.000000000000000094,
|
|
Packit |
67cb25 |
0.000000000000000023
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
static cheb_series AE13_cs = {
|
|
Packit |
67cb25 |
AE13_data,
|
|
Packit |
67cb25 |
24,
|
|
Packit |
67cb25 |
-1, 1,
|
|
Packit |
67cb25 |
15
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static double AE14_data[26] = {
|
|
Packit |
67cb25 |
-0.18929180007530170,
|
|
Packit |
67cb25 |
-0.08648117855259871,
|
|
Packit |
67cb25 |
0.00722410154374659,
|
|
Packit |
67cb25 |
-0.00080975594575573,
|
|
Packit |
67cb25 |
0.00010999134432661,
|
|
Packit |
67cb25 |
-0.00001717332998937,
|
|
Packit |
67cb25 |
0.00000298562751447,
|
|
Packit |
67cb25 |
-0.00000056596491457,
|
|
Packit |
67cb25 |
0.00000011526808397,
|
|
Packit |
67cb25 |
-0.00000002495030440,
|
|
Packit |
67cb25 |
0.00000000569232420,
|
|
Packit |
67cb25 |
-0.00000000135995766,
|
|
Packit |
67cb25 |
0.00000000033846628,
|
|
Packit |
67cb25 |
-0.00000000008737853,
|
|
Packit |
67cb25 |
0.00000000002331588,
|
|
Packit |
67cb25 |
-0.00000000000641148,
|
|
Packit |
67cb25 |
0.00000000000181224,
|
|
Packit |
67cb25 |
-0.00000000000052538,
|
|
Packit |
67cb25 |
0.00000000000015592,
|
|
Packit |
67cb25 |
-0.00000000000004729,
|
|
Packit |
67cb25 |
0.00000000000001463,
|
|
Packit |
67cb25 |
-0.00000000000000461,
|
|
Packit |
67cb25 |
0.00000000000000148,
|
|
Packit |
67cb25 |
-0.00000000000000048,
|
|
Packit |
67cb25 |
0.00000000000000016,
|
|
Packit |
67cb25 |
-0.00000000000000005
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
static cheb_series AE14_cs = {
|
|
Packit |
67cb25 |
AE14_data,
|
|
Packit |
67cb25 |
25,
|
|
Packit |
67cb25 |
-1, 1,
|
|
Packit |
67cb25 |
13
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* implementation for E1, allowing for scaling by exp(x) */
|
|
Packit |
67cb25 |
static
|
|
Packit |
67cb25 |
int expint_E1_impl(const double x, gsl_sf_result * result, const int scale)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
const double xmaxt = -GSL_LOG_DBL_MIN; /* XMAXT = -LOG (R1MACH(1)) */
|
|
Packit |
67cb25 |
const double xmax = xmaxt - log(xmaxt); /* XMAX = XMAXT - LOG(XMAXT) */
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* CHECK_POINTER(result) */
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if(x < -xmax && !scale) {
|
|
Packit |
67cb25 |
OVERFLOW_ERROR(result);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else if(x <= -10.0) {
|
|
Packit |
67cb25 |
const double s = 1.0/x * ( scale ? 1.0 : exp(-x) );
|
|
Packit |
67cb25 |
gsl_sf_result result_c;
|
|
Packit |
67cb25 |
cheb_eval_e(&AE11_cs, 20.0/x+1.0, &result_c);
|
|
Packit |
67cb25 |
result->val = s * (1.0 + result_c.val);
|
|
Packit |
67cb25 |
result->err = s * result_c.err;
|
|
Packit |
67cb25 |
result->err += 2.0 * GSL_DBL_EPSILON * (fabs(x) + 1.0) * fabs(result->val);
|
|
Packit |
67cb25 |
return GSL_SUCCESS;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else if(x <= -4.0) {
|
|
Packit |
67cb25 |
const double s = 1.0/x * ( scale ? 1.0 : exp(-x) );
|
|
Packit |
67cb25 |
gsl_sf_result result_c;
|
|
Packit |
67cb25 |
cheb_eval_e(&AE12_cs, (40.0/x+7.0)/3.0, &result_c);
|
|
Packit |
67cb25 |
result->val = s * (1.0 + result_c.val);
|
|
Packit |
67cb25 |
result->err = s * result_c.err;
|
|
Packit |
67cb25 |
result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
|
|
Packit |
67cb25 |
return GSL_SUCCESS;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else if(x <= -1.0) {
|
|
Packit |
67cb25 |
const double ln_term = -log(fabs(x));
|
|
Packit |
67cb25 |
const double scale_factor = ( scale ? exp(x) : 1.0 );
|
|
Packit |
67cb25 |
gsl_sf_result result_c;
|
|
Packit |
67cb25 |
cheb_eval_e(&E11_cs, (2.0*x+5.0)/3.0, &result_c);
|
|
Packit |
67cb25 |
result->val = scale_factor * (ln_term + result_c.val);
|
|
Packit |
67cb25 |
result->err = scale_factor * (result_c.err + GSL_DBL_EPSILON * fabs(ln_term));
|
|
Packit |
67cb25 |
result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
|
|
Packit |
67cb25 |
return GSL_SUCCESS;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else if(x == 0.0) {
|
|
Packit |
67cb25 |
DOMAIN_ERROR(result);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else if(x <= 1.0) {
|
|
Packit |
67cb25 |
const double ln_term = -log(fabs(x));
|
|
Packit |
67cb25 |
const double scale_factor = ( scale ? exp(x) : 1.0 );
|
|
Packit |
67cb25 |
gsl_sf_result result_c;
|
|
Packit |
67cb25 |
cheb_eval_e(&E12_cs, x, &result_c);
|
|
Packit |
67cb25 |
result->val = scale_factor * (ln_term - 0.6875 + x + result_c.val);
|
|
Packit |
67cb25 |
result->err = scale_factor * (result_c.err + GSL_DBL_EPSILON * fabs(ln_term));
|
|
Packit |
67cb25 |
result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
|
|
Packit |
67cb25 |
return GSL_SUCCESS;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else if(x <= 4.0) {
|
|
Packit |
67cb25 |
const double s = 1.0/x * ( scale ? 1.0 : exp(-x) );
|
|
Packit |
67cb25 |
gsl_sf_result result_c;
|
|
Packit |
67cb25 |
cheb_eval_e(&AE13_cs, (8.0/x-5.0)/3.0, &result_c);
|
|
Packit |
67cb25 |
result->val = s * (1.0 + result_c.val);
|
|
Packit |
67cb25 |
result->err = s * result_c.err;
|
|
Packit |
67cb25 |
result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
|
|
Packit |
67cb25 |
return GSL_SUCCESS;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else if(x <= xmax || scale) {
|
|
Packit |
67cb25 |
const double s = 1.0/x * ( scale ? 1.0 : exp(-x) );
|
|
Packit |
67cb25 |
gsl_sf_result result_c;
|
|
Packit |
67cb25 |
cheb_eval_e(&AE14_cs, 8.0/x-1.0, &result_c);
|
|
Packit |
67cb25 |
result->val = s * (1.0 + result_c.val);
|
|
Packit |
67cb25 |
result->err = s * (GSL_DBL_EPSILON + result_c.err);
|
|
Packit |
67cb25 |
result->err += 2.0 * (x + 1.0) * GSL_DBL_EPSILON * fabs(result->val);
|
|
Packit |
67cb25 |
if(result->val == 0.0)
|
|
Packit |
67cb25 |
UNDERFLOW_ERROR(result);
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
return GSL_SUCCESS;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else {
|
|
Packit |
67cb25 |
UNDERFLOW_ERROR(result);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static
|
|
Packit |
67cb25 |
int expint_E2_impl(const double x, gsl_sf_result * result, const int scale)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
const double xmaxt = -GSL_LOG_DBL_MIN;
|
|
Packit |
67cb25 |
const double xmax = xmaxt - log(xmaxt);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* CHECK_POINTER(result) */
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if(x < -xmax && !scale) {
|
|
Packit |
67cb25 |
OVERFLOW_ERROR(result);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else if (x == 0.0) {
|
|
Packit |
67cb25 |
result->val = 1.0;
|
|
Packit |
67cb25 |
result->err = 0.0;
|
|
Packit |
67cb25 |
return GSL_SUCCESS;
|
|
Packit |
67cb25 |
} else if(x < 100.0) {
|
|
Packit |
67cb25 |
const double ex = ( scale ? 1.0 : exp(-x) );
|
|
Packit |
67cb25 |
gsl_sf_result result_E1;
|
|
Packit |
67cb25 |
int stat_E1 = expint_E1_impl(x, &result_E1, scale);
|
|
Packit |
67cb25 |
result->val = ex - x*result_E1.val;
|
|
Packit |
67cb25 |
result->err = GSL_DBL_EPSILON*ex + fabs(x) * result_E1.err;
|
|
Packit |
67cb25 |
result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
|
|
Packit |
67cb25 |
return stat_E1;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else if(x < xmax || scale) {
|
|
Packit |
67cb25 |
const double s = ( scale ? 1.0 : exp(-x) );
|
|
Packit |
67cb25 |
const double c1 = -2.0;
|
|
Packit |
67cb25 |
const double c2 = 6.0;
|
|
Packit |
67cb25 |
const double c3 = -24.0;
|
|
Packit |
67cb25 |
const double c4 = 120.0;
|
|
Packit |
67cb25 |
const double c5 = -720.0;
|
|
Packit |
67cb25 |
const double c6 = 5040.0;
|
|
Packit |
67cb25 |
const double c7 = -40320.0;
|
|
Packit |
67cb25 |
const double c8 = 362880.0;
|
|
Packit |
67cb25 |
const double c9 = -3628800.0;
|
|
Packit |
67cb25 |
const double c10 = 39916800.0;
|
|
Packit |
67cb25 |
const double c11 = -479001600.0;
|
|
Packit |
67cb25 |
const double c12 = 6227020800.0;
|
|
Packit |
67cb25 |
const double c13 = -87178291200.0;
|
|
Packit |
67cb25 |
const double y = 1.0/x;
|
|
Packit |
67cb25 |
const double sum6 = c6+y*(c7+y*(c8+y*(c9+y*(c10+y*(c11+y*(c12+y*c13))))));
|
|
Packit |
67cb25 |
const double sum = y*(c1+y*(c2+y*(c3+y*(c4+y*(c5+y*sum6)))));
|
|
Packit |
67cb25 |
result->val = s * (1.0 + sum)/x;
|
|
Packit |
67cb25 |
result->err = 2.0 * (x + 1.0) * GSL_DBL_EPSILON * result->val;
|
|
Packit |
67cb25 |
if(result->val == 0.0)
|
|
Packit |
67cb25 |
UNDERFLOW_ERROR(result);
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
return GSL_SUCCESS;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else {
|
|
Packit |
67cb25 |
UNDERFLOW_ERROR(result);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static
|
|
Packit |
67cb25 |
int expint_En_impl(const int n, const double x, gsl_sf_result * result, const int scale)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
if (n < 0) {
|
|
Packit |
67cb25 |
DOMAIN_ERROR(result);
|
|
Packit |
67cb25 |
} else if (n == 0) {
|
|
Packit |
67cb25 |
if (x == 0) {
|
|
Packit |
67cb25 |
DOMAIN_ERROR(result);
|
|
Packit |
67cb25 |
} else {
|
|
Packit |
67cb25 |
result->val = (scale ? 1.0 : exp(-x)) / x;
|
|
Packit |
67cb25 |
result->err = 2 * GSL_DBL_EPSILON * fabs(result->val);
|
|
Packit |
67cb25 |
CHECK_UNDERFLOW(result);
|
|
Packit |
67cb25 |
return GSL_SUCCESS;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
} else if (n == 1) {
|
|
Packit |
67cb25 |
return expint_E1_impl(x, result, scale);
|
|
Packit |
67cb25 |
} else if (n == 2) {
|
|
Packit |
67cb25 |
return expint_E2_impl(x, result, scale);
|
|
Packit |
67cb25 |
} else {
|
|
Packit |
67cb25 |
if(x < 0) {
|
|
Packit |
67cb25 |
DOMAIN_ERROR(result);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
if (x == 0) {
|
|
Packit |
67cb25 |
result->val = (scale ? exp(x) : 1 ) * (1/(n-1.0));
|
|
Packit |
67cb25 |
result->err = 2 * GSL_DBL_EPSILON * fabs(result->val);
|
|
Packit |
67cb25 |
CHECK_UNDERFLOW(result);
|
|
Packit |
67cb25 |
return GSL_SUCCESS;
|
|
Packit |
67cb25 |
} else {
|
|
Packit |
67cb25 |
gsl_sf_result result_g;
|
|
Packit |
67cb25 |
double prefactor = pow(x, n-1);
|
|
Packit |
67cb25 |
int status = gsl_sf_gamma_inc_e (1-n, x, &result_g);
|
|
Packit |
67cb25 |
double scale_factor = ( scale ? exp(x) : 1.0 );
|
|
Packit |
67cb25 |
result->val = scale_factor * prefactor * result_g.val;
|
|
Packit |
67cb25 |
result->err = 2 * GSL_DBL_EPSILON * fabs(result->val);
|
|
Packit |
67cb25 |
result->err += 2 * fabs(scale_factor * prefactor * result_g.err);
|
|
Packit |
67cb25 |
if (status == GSL_SUCCESS) CHECK_UNDERFLOW(result);
|
|
Packit |
67cb25 |
return status;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
int gsl_sf_expint_E1_e(const double x, gsl_sf_result * result)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
return expint_E1_impl(x, result, 0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
int gsl_sf_expint_E1_scaled_e(const double x, gsl_sf_result * result)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
return expint_E1_impl(x, result, 1);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
int gsl_sf_expint_E2_e(const double x, gsl_sf_result * result)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
return expint_E2_impl(x, result, 0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
int gsl_sf_expint_E2_scaled_e(const double x, gsl_sf_result * result)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
return expint_E2_impl(x, result, 1);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
int gsl_sf_expint_En_e(const int n, const double x, gsl_sf_result * result)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
return expint_En_impl(n, x, result, 0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
int gsl_sf_expint_En_scaled_e(const int n, const double x, gsl_sf_result * result)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
return expint_En_impl(n, x, result, 1);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
int gsl_sf_expint_Ei_e(const double x, gsl_sf_result * result)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
/* CHECK_POINTER(result) */
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
int status = gsl_sf_expint_E1_e(-x, result);
|
|
Packit |
67cb25 |
result->val = -result->val;
|
|
Packit |
67cb25 |
return status;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
int gsl_sf_expint_Ei_scaled_e(const double x, gsl_sf_result * result)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
/* CHECK_POINTER(result) */
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
int status = gsl_sf_expint_E1_scaled_e(-x, result);
|
|
Packit |
67cb25 |
result->val = -result->val;
|
|
Packit |
67cb25 |
return status;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
#if 0
|
|
Packit |
67cb25 |
static double recurse_En(int n, double x, double E1)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
int i;
|
|
Packit |
67cb25 |
double En = E1;
|
|
Packit |
67cb25 |
double ex = exp(-x);
|
|
Packit |
67cb25 |
for(i=2; i<=n; i++) {
|
|
Packit |
67cb25 |
En = 1./(i-1) * (ex - x * En);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
return En;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
#endif
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
#include "eval.h"
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double gsl_sf_expint_E1(const double x)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
EVAL_RESULT(gsl_sf_expint_E1_e(x, &result));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double gsl_sf_expint_E1_scaled(const double x)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
EVAL_RESULT(gsl_sf_expint_E1_scaled_e(x, &result));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double gsl_sf_expint_E2(const double x)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
EVAL_RESULT(gsl_sf_expint_E2_e(x, &result));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double gsl_sf_expint_E2_scaled(const double x)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
EVAL_RESULT(gsl_sf_expint_E2_scaled_e(x, &result));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double gsl_sf_expint_En(const int n, const double x)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
EVAL_RESULT(gsl_sf_expint_En_e(n, x, &result));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double gsl_sf_expint_En_scaled(const int n, const double x)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
EVAL_RESULT(gsl_sf_expint_En_scaled_e(n, x, &result));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double gsl_sf_expint_Ei(const double x)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
EVAL_RESULT(gsl_sf_expint_Ei_e(x, &result));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double gsl_sf_expint_Ei_scaled(const double x)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
EVAL_RESULT(gsl_sf_expint_Ei_scaled_e(x, &result));
|
|
Packit |
67cb25 |
}
|