Blame specfunc/bessel_I1.c

Packit 67cb25
/* specfunc/bessel_I1.c
Packit 67cb25
 * 
Packit 67cb25
 * Copyright (C) 1996, 1997, 1998, 1999, 2000 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_bessel.h>
Packit 67cb25
Packit 67cb25
#include "error.h"
Packit 67cb25
Packit 67cb25
#include "chebyshev.h"
Packit 67cb25
#include "cheb_eval.c"
Packit 67cb25
Packit 67cb25
#define ROOT_EIGHT (2.0*M_SQRT2)
Packit 67cb25
Packit 67cb25
Packit 67cb25
/*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/
Packit 67cb25
Packit 67cb25
/* based on SLATEC besi1(), besi1e() */
Packit 67cb25
Packit 67cb25
/* chebyshev expansions
Packit 67cb25
Packit 67cb25
 series for bi1        on the interval  0.          to  9.00000d+00
Packit 67cb25
                                        with weighted error   2.40e-17
Packit 67cb25
                                         log weighted error  16.62
Packit 67cb25
                               significant figures required  16.23
Packit 67cb25
                                    decimal places required  17.14
Packit 67cb25
Packit 67cb25
 series for ai1        on the interval  1.25000d-01 to  3.33333d-01
Packit 67cb25
                                        with weighted error   6.98e-17
Packit 67cb25
                                         log weighted error  16.16
Packit 67cb25
                               significant figures required  14.53
Packit 67cb25
                                    decimal places required  16.82
Packit 67cb25
Packit 67cb25
 series for ai12       on the interval  0.          to  1.25000d-01
Packit 67cb25
                                       with weighted error   3.55e-17
Packit 67cb25
                                        log weighted error  16.45
Packit 67cb25
                              significant figures required  14.69
Packit 67cb25
                                   decimal places required  17.12
Packit 67cb25
*/
Packit 67cb25
Packit 67cb25
static double bi1_data[11] = {
Packit 67cb25
  -0.001971713261099859,
Packit 67cb25
   0.407348876675464810,
Packit 67cb25
   0.034838994299959456,
Packit 67cb25
   0.001545394556300123,
Packit 67cb25
   0.000041888521098377,
Packit 67cb25
   0.000000764902676483,
Packit 67cb25
   0.000000010042493924,
Packit 67cb25
   0.000000000099322077,
Packit 67cb25
   0.000000000000766380,
Packit 67cb25
   0.000000000000004741,
Packit 67cb25
   0.000000000000000024
Packit 67cb25
};
Packit 67cb25
static cheb_series bi1_cs = {
Packit 67cb25
  bi1_data,
Packit 67cb25
  10,
Packit 67cb25
  -1, 1,
Packit 67cb25
  10
Packit 67cb25
};
Packit 67cb25
Packit 67cb25
static double ai1_data[21] = {
Packit 67cb25
  -0.02846744181881479,
Packit 67cb25
  -0.01922953231443221,
Packit 67cb25
  -0.00061151858579437,
Packit 67cb25
  -0.00002069971253350,
Packit 67cb25
   0.00000858561914581,
Packit 67cb25
   0.00000104949824671,
Packit 67cb25
  -0.00000029183389184,
Packit 67cb25
  -0.00000001559378146,
Packit 67cb25
   0.00000001318012367,
Packit 67cb25
  -0.00000000144842341,
Packit 67cb25
  -0.00000000029085122,
Packit 67cb25
   0.00000000012663889,
Packit 67cb25
  -0.00000000001664947,
Packit 67cb25
  -0.00000000000166665,
Packit 67cb25
   0.00000000000124260,
Packit 67cb25
  -0.00000000000027315,
Packit 67cb25
   0.00000000000002023,
Packit 67cb25
   0.00000000000000730,
Packit 67cb25
  -0.00000000000000333,
Packit 67cb25
   0.00000000000000071,
Packit 67cb25
  -0.00000000000000006
Packit 67cb25
};
Packit 67cb25
static cheb_series ai1_cs = {
Packit 67cb25
  ai1_data,
Packit 67cb25
  20,
Packit 67cb25
  -1, 1,
Packit 67cb25
  11
Packit 67cb25
};
Packit 67cb25
Packit 67cb25
static double ai12_data[22] = {
Packit 67cb25
   0.02857623501828014,
Packit 67cb25
  -0.00976109749136147,
Packit 67cb25
  -0.00011058893876263,
Packit 67cb25
  -0.00000388256480887,
Packit 67cb25
  -0.00000025122362377,
Packit 67cb25
  -0.00000002631468847,
Packit 67cb25
  -0.00000000383538039,
Packit 67cb25
  -0.00000000055897433,
Packit 67cb25
  -0.00000000001897495,
Packit 67cb25
   0.00000000003252602,
Packit 67cb25
   0.00000000001412580,
Packit 67cb25
   0.00000000000203564,
Packit 67cb25
  -0.00000000000071985,
Packit 67cb25
  -0.00000000000040836,
Packit 67cb25
  -0.00000000000002101,
Packit 67cb25
   0.00000000000004273,
Packit 67cb25
   0.00000000000001041,
Packit 67cb25
  -0.00000000000000382,
Packit 67cb25
  -0.00000000000000186,
Packit 67cb25
   0.00000000000000033,
Packit 67cb25
   0.00000000000000028,
Packit 67cb25
  -0.00000000000000003
Packit 67cb25
};
Packit 67cb25
static cheb_series ai12_cs = {
Packit 67cb25
  ai12_data,
Packit 67cb25
  21,
Packit 67cb25
  -1, 1,
Packit 67cb25
  9
Packit 67cb25
};
Packit 67cb25
Packit 67cb25
Packit 67cb25
/*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/
Packit 67cb25
Packit 67cb25
int gsl_sf_bessel_I1_scaled_e(const double x, gsl_sf_result * result)
Packit 67cb25
{
Packit 67cb25
  const double xmin    = 2.0 * GSL_DBL_MIN;
Packit 67cb25
  const double x_small = ROOT_EIGHT * GSL_SQRT_DBL_EPSILON;
Packit 67cb25
  const double y = fabs(x);
Packit 67cb25
Packit 67cb25
  /* CHECK_POINTER(result) */
