Changeset 97f9b46 in sasmodels


Ignore:
Timestamp:
Oct 20, 2016 3:58:39 PM (8 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, core_shell_microgels, costrafo411, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
Children:
aea515c
Parents:
ca9e54e
Message:

tgamma: better handling of gamma(x) for x<0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/models/lib/sas_gamma.c

    r217590b r97f9b46  
    55We use gamma definition Gamma(t + 1) = t * Gamma(t) to compute 
    66to function for values lower than 1.0. Namely Gamma(t) = 1/t * Gamma(t + 1) 
     7For t < 0, we use Gamma(t) = pi / ( Gamma(1 - t) * sin(pi * t) ) 
    78*/ 
    89 
     
    137138 
    138139 
    139 inline double sas_gamma(double x) { 
    140 #if 1 
    141     // Fast reliable gamma in [-n,171], where n is a small integer 
    142     double norm = 1.; 
    143     while (x < 1.) { 
    144         norm *= x; 
    145         x += 1.0; 
    146     } 
    147     return tgamma(x)/norm; 
    148 #else 
    149     // Fast reliable gamma in [0,170] 
    150     return tgamma(x+1)/x; 
    151 #endif 
     140inline double sas_gamma(double x) 
     141{ 
     142    // Note: the builtin tgamma can give slow and unreliable results for x<1. 
     143    // The following transform extends it to zero and to negative values. 
     144    // It should return NaN for zero and negative integers but doesn't. 
     145    // The accuracy is okay but not wonderful for negative numbers, maybe 
     146    // one or two digits lost in the calculation. If higher accuracy is 
     147    // needed, you could test the following loop: 
     148    //    double norm = 1.; 
     149    //    while (x<1.) { norm*=x; x+=1.; } 
     150    //    return tgamma(x)/norm; 
     151    return (x<0. ? M_PI/tgamma(1.-x)/sin(M_PI*x) : tgamma(x+1)/x); 
    152152} 
Note: See TracChangeset for help on using the changeset viewer.