Kindfield
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Friends Pages
boysfunction.cpp
Go to the documentation of this file.
1 #include "boysfunction.h"
2 #include <iomanip>
4 
5 using namespace std;
6 
16 {
17 
18 }
19 
20 BoysFunction::BoysFunction(double arg, int levelMax, BoysFunctionIntermediate *intermediate)
21 {
22  set(arg, levelMax, intermediate);
23 }
24 
25 void BoysFunction::set(double arg, int levelMax, BoysFunctionIntermediate *intermediate)
26 {
27  double limitMin = 0;
28  double limitMax = 50;
29  if(intermediate == 0) {
30  m_intermediate = &(BoysFunctionIntermediate::getInstance());
31  } else {
32  m_intermediate = intermediate;
33  }
34  double x = arg;
35  m_results = zeros(levelMax + 1);
36  double expmx = exp(-x);
37  if(arg < limitMin || arg > limitMax) {
38  if(arg < limitMin) {
39  m_results(levelMax) = calculateTaylorExpansion(arg, levelMax);
40  } else if(arg > limitMax) {
41  m_results(levelMax) = calculateAsymptopticForm(arg, levelMax);
42  }
43  // Iterate down
44  for(int n = levelMax; n > 0; n--) {
45  double Fn = m_results(n);
46  m_results(n - 1) = (2*x*Fn + expmx) / (2*n - 1);
47  }
48  } else {
49  // Get results from intermediate area
50  for(int n = 0; n < levelMax + 1; n++) {
51  m_results(n) = m_intermediate->result(arg, n);
52  }
53  }
54 }
55 
56 double BoysFunction::calculateAsymptopticForm(double arg, int level) {
57  double n = level;
58  double dfac = doubleFactorial(2 * n - 1);
59  double result = dfac / pow(2, n + 1) * sqrt(M_PI / pow(arg, 2*n + 1));
60  return result;
61 }
62 
64  if(n == -1) {
65  return 1;
66  }
67  double result = 1;
68  for(double i = n; i >= 1; i -= 2) {
69  result *= i;
70  }
71  return result;
72 }
73 
74 double BoysFunction::factorial(double n) {
75  if(n == 0) {
76  return 1;
77  }
78  double result = 1;
79  double startPoint = 2;
80  for(double i = startPoint; i <= n; i++) {
81  result *= i;
82  }
83  return result;
84 }
85 
86 double BoysFunction::calculateTaylorExpansion(double arg, int level) {
87  double n = level;
88  double result = 0;
89  for(int k = 0; k < 100; k++) {
90  result += pow(-arg, k) / (factorial(k) * (2 * n + 2 * k + 1));
91  }
92  return result;
93 }
94 
96  if (arg < 1.0E-6){
97  return 1.0;
98  } else {
99  arg = sqrt(arg);
100  double f = 1.0/arg * erf(arg) *sqrt(M_PI)/2.0;
101  return f;
102  }
103 }
104 
105 double BoysFunction::result(int level) const
106 {
107  return m_results(level);
108 }