Packit 67cb25
Packit 67cb25
  if(y == 0.0) {
Packit 67cb25
    result->val = 0.0;
Packit 67cb25
    result->err = 0.0;
Packit 67cb25
    return GSL_SUCCESS;
Packit 67cb25
  }
Packit 67cb25
  else if(y < xmin) {
Packit 67cb25
    UNDERFLOW_ERROR(result);
Packit 67cb25
  }
Packit 67cb25
  else if(y < x_small) {
Packit 67cb25
    result->val = 0.5*x;
Packit 67cb25
    result->err = 0.0;
Packit 67cb25
    return GSL_SUCCESS;
Packit 67cb25
  }
Packit 67cb25
  else if(y <= 3.0) {
Packit 67cb25
    const double ey = exp(-y);
Packit 67cb25
    gsl_sf_result c;
Packit 67cb25
    cheb_eval_e(&bi1_cs, y*y/4.5-1.0, &c);
Packit 67cb25
    result->val  = x * ey * (0.875 + c.val);
Packit 67cb25
    result->err  = ey * c.err + y * GSL_DBL_EPSILON * fabs(result->val);
Packit 67cb25
    result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
Packit 67cb25
    return GSL_SUCCESS;
Packit 67cb25
  }
Packit 67cb25
  else if(y <= 8.0) {
Packit 67cb25
    const double sy = sqrt(y);
Packit 67cb25
    gsl_sf_result c;
Packit 67cb25
    double b;
Packit 67cb25
    double s;
Packit 67cb25
    cheb_eval_e(&ai1_cs, (48.0/y-11.0)/5.0, &c);
Packit 67cb25
    b = (0.375 + c.val) / sy;
Packit 67cb25
    s = (x > 0.0 ? 1.0 : -1.0);
Packit 67cb25
    result->val  = s * b;
Packit 67cb25
    result->err  = c.err / sy;
Packit 67cb25
    result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
Packit 67cb25
    return GSL_SUCCESS;
Packit 67cb25
  }
