source: sasview/sansmodels/igor_wrapper/src/erf.c @ 5548954

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 5548954 was 25a60dc1, checked in by Jae Cho <jhjcho@…>, 13 years ago

moving a folder

  • Property mode set to 100644
File size: 2.6 KB
Line 
1/* erf.c
2reference - Haruhiko Okumura: C-gengo niyoru saishin algorithm jiten
3            (New Algorithm handbook in C language) (Gijyutsu hyouron
4            sha, Tokyo, 1991) p.227 [in Japanese]                 */
5#include <stdio.h>
6#include <math.h>
7
8#ifdef _MSC_VER
9
10
11#ifdef _WIN32
12# include <float.h>
13# if !defined __MINGW32__ || defined __NO_ISOCEXT
14#  ifndef isnan
15#   define isnan(x) _isnan(x)
16#  endif
17#  ifndef isinf
18#   define isinf(x) (!_finite(x) && !_isnan(x))
19#  endif
20#  ifndef finite
21#   define finite(x) _finite(x)
22#  endif
23# endif
24#endif
25
26static double q_gamma(double, double, double);
27
28/* Incomplete gamma function
29   1 / Gamma(a) * Int_0^x exp(-t) t^(a-1) dt  */
30static double p_gamma(a, x, loggamma_a)
31    double a, x, loggamma_a;
32{
33    int k;
34    double result, term, previous;
35
36    if (x >= 1 + a) return 1 - q_gamma(a, x, loggamma_a);
37    if (x == 0)     return 0;
38    result = term = exp(a * log(x) - x - loggamma_a) / a;
39    for (k = 1; k < 1000; k++) {
40        term *= x / (a + k);
41        previous = result;  result += term;
42        if (result == previous) return result;
43    }
44    fprintf(stderr, "erf.c:%d:p_gamma() could not converge.", __LINE__);
45    return result;
46}
47
48/* Incomplete gamma function
49   1 / Gamma(a) * Int_x^inf exp(-t) t^(a-1) dt  */
50static double q_gamma(a, x, loggamma_a)
51    double a, x, loggamma_a;
52{
53    int k;
54    double result, w, temp, previous;
55    double la = 1, lb = 1 + x - a;  /* Laguerre polynomial */
56
57    if (x < 1 + a) return 1 - p_gamma(a, x, loggamma_a);
58    w = exp(a * log(x) - x - loggamma_a);
59    result = w / lb;
60    for (k = 2; k < 1000; k++) {
61        temp = ((k - 1 - a) * (lb - la) + (k + x) * lb) / k;
62        la = lb;  lb = temp;
63        w *= (k - 1 - a) / k;
64        temp = w / (la * lb);
65        previous = result;  result += temp;
66        if (result == previous) return result;
67    }
68    fprintf(stderr, "erf.c:%d:q_gamma() could not converge.", __LINE__);
69    return result;
70}
71
72#define LOG_PI_OVER_2 0.572364942924700087071713675675 /* log_e(PI)/2 */
73
74double erf(x)
75    double x;
76{
77    if (!finite(x)) {
78        if (isnan(x)) return x;      /* erf(NaN)   = NaN   */
79        return (x>0 ? 1.0 : -1.0);   /* erf(+-inf) = +-1.0 */
80    }
81    if (x >= 0) return   p_gamma(0.5, x * x, LOG_PI_OVER_2);
82    else        return - p_gamma(0.5, x * x, LOG_PI_OVER_2);
83}
84
85double erfc(x)
86    double x;
87{
88    if (!finite(x)) {
89        if (isnan(x)) return x;      /* erfc(NaN)   = NaN      */
90        return (x>0 ? 0.0 : 2.0);    /* erfc(+-inf) = 0.0, 2.0 */
91    }
92    if (x >= 0) return  q_gamma(0.5, x * x, LOG_PI_OVER_2);
93    else        return  1 + p_gamma(0.5, x * x, LOG_PI_OVER_2);
94}
95
96#endif
Note: See TracBrowser for help on using the repository browser.