Changeset 4c29e4d in sasview for src/sas/sascalc/calculator/c_extensions/librefl.c
- Timestamp:
- May 6, 2016 12:43:26 PM (9 years ago)
- Branches:
- master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- b523c0e
- Parents:
- 6a698c0
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sascalc/calculator/c_extensions/librefl.c
r9e531f2 r4c29e4d 8 8 #include <stdlib.h> 9 9 #if defined(_MSC_VER) 10 # include "winFuncs.h"10 #define NEED_ERF 11 11 #endif 12 13 14 15 #if defined(NEED_ERF) 16 /* erf.c - public domain implementation of error function erf(3m) 17 18 reference - Haruhiko Okumura: C-gengo niyoru saishin algorithm jiten 19 (New Algorithm handbook in C language) (Gijyutsu hyouron 20 sha, Tokyo, 1991) p.227 [in Japanese] */ 21 22 23 #ifdef _WIN32 24 # include <float.h> 25 # if !defined __MINGW32__ || defined __NO_ISOCEXT 26 # ifndef isnan 27 # define isnan(x) _isnan(x) 28 # endif 29 # ifndef isinf 30 # define isinf(x) (!_finite(x) && !_isnan(x)) 31 # endif 32 # ifndef finite 33 # define finite(x) _finite(x) 34 # endif 35 # endif 36 #endif 37 38 static double q_gamma(double, double, double); 39 40 /* Incomplete gamma function 41 1 / Gamma(a) * Int_0^x exp(-t) t^(a-1) dt */ 42 static double p_gamma(double a, double x, double loggamma_a) 43 { 44 int k; 45 double result, term, previous; 46 47 if (x >= 1 + a) return 1 - q_gamma(a, x, loggamma_a); 48 if (x == 0) return 0; 49 result = term = exp(a * log(x) - x - loggamma_a) / a; 50 for (k = 1; k < 1000; k++) { 51 term *= x / (a + k); 52 previous = result; result += term; 53 if (result == previous) return result; 54 } 55 fprintf(stderr, "erf.c:%d:p_gamma() could not converge.", __LINE__); 56 return result; 57 } 58 59 /* Incomplete gamma function 60 1 / Gamma(a) * Int_x^inf exp(-t) t^(a-1) dt */ 61 static double q_gamma(double a, double x, double loggamma_a) 62 { 63 int k; 64 double result, w, temp, previous; 65 double la = 1, lb = 1 + x - a; /* Laguerre polynomial */ 66 67 if (x < 1 + a) return 1 - p_gamma(a, x, loggamma_a); 68 w = exp(a * log(x) - x - loggamma_a); 69 result = w / lb; 70 for (k = 2; k < 1000; k++) { 71 temp = ((k - 1 - a) * (lb - la) + (k + x) * lb) / k; 72 la = lb; lb = temp; 73 w *= (k - 1 - a) / k; 74 temp = w / (la * lb); 75 previous = result; result += temp; 76 if (result == previous) return result; 77 } 78 fprintf(stderr, "erf.c:%d:q_gamma() could not converge.", __LINE__); 79 return result; 80 } 81 82 #define LOG_PI_OVER_2 0.572364942924700087071713675675 /* log_e(PI)/2 */ 83 84 double erf(double x) 85 { 86 if (!finite(x)) { 87 if (isnan(x)) return x; /* erf(NaN) = NaN */ 88 return (x>0 ? 1.0 : -1.0); /* erf(+-inf) = +-1.0 */ 89 } 90 if (x >= 0) return p_gamma(0.5, x * x, LOG_PI_OVER_2); 91 else return - p_gamma(0.5, x * x, LOG_PI_OVER_2); 92 } 93 94 double erfc(double x) 95 { 96 if (!finite(x)) { 97 if (isnan(x)) return x; /* erfc(NaN) = NaN */ 98 return (x>0 ? 0.0 : 2.0); /* erfc(+-inf) = 0.0, 2.0 */ 99 } 100 if (x >= 0) return q_gamma(0.5, x * x, LOG_PI_OVER_2); 101 else return 1 + p_gamma(0.5, x * x, LOG_PI_OVER_2); 102 } 103 #endif // NEED_ERF 12 104 13 105 complex cassign(real, imag)
Note: See TracChangeset
for help on using the changeset viewer.