Packit 67cb25
  else {
Packit 67cb25
    const double sy = sqrt(y);
Packit 67cb25
    gsl_sf_result c;
Packit 67cb25
    double b;
Packit 67cb25
    double s;
Packit 67cb25
    cheb_eval_e(&ai12_cs, 16.0/y-1.0, &c);
Packit 67cb25
    b = (0.375 + c.val) / sy;
Packit 67cb25
    s = (x > 0.0 ? 1.0 : -1.0);
Packit 67cb25
    result->val  = s * b;
Packit 67cb25
    result->err  = c.err / sy;
Packit 67cb25
    result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
Packit 67cb25
    return GSL_SUCCESS;
Packit 67cb25
  }
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
Packit 67cb25
int gsl_sf_bessel_I1_e(const double x, gsl_sf_result * result)
Packit 67cb25
{
Packit 67cb25
  const double xmin    = 2.0 * GSL_DBL_MIN;
Packit 67cb25
  const double x_small = ROOT_EIGHT * GSL_SQRT_DBL_EPSILON;
Packit 67cb25
  const double y = fabs(x);
Packit 67cb25
Packit 67cb25
  /* CHECK_POINTER(result) */
Packit 67cb25
Packit 67cb25
  if(y == 0.0) {
Packit 67cb25
    result->val = 0.0;
Packit 67cb25
    result->err = 0.0;
Packit 67cb25
    return GSL_SUCCESS;
Packit 67cb25
  }
Packit 67cb25
  else if(y < xmin) {
Packit 67cb25
    UNDERFLOW_ERROR(result);
Packit 67cb25
  }
Packit 67cb25
  else if(y < x_small) {
Packit 67cb25
    result->val = 0.5*x;
Packit 67cb25
    result->err = 0.0;
Packit 67cb25
    return GSL_SUCCESS;
Packit 67cb25
  }
Packit 67cb25
  else if(y <= 3.0) {
Packit 67cb25
    gsl_sf_result c;
Packit 67cb25
    cheb_eval_e(&bi1_cs, y*y/4.5-1.0, &c);
Packit 67cb25
    result->val  = x * (0.875 + c.val);
Packit 67cb25
    result->err  = y * 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(y < GSL_LOG_DBL_MAX) {
Packit 67cb25
    const double ey = exp(y);
Packit 67cb25
    gsl_sf_result I1_scaled;
Packit 67cb25
    gsl_sf_bessel_I1_scaled_e(x, &I1_scaled);
Packit 67cb25
    result->val  = ey * I1_scaled.val;
Packit 67cb25
    result->err  = ey * I1_scaled.err + y * GSL_DBL_EPSILON * fabs(result->val);
Packit 67cb25
    result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
Packit 67cb25
    return GSL_SUCCESS;
Packit 67cb25
  }
Packit 67cb25
  else {
Packit 67cb25
    OVERFLOW_ERROR(result);
Packit 67cb25
  }
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
/*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/
Packit 67cb25
Packit 67cb25
#include "eval.h"
Packit 67cb25
Packit 67cb25
double gsl_sf_bessel_I1_scaled(const double x)
Packit 67cb25
{
Packit 67cb25
  EVAL_RESULT(gsl_sf_bessel_I1_scaled_e(x, &result));
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
double gsl_sf_bessel_I1(const double x)
Packit 67cb25
{
Packit 67cb25
  EVAL_RESULT(gsl_sf_bessel_I1_e(x, &result));
Packit 67cb25
}