コード例 #1
0
ファイル: NR.cpp プロジェクト: nbigaouette/libpotentials
// **************************************************************
fdouble gammln(fdouble xx)
/**
 * Returns the value ln[Γ(xx)] for xx > 0.
 * See "Numerical Recipes in C", 2nd edition, page 214
 */
{
    // Internal arithmetic will be done in fdouble precision,
    // a nicety that you can omit if five-figure accuracy is good enough.
    fdouble x, y, tmp, ser;
    static fdouble cof[6] = {
        fdouble(76.18009172947146),
        fdouble(-86.50532032941677),
        fdouble(24.01409824083091),
        fdouble(-1.231739572450155),
        fdouble(0.1208650973866179e-2),
        fdouble(-0.5395239384953e-5)
    };

    int j;
    y = x = xx;
    tmp = x + fdouble(5.5);
    tmp -= (x + fhalf) * std::log(tmp);
    ser = fdouble(1.000000000190015);
    for (j = 0 ; j <= 5 ; j++) ser += cof[j] / ++y;

    return -tmp + std::log(fdouble(2.5066282746310005) * ser / x);
}
コード例 #2
0
ファイル: NR.cpp プロジェクト: nbigaouette/libpotentials
// **************************************************************
fdouble Gamma_NaturalLogarithm(fdouble xx)
/**
 * Natural logarithm of the (approximate) gamma function. See:
 * See "Numerical Recipes in C", 2nd edition, page 214
 * Gives the same result as gammln() from the treecode (2008 09 25)
 */
{
    int i;
    fdouble cof[6],stp;
    fdouble x,y,tmp,ser;

    cof[0] = fdouble(76.18009172947146);
    cof[1] = fdouble(-86.50532032941677);
    cof[2] = fdouble(24.01409824083091);
    cof[3] = fdouble(-1.231739572450155);
    cof[4] = fdouble(0.1208650973866179E-2);
    cof[5] = fdouble(-0.5395239384953E-5);

    stp = fdouble(2.5066282746310005);

    x = xx;
    y = x;
    tmp = x + fdouble(5.5);
    tmp = (x+fhalf)*std::log(tmp) - tmp;

    ser = fdouble(1.000000000190015);

    for( i = 0; i < 6; i++ )
    {
        y += 1;
        ser += cof[i]/y;
    }

    return (tmp + std::log(stp*ser/x) );
}
コード例 #3
0
ファイル: NR.cpp プロジェクト: nbigaouette/libpotentials
// **************************************************************
void gcf(fdouble *gammcf, fdouble a, fdouble x, fdouble *gln)
/**
 * Returns the incomplete gamma function Q(a, x) evaluated by
 * its continued fraction representation as gammcf. Also
 * returns ln Γ(a) as gln.
 * See "Numerical Recipes in C", 2nd edition, page 219
 */
{
    int i;
    fdouble an, b, c, d, del, h;

    const int    ITMAX = 100;       // Maximum allowed number of iterations.
    const fdouble EPS   = fdouble(3.0e-7);    // Relative accuracy.
    const fdouble FPMIN = fdouble(1.0e-30);   // Number near the smallest representable floating-point number.

    *gln = gammln(a);

    // Set up for evaluating continued fraction by modified
    // Lentz's method (§5.2) with b0 = 0.
    b = x + fone - a;
    c=fone / FPMIN;
    d=fone / b;

    h = d;
    for (i = 1 ; i <= ITMAX ; i++)
    {
        // Iterate to convergence.
        an = -fdouble(i)*(fdouble(i)-a);
        b += fdouble(2.0);
        d = an * d + b;
        if (std::abs(d) < FPMIN) d = FPMIN;
        c = b + an / c;
        if (std::abs(c) < FPMIN) c = FPMIN;
        d = fone / d;
        del = d * c;
        h *= del;
        if (std::abs(del-fone) < EPS) break;
    }
    if (i > ITMAX)
    {
        std_cout << "a too large, ITMAX too small in gcf\n";
        abort();
    }

    // Put factors in front.
    *gammcf = std::exp(-x + a * std::log(x) - (*gln)) * h;
}
コード例 #4
0
ファイル: NR.cpp プロジェクト: nbigaouette/libpotentials
// **************************************************************
void gser(fdouble *gamser, fdouble a, fdouble x, fdouble *gln)
/**
 * Returns the incomplete gamma function P (a, x) evaluated by
 * its series representation as gamser.
 * Also returns ln Γ(a) as gln.
 * See "Numerical Recipes in C", 2nd edition, page 218
 */
{
    const int    ITMAX = 100;
    const fdouble EPS   = fdouble(3.0e-7);

    int n;
    fdouble sum, del, ap;
    *gln = gammln(a);

    if (x <= 0.0)
    {
        if (x < 0.0)
        {
            std_cout << "x less than 0 in routine gser\n";
            abort();
        }

        *gamser=0.0;
        return;
    } else {
        ap = a;
        del = sum = fone / a;
        for (n = 1 ; n <= ITMAX ; n++)
        {
            ++ap;
            del *= x / ap;
            sum += del;
            if (std::abs(del) < std::abs(sum)*EPS)
            {
                *gamser = sum * std::exp(-x + a * std::log(x) - (*gln));
                return;
            }
        }
        std_cout << "a too large, ITMAX too small in routine gser\n";
        abort();
    }
}
コード例 #5
0
ファイル: NR.cpp プロジェクト: nbigaouette/libpotentials
// **************************************************************
fdouble python_erf(fdouble x)
/**
 * Taken from http://www.johndcook.com/blog/2009/01/19/stand-alone-error-function-erf/
 */
{
    // constants
    const fdouble a1 = fdouble( 0.254829592);
    const fdouble a2 = fdouble(-0.284496736);
    const fdouble a3 = fdouble( 1.421413741);
    const fdouble a4 = fdouble(-1.453152027);
    const fdouble a5 = fdouble( 1.061405429);
    const fdouble p  = fdouble( 0.3275911);

    // Save the sign of x
    fdouble sign = fone;
    if (x < 0.0) sign = -fone;
    const fdouble absx = std::abs(x);

    // A & S 7.1.26
    const fdouble t = fone / (fone + p * absx);
    const fdouble y = fone - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t * std::exp(-absx*absx);

    return sign*y;
}
コード例 #6
0
fdouble Get_Mass(void *b) { return fdouble(-9999999.9); }
コード例 #7
0
fdouble Get_Chargea(void *b) { return fdouble(-9999999.9); }
コード例 #8
0
ファイル: NR.cpp プロジェクト: nbigaouette/libpotentials
// **************************************************************
fdouble int_erf(fdouble x)
/**
 * "Pretty accurate simpson integration for the error function"
 * Taken from MDCluster's mdcluster_dyn.c line 27
 */
{
    int loop,n=1000; /* number of points */
    fdouble I,h;
    h=x/fdouble(n-1);
    I=0;
    I+=fdouble(3.0/8.0)  *h;
    I+=fdouble(7.0/6.0)  *h*std::exp(-h*h);
    I+=fdouble(23.0/24.0)*h*std::exp(-fdouble(4.0)*h*h);
    for (loop=3;loop<n-3;loop++) I+=h*std::exp(-fdouble(loop*loop)*h*h);
    I+=fdouble(23.0/24.0)*h*std::exp(-fdouble(loop*loop)*h*h);   loop++;
    I+=fdouble(7.0/6.0)*h*std::exp(-fdouble(loop*loop)*h*h);   loop++;
    I+=fdouble(3.0/8.0)*h*std::exp(-fdouble(loop*loop)*h*h);
    I*=fdouble(2.0)/std::sqrt(libpotentials::Pi);
    return(I);
}
コード例 #9
0
ファイル: NR.cpp プロジェクト: nbigaouette/libpotentials
namespace nr
{

    const fdouble fone  = fdouble(1.0);
    const fdouble fhalf = fdouble(0.5);

// **************************************************************
fdouble Gamma_NaturalLogarithm(fdouble xx)
/**
 * Natural logarithm of the (approximate) gamma function. See:
 * See "Numerical Recipes in C", 2nd edition, page 214
 * Gives the same result as gammln() from the treecode (2008 09 25)
 */
{
    int i;
    fdouble cof[6],stp;
    fdouble x,y,tmp,ser;

    cof[0] = fdouble(76.18009172947146);
    cof[1] = fdouble(-86.50532032941677);
    cof[2] = fdouble(24.01409824083091);
    cof[3] = fdouble(-1.231739572450155);
    cof[4] = fdouble(0.1208650973866179E-2);
    cof[5] = fdouble(-0.5395239384953E-5);

    stp = fdouble(2.5066282746310005);

    x = xx;
    y = x;
    tmp = x + fdouble(5.5);
    tmp = (x+fhalf)*std::log(tmp) - tmp;

    ser = fdouble(1.000000000190015);

    for( i = 0; i < 6; i++ )
    {
        y += 1;
        ser += cof[i]/y;
    }

    return (tmp + std::log(stp*ser/x) );
}

// **************************************************************
fdouble Gamma(fdouble xx)
/**
 * Approximate gamma function.
 * See "Numerical Recipes in C", 2nd edition, page 214
 */
{
    return std::exp( Gamma_NaturalLogarithm(xx) );
}

// **************************************************************
fdouble gammln(fdouble xx)
/**
 * Returns the value ln[Γ(xx)] for xx > 0.
 * See "Numerical Recipes in C", 2nd edition, page 214
 */
{
    // Internal arithmetic will be done in fdouble precision,
    // a nicety that you can omit if five-figure accuracy is good enough.
    fdouble x, y, tmp, ser;
    static fdouble cof[6] = {
        fdouble(76.18009172947146),
        fdouble(-86.50532032941677),
        fdouble(24.01409824083091),
        fdouble(-1.231739572450155),
        fdouble(0.1208650973866179e-2),
        fdouble(-0.5395239384953e-5)
    };

    int j;
    y = x = xx;
    tmp = x + fdouble(5.5);
    tmp -= (x + fhalf) * std::log(tmp);
    ser = fdouble(1.000000000190015);
    for (j = 0 ; j <= 5 ; j++) ser += cof[j] / ++y;

    return -tmp + std::log(fdouble(2.5066282746310005) * ser / x);
}

// **************************************************************
fdouble gammp(fdouble a, fdouble x)
/**
 * Returns the incomplete gamma function P (a, x).
 * See "Numerical Recipes in C", 2nd edition, page 218
 */
{
    fdouble gamser, gammcf, gln;

    if (x < 0.0 || a <= 0.0)
    {
        std_cout << "Invalid arguments in routine gammp\n";
        abort();
    }

    if (x < (a+fone))
    {
        //Use the series representation.
        gser(&gamser, a, x, &gln);
        return gamser;
    } else {
        // Use the continued fraction representation and take its complement.
        gcf(&gammcf, a, x, &gln);
        return fone - gammcf;
    }
}

// **************************************************************
void gser(fdouble *gamser, fdouble a, fdouble x, fdouble *gln)
/**
 * Returns the incomplete gamma function P (a, x) evaluated by
 * its series representation as gamser.
 * Also returns ln Γ(a) as gln.
 * See "Numerical Recipes in C", 2nd edition, page 218
 */
{
    const int    ITMAX = 100;
    const fdouble EPS   = fdouble(3.0e-7);

    int n;
    fdouble sum, del, ap;
    *gln = gammln(a);

    if (x <= 0.0)
    {
        if (x < 0.0)
        {
            std_cout << "x less than 0 in routine gser\n";
            abort();
        }

        *gamser=0.0;
        return;
    } else {
        ap = a;
        del = sum = fone / a;
        for (n = 1 ; n <= ITMAX ; n++)
        {
            ++ap;
            del *= x / ap;
            sum += del;
            if (std::abs(del) < std::abs(sum)*EPS)
            {
                *gamser = sum * std::exp(-x + a * std::log(x) - (*gln));
                return;
            }
        }
        std_cout << "a too large, ITMAX too small in routine gser\n";
        abort();
    }
}

// **************************************************************
void gcf(fdouble *gammcf, fdouble a, fdouble x, fdouble *gln)
/**
 * Returns the incomplete gamma function Q(a, x) evaluated by
 * its continued fraction representation as gammcf. Also
 * returns ln Γ(a) as gln.
 * See "Numerical Recipes in C", 2nd edition, page 219
 */
{
    int i;
    fdouble an, b, c, d, del, h;

    const int    ITMAX = 100;       // Maximum allowed number of iterations.
    const fdouble EPS   = fdouble(3.0e-7);    // Relative accuracy.
    const fdouble FPMIN = fdouble(1.0e-30);   // Number near the smallest representable floating-point number.

    *gln = gammln(a);

    // Set up for evaluating continued fraction by modified
    // Lentz's method (§5.2) with b0 = 0.
    b = x + fone - a;
    c=fone / FPMIN;
    d=fone / b;

    h = d;
    for (i = 1 ; i <= ITMAX ; i++)
    {
        // Iterate to convergence.
        an = -fdouble(i)*(fdouble(i)-a);
        b += fdouble(2.0);
        d = an * d + b;
        if (std::abs(d) < FPMIN) d = FPMIN;
        c = b + an / c;
        if (std::abs(c) < FPMIN) c = FPMIN;
        d = fone / d;
        del = d * c;
        h *= del;
        if (std::abs(del-fone) < EPS) break;
    }
    if (i > ITMAX)
    {
        std_cout << "a too large, ITMAX too small in gcf\n";
        abort();
    }

    // Put factors in front.
    *gammcf = std::exp(-x + a * std::log(x) - (*gln)) * h;
}

// **************************************************************
fdouble erff(fdouble x)
/**
 * Returns the error function erf(x).
 * See "Numerical Recipes in C", 2nd edition, page 220
 */
{
    return x < 0.0 ? -gammp(0.5,x*x) : gammp(0.5,x*x);
}

// **************************************************************
fdouble int_erf(fdouble x)
/**
 * "Pretty accurate simpson integration for the error function"
 * Taken from MDCluster's mdcluster_dyn.c line 27
 */
{
    int loop,n=1000; /* number of points */
    fdouble I,h;
    h=x/fdouble(n-1);
    I=0;
    I+=fdouble(3.0/8.0)  *h;
    I+=fdouble(7.0/6.0)  *h*std::exp(-h*h);
    I+=fdouble(23.0/24.0)*h*std::exp(-fdouble(4.0)*h*h);
    for (loop=3;loop<n-3;loop++) I+=h*std::exp(-fdouble(loop*loop)*h*h);
    I+=fdouble(23.0/24.0)*h*std::exp(-fdouble(loop*loop)*h*h);   loop++;
    I+=fdouble(7.0/6.0)*h*std::exp(-fdouble(loop*loop)*h*h);   loop++;
    I+=fdouble(3.0/8.0)*h*std::exp(-fdouble(loop*loop)*h*h);
    I*=fdouble(2.0)/std::sqrt(libpotentials::Pi);
    return(I);
}

// **************************************************************
fdouble python_erf(fdouble x)
/**
 * Taken from http://www.johndcook.com/blog/2009/01/19/stand-alone-error-function-erf/
 */
{
    // constants
    const fdouble a1 = fdouble( 0.254829592);
    const fdouble a2 = fdouble(-0.284496736);
    const fdouble a3 = fdouble( 1.421413741);
    const fdouble a4 = fdouble(-1.453152027);
    const fdouble a5 = fdouble( 1.061405429);
    const fdouble p  = fdouble( 0.3275911);

    // Save the sign of x
    fdouble sign = fone;
    if (x < 0.0) sign = -fone;
    const fdouble absx = std::abs(x);

    // A & S 7.1.26
    const fdouble t = fone / (fone + p * absx);
    const fdouble y = fone - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t * std::exp(-absx*absx);

    return sign*y;
}

}
コード例 #10
0
void h (void)
{
  float f = 0;
  double d = 0;
  long double ld = 0;

  ffloat (3.1); /* { dg-warning "conversion" } */
  vfloat = 3.1; /* { dg-warning "conversion" } */
  ffloat (3.1L); /* { dg-warning "conversion" } */
  vfloat = 3.1L;  /* { dg-warning "conversion" } */
  fdouble (3.1L); /* { dg-warning "conversion" "" { target large_long_double } } */
  vdouble = 3.1L; /* { dg-warning "conversion" "" { target large_long_double } } */
  ffloat (vdouble); /* { dg-warning "conversion" } */
  vfloat = vdouble; /* { dg-warning "conversion" } */
  ffloat (vlongdouble); /* { dg-warning "conversion" } */
  vfloat = vlongdouble; /* { dg-warning "conversion" } */
  fdouble (vlongdouble); /* { dg-warning "conversion" "" { target large_long_double } } */
  vdouble = vlongdouble; /* { dg-warning "conversion" "" { target large_long_double } } */


  ffloat ((float) 3.1); 
  vfloat = (float) 3.1;
  ffloat ((float) 3.1L);
  vfloat = (float) 3.1L; 
  fdouble ((double) 3.1L); 
  vdouble = (double) 3.1L; 
  ffloat ((float) vdouble); 
  vfloat = (float) vdouble; 
  ffloat ((float) vlongdouble); 
  vfloat = (float) vlongdouble;
  fdouble ((double) vlongdouble);
  vdouble = (double) vlongdouble;


  ffloat (3.0);
  vfloat = 3.0;
  ffloat (3.1f);
  vfloat = 3.1f;
  ffloat (0.25L);
  vfloat = 0.25L;


  fdouble (3.0);
  vdouble = 3.0;
  fdouble (3.1f);
  vdouble = 3.1f;
  fdouble (0.25L);
  vdouble = 0.25L;

  flongdouble (3.0);
  vlongdouble = 3.0;
  flongdouble (3.1f);
  vlongdouble = 3.1f;
  flongdouble (0.25L);
  vlongdouble = 0.25L;

  ffloat (f);
  vfloat = f;
  fdouble (f);
  vdouble = f;
  fdouble (d);
  vdouble = d;
  flongdouble (f);
  vlongdouble = f;
  flongdouble (d);
  vlongdouble = d;
  flongdouble (ld);
  vlongdouble = ld;
}