ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/math/erfc.hpp
Revision: 1767
Committed: Fri Jul 6 22:01:58 2012 UTC (12 years, 9 months ago) by gezelter
File size: 2552 byte(s)
Log Message:
Various fixes required to compile OpenMD with the MS Visual C++ compiler

File Contents

# Content
1 /*
2 * Borrowed from OpenMM.
3 */
4
5 #include "config.h"
6 #ifndef MATH_ERFC_H
7 #define MATH_ERFC_H
8
9 /*
10 * At least up to version 8 (VC++ 2005), Microsoft does not support the
11 * standard C99 erf() and erfc() functions. For now we're including these
12 * definitions for an MSVC compilation; if these are added later then
13 * the #ifdef below should change to compare _MSC_VER with a particular
14 * version level.
15 */
16
17 #ifdef _MSC_VER
18
19
20 /***************************
21 * erf.cpp
22 * author: Steve Strand
23 * written: 29-Jan-04
24 ***************************/
25
26 #include <cmath>
27
28 static const RealType rel_error= 1E-12; //calculate 12 significant figures
29 //you can adjust rel_error to trade off between accuracy and speed
30 //but don't ask for > 15 figures (assuming usual 52 bit mantissa in a double)
31
32 static RealType erfc(RealType x);
33
34 static RealType erf(RealType x)
35 //erf(x) = 2/sqrt(pi)*integral(exp(-t^2),t,0,x)
36 // = 2/sqrt(pi)*[x - x^3/3 + x^5/5*2! - x^7/7*3! + ...]
37 // = 1-erfc(x)
38 {
39 static const RealType two_sqrtpi= 1.128379167095512574; // 2/sqrt(pi)
40 if (fabs(x) > 2.2) {
41 return 1.0 - erfc(x); //use continued fraction when fabs(x) > 2.2
42 }
43 RealType sum= x, term= x, xsqr= x*x;
44 int j= 1;
45 do {
46 term*= xsqr/j;
47 sum-= term/(2*j+1);
48 ++j;
49 term*= xsqr/j;
50 sum+= term/(2*j+1);
51 ++j;
52 } while (fabs(term)/sum > rel_error);
53 return two_sqrtpi*sum;
54 }
55
56
57 static RealType erfc(RealType x)
58 //erfc(x) = 2/sqrt(pi)*integral(exp(-t^2),t,x,inf)
59 // = exp(-x^2)/sqrt(pi) * [1/x+ (1/2)/x+ (2/2)/x+ (3/2)/x+ (4/2)/x+ ...]
60 // = 1-erf(x)
61 //expression inside [] is a continued fraction so '+' means add to denominator only
62 {
63 static const RealType one_sqrtpi= 0.564189583547756287; // 1/sqrt(pi)
64 if (fabs(x) < 2.2) {
65 return 1.0 - erf(x); //use series when fabs(x) < 2.2
66 }
67 // Don't look for x==0 here!
68 if (x < 0) { //continued fraction only valid for x>0
69 return 2.0 - erfc(-x);
70 }
71 RealType a=1, b=x; //last two convergent numerators
72 RealType c=x, d=x*x+0.5; //last two convergent denominators
73 RealType q1, q2= b/d; //last two convergents (a/c and b/d)
74 RealType n= 1.0, t;
75 do {
76 t= a*n+b*x;
77 a= b;
78 b= t;
79 t= c*n+d*x;
80 c= d;
81 d= t;
82 n+= 0.5;
83 q1= q2;
84 q2= b/d;
85 } while (fabs(q1-q2)/q2 > rel_error);
86 return one_sqrtpi*exp(-x*x)*q2;
87 }
88
89 #endif // _MSC_VER
90
91 #endif

Properties

Name Value
svn:eol-